Cấu hình pfSense HAProxy: SSL Offloading, Client IP, DDoS L7
Kiến trúc Reverse Proxy sử dụng HAProxy trên tường lửa pfSense là một giải pháp tiêu chuẩn trong doanh nghiệp. Bài viết này hướng dẫn chi tiết cách triển khai HAProxy làm "cửa ngõ" đón luồng truy cập HTTPS, giải mã SSL, đẩy traffic về Web Server nội bộ (Nginx), đồng thời tích hợp cơ chế chống tấn công từ chối dịch vụ (DDoS) ở Tầng 7.
Cấu hình cơ bản pfSense HAProxy (Global, Backend & Frontend)
Mặc định, pfSense không tích hợp sẵn HAProxy. Để sử dụng, chúng ta cần cài đặt package này từ kho ứng dụng chính thức:
-
Đăng nhập vào trang quản trị pfSense.
-
Điều hướng đến System > Package Manager.
-
Chuyển sang tab Available Packages.
-
Tại ô tìm kiếm (Search term), gõ
haproxyvà nhấn Search. -
Tìm gói haproxy trong danh sách và bấm nút Install (màu xanh lá).
-
Xác nhận Confirm và chờ hệ thống tự động tải, cài đặt gói.

Nạp Chứng chỉ SSL (Let's Encrypt) vào pfSense
Vì HAProxy sẽ đứng ra làm nhiệm vụ giải mã (SSL Offloading), chúng ta cần chuyển chứng chỉ SSL từ máy chủ Web (đã được tạo bởi Certbot) lên lưu trữ tại Tường lửa pfSense.
Bước 1: Trích xuất chứng chỉ từ máy chủ Ubuntu (Web Server) Truy cập SSH vào máy chủ Ubuntu và sử dụng lệnh cat để đọc nội dung 2 file chứng chỉ Let's Encrypt:
-
Đọc file Chứng chỉ (Certificate):
sudo cat /etc/letsencrypt/live/cyber.quyenlt.com/fullchain.pem(Copy toàn bộ nội dung từ
-----BEGIN CERTIFICATE-----đến-----END CERTIFICATE-----) -
Đọc file Khóa bảo mật (Private Key):
sudo cat /etc/letsencrypt/live/cyber.quyenlt.com/privkey.pem(Copy toàn bộ nội dung từ
-----BEGIN PRIVATE KEY-----đến-----END PRIVATE KEY-----)
Bước 2: Import vào pfSense Cert Manager Chuyển sang giao diện quản trị pfSense để tiến hành nạp chứng chỉ:
-
Điều hướng đến System > Cert. Manager.
-
Chọn tab Certificates và nhấn nút Add/Sign (Màu xanh lá ở góc dưới).
-
Method: Chọn
Import an existing Certificate. -
Descriptive name: Đặt tên dễ nhớ, ví dụ:
SSL-cyber.quyenlt.com. -
Certificate data: Dán (Paste) toàn bộ nội dung file
fullchain.pemvừa copy ở Bước 1. -
Private key data: Dán toàn bộ nội dung file
privkey.pem. -
Nhấn Save.

Lúc này, chứng chỉ SSL của bạn đã nằm an toàn trên pfSense, sẵn sàng để gán cho cổng giao tiếp Frontend của HAProxy trong bước tiếp theo.
Mô hình triển khai: pfSense đứng ngoài hứng traffic cổng 443 (WAN), sau đó đẩy luồng dữ liệu thô (cổng 80) vào Web Server nội bộ Nginx (IP: 10.0.0.2).
1.1. Cấu hình Global Settings
Trước khi tạo luồng mạng, cần cấu hình giới hạn kết nối và mở cổng quản trị cho HAProxy.
-
Truy cập Services > HAProxy > Settings.
-
Maximum connections: Điền
1000(Ngưỡng an toàn để tránh cạn kiệt RAM của pfSense).

-
Internal stats port: Điền
2200(Cổng dùng để xem biểu đồ thống kê).

-
Tích chọn Enable HAProxy. Nhấn Save.
1.2. Khai báo Web Server (Backend)
-
Chuyển sang tab Backend > Bấm Add.
-
Name:
Web_Server_Pool. -
Server list: Điền thông tin máy chủ Nginx nội bộ.
-
Mode:
active -
Address:
10.0.0.2 -
Port:
80
-

-
Health checking: Đổi phương thức kiểm tra từ
HTTPsangBasic(Kiểm tra TCP ping). Điều này giúp tránh lỗi 503 do Nginx/WordPress chặn các truy vấn kiểm tra dạng HTTP không rõ ràng.

-
Advanced settings > Backend pass thru: Nhập cấu hình ép HAProxy chèn Header IP thật của client:
option forwardfor -
Nhấn Save.

1.3. Mở cửa đón khách (Frontend)
-
Chuyển sang tab Frontend > Bấm Add.
-
Name:
HTTPS_Frontend. -
External address: * Listen address:
WAN address (IPv4)-
Port:
443 -
Tích chọn SSL Offloading.
-

-
Default backend: Chọn
Web_Server_Poolvừa tạo.

-
SSL Offloading: Tại mục Certificates, chọn chứng chỉ SSL của tên miền (ví dụ:
SSL-cyber.quyenlt.com) đã được Import trước đó trong phần System > Cert. Manager.

-
Nhấn Save và Apply Changes.
Cấu hình Nginx nhận IP thật (X-Forwarded-For)
Khi traffic đi qua HAProxy, Nginx mặc định sẽ chỉ nhận diện được IP của pfSense (ví dụ 10.0.0.1). Để ghi nhận đúng IP public của người dùng vào Access Log, Nginx cần được cấu hình đọc Header X-Forwarded-For.
-
Truy cập vào máy chủ Ubuntu Nginx, chỉnh sửa file cấu hình website (vd:
/etc/nginx/sites-available/wordpress). -
Bổ sung các chỉ thị
real_ipvà xóa bỏ block cấu hình ép Redirect HTTP -> HTTPS cũ của Certbot (để tránh lỗi Too Many Redirects do pfSense đã quản lý SSL).
File cấu hình Nginx chuẩn:
server {
listen 80;
server_name cyber.quyenlt.com;
root /var/www/html/wordpress;
index index.php index.html index.htm;
# Cấu hình nhận diện IP thật từ pfSense HAProxy
set_real_ip_from 10.0.0.1; # Địa chỉ IP nội bộ của pfSense
real_ip_header X-Forwarded-For;
real_ip_recursive on;
location / {
try_files $uri $uri/ /index.php?$args;
}
location ~ \.php$ {
include snippets/fastcgi-php.conf;
fastcgi_pass unix:/var/run/php/php8.1-fpm.sock;
}
}
-
Lưu file và khởi động lại Nginx:
sudo systemctl restart nginx. -
Kiểm tra bằng lệnh:
tail -f /var/log/nginx/access.log. Lúc này IP thật của Client sẽ xuất hiện.

Cấu hình ACL Chống DDoS Layer 7 (Rate Limiting & Penalty Box)
Thay vì chỉ chặn tốc độ tạm thời, kỹ thuật này sử dụng bảng nhớ Stick-table và cờ phạt gpc0 (General Purpose Counter) để đếm số lượng HTTP Request. Nếu 1 IP truy vấn quá nhanh, hệ thống sẽ chặn vĩnh viễn IP đó trong 24 giờ.
-
Trở lại pfSense, chỉnh sửa
HTTPS_Frontendtrên HAProxy. -
Cuộn xuống ô Advanced pass thru và dán đoạn mã (dành cho HAProxy bản 2.8 trở lên):
# Khởi tạo bảng Stick-table trên RAM, nhớ trong 24 tiếng. Lưu tốc độ (10s) và cờ gpc0
stick-table type ip size 100k expire 24h store http_req_rate(10s),gpc0
# Bắt đầu theo dõi IP của người truy cập
http-request track-sc0 src
# Luật 1: Kích hoạt cờ phạt (tăng gpc0 lên 1) nếu 1 IP gửi quá 30 request trong 10 giây
http-request sc-inc-gpc0(0) if { sc_http_req_rate(0) gt 30 }
# Luật 2: Từ chối truy cập (trả mã 403) ngay lập tức đối với bất kỳ IP nào mang cờ phạt
http-request deny deny_status 403 if { sc_get_gpc0(0) gt 0 }
-
Nhấn Save và Apply Changes.

Quản trị và Xử lý sự cố qua Command Line (CLI)
Bảng Sổ đen (Stick-table) được HAProxy lưu hoàn toàn trên RAM để đảm bảo tốc độ phản hồi tính bằng mili-giây. Quản trị viên cần dùng giao diện dòng lệnh (Socket) để can thiệp.
Trên pfSense, truy cập Diagnostics > Command Prompt. Tại ô Execute Shell Command, sử dụng ống dẫn nc (Netcat) để thao tác:
1. Xem danh sách các IP đang truy cập và bị phạt:
echo "show table HTTPS_Frontend" | nc -U /tmp/haproxy.socket
Kết quả mẫu: 0x3a...: key=45.252.250.199 use=0 exp=86300164 shard=0 gpc0=1055 ... (IP có thông số gpc0 > 0 nghĩa là đang bị khóa).

2. Gỡ chặn (Ân xá) cho một IP cụ thể:
echo "clear table HTTPS_Frontend key 45.252.250.199" | nc -U /tmp/haproxy.socket
Thực chiến giả lập tấn công HTTP Flood và Nghiệm thu hệ thống
Để chứng minh tính hiệu quả của bức tường lửa vừa thiết lập, chúng ta sẽ tiến hành một bài test giả lập cuộc tấn công DDoS Layer 7 (HTTP Flood) quy mô nhỏ và quan sát phản ứng của hệ thống.
Bước 1: Chuẩn bị "Mắt thần" giám sát
Trước khi khai hỏa, bạn cần mở sẵn 2 màn hình giám sát để có cái nhìn đối chiếu trực quan:
-
Màn hình 1 (Giám sát Web Server): SSH vào máy chủ Ubuntu (
10.0.0.2) và chạy lệnh soi log theo thời gian thực để xem có traffic rác nào lọt được vào trong không:tail -f /var/log/nginx/access.log -
Màn hình 2 (Giám sát HAProxy): Trên giao diện pfSense, truy cập Services > HAProxy > Stats FS (Đây là bảng biểu đồ đã được kích hoạt qua cổng 2200 ở phần Global Settings). Hãy đặc biệt chú ý vào cột
Denied -> Reqtại dòngHTTPS_Frontend.

Bước 2: Khai hỏa bằng công cụ giả lập
Từ một thiết bị khác (khuyến nghị dùng mạng 4G hoặc máy tính khác IP mạng cục bộ), mở Terminal/Command Prompt và sử dụng một trong hai cách sau để tạo lượng truy vấn ồ ạt:
Cách 1: Dùng vòng lặp curl (Nhanh gọn, không cần cài đặt thêm) Lệnh này sẽ nã song song 100 truy vấn liên tục vào website để ép tốc độ vượt ngưỡng 30 request/10s:
for i in {1..100}; do curl -s -o /dev/null -w "Request $i - Status: %{http_code}\n" https://cyber.quyenlt.com & done
Cách 2: Dùng Apache Benchmark (ab) Nếu máy có cài đặt sẵn công cụ test tải ab, lệnh sau sẽ thực hiện bài stress test chuyên nghiệp hơn với 500 truy vấn, mỗi đợt 20 kết nối đồng thời:
ab -n 500 -c 20 https://cyber.quyenlt.com/
Bước 3: Đánh giá kết quả (Nghiệm thu)
Ngay khi đợt tấn công được phát động, hệ thống sẽ kích hoạt dây chuyền phòng vệ tự động theo đúng thiết kế:
-
Trên màn hình kẻ tấn công: Ở tích tắc đầu tiên, vài truy vấn đầu lọt qua sẽ trả về mã
200 OK. Nhưng ngay khoảnh khắc tốc độ vượt ngưỡng, hệ thống lập tức sập cửa, toàn bộ các truy vấn sau đó đều bị trả về mã lỗi403 Forbidden(Cấm truy cập vĩnh viễn 24h). -
Trên Dashboard Tường lửa (Màn hình 2): Khi tải lại (F5) trang Stats của HAProxy, con số ở cột
Deniednhảy vọt lên chóng mặt bằng đúng số lượng request rác được gửi đi. Điều này chứng minh Frontend đã đứng ra hứng chịu toàn bộ hỏa lực. -
Trên Web Server nội bộ (Màn hình 1): Màn hình
access.logcủa Nginx hoàn toàn đứng im. Máy chủ web không hề nhận được một "hạt bụi" nào từ đợt tấn công, tài nguyên CPU và RAM của hệ thống lõi được bảo vệ an toàn 100%.
Kết luận: Mô hình Reverse Proxy kết hợp ACL trên pfSense đã chứng minh được hiệu quả phòng thủ chiều sâu (Defense in Depth). Nó không chỉ ẩn danh được hạ tầng bên trong, xử lý mượt mà mã hóa SSL mà còn tự động hóa hoàn toàn việc cô lập và trừng phạt các nguồn truy cập độc hại mà không cần sự can thiệp thủ công của quản trị viên.
Xử lý sự cố Tường lửa "Kill" HAProxy do cạn kiệt tài nguyên
Trong môi trường thực chiến, khi hứng chịu một đợt tấn công DDoS cường độ quá lớn, bạn có thể gặp tình trạng dịch vụ HAProxy đột ngột dừng hoạt động (Stop/Crash). Nguyên nhân cốt lõi thường không phải do lỗi phần mềm HAProxy, mà do cơ chế tự vệ của hệ điều hành pfSense (OOM Killer) đã chủ động "tiêu diệt" tiến trình HAProxy để cứu vãn phần còn lại của tường lửa khỏi việc cạn kiệt RAM.
Để xây dựng một hạ tầng có sức chống chịu cao, chúng ta cần thực hiện quy trình Truy vết sự cố (Post-mortem Analysis) và triển khai các Lớp phòng thủ tăng cường.
Bước 1: Truy vết nguyên nhân qua System Logs
Khi dịch vụ bị sập, hệ điều hành sẽ lưu lại "di thư" trong log Kernel. Để chẩn đoán chính xác bệnh của hệ thống:
-
Truy cập trang quản trị pfSense, điều hướng đến Status > System Logs > System > General.
-
Tại ô Filter / Search, nhập từ khóa
haproxyhoặckernelvà nhấn Filter.

Đọc và phân tích log:
-
-
Trường hợp 1: Nếu xuất hiện log dạng
kernel: pid 12345 (haproxy), uid 0, was killed: out of swap space. Đây là dấu hiệu HAProxy đã tiêu thụ vượt mức RAM cho phép. Hệ điều hành phải kill nó để giữ pfSense không bị treo.
-
-
Trường hợp 2: Nếu xuất hiện log
pf: State table full. Dấu hiệu này cho thấy kẻ tấn công (Botnet) đã mở quá nhiều kết nối TCP đồng thời (SYN Flood), làm đầy bảng trạng thái mạng ở Tầng 4.
Khi đã xác định được nguyên nhân, chúng ta tiến hành gia cố hệ thống bằng 3 lớp "áo giáp" cấu hình dưới đây.
Bước 2: Ép HAProxy cắt đuôi kẻ lề mề (Chống Slowloris DDoS)
Hacker thường sử dụng kỹ thuật ngâm kết nối (Slowloris) bằng cách gửi dữ liệu cực kỳ chậm, khiến HAProxy không thể giải phóng slot kết nối, dẫn đến cạn kiệt RAM. Chúng ta cần thiết lập ngưỡng Timeout cực kỳ nghiêm ngặt.
Tại Frontend (Cửa đón khách):
-
Điều hướng đến Services > HAProxy > Frontend, chỉnh sửa
HTTPS_Frontend. -
Cuộn xuống ô Advanced pass thru và bổ sung 2 dòng lệnh sau lên trên cùng:
timeout http-request 5s timeout client 10s(Luật này quy định: Khách hàng chỉ có tối đa 5 giây để gửi xong HTTP Request và 10 giây cho toàn bộ kết nối. Quá hạn, HAProxy lập tức đá văng và thu hồi tài nguyên RAM).

Tại Backend (Máy chủ nội bộ):
-
Sang tab Backend, chỉnh sửa
Web_Server_Pool. -
Cuộn xuống ô Advanced pass thru, bổ sung dòng lệnh sau:
timeout server 10s(Luật này giúp HAProxy chủ động ngắt kết nối nếu Nginx phía sau bị nghẽn và phản hồi chậm hơn 10 giây, tránh tình trạng HAProxy bị treo lây).

Bước 3: Mở rộng sức chịu đựng Kernel và Bật Kháng thể SYN Flood
Nếu Tường lửa pfSense của bạn sở hữu lượng RAM vật lý lớn (từ 2GB trở lên), hãy tối ưu hóa nhân hệ thống (Kernel) để tối đa hóa năng lực xử lý.
1. Mở rộng State Table (Bảng trạng thái Firewall Tầng 4):
-
Truy cập System > Advanced > Firewall & NAT.
-
Tìm đến trường Firewall Maximum States.
-
Tăng giá trị lên
1000000(1 triệu states). Nhấn Save. Việc này giúp pfSense không bị nghẽn khi đối phó với số lượng IP ma cực lớn.

2. Kích hoạt TCP Syncookies: Đây là công nghệ "kháng thể" xuất sắc giúp Tường lửa phản hồi hàng triệu gói tin SYN rác mà không tiêu tốn RAM để lưu trữ trạng thái kết nối ảo.
-
Truy cập System > Advanced > System Tunables.
-
Tìm tham số có tên
net.inet.tcp.syncookies. Nhấn biểu tượng cây bút chì (Edit) để chỉnh sửa.

-
Thay đổi giá trị từ
0(Tắt) thành1(Bật). -
Nhấn Save và Apply Changes.
Bước 4: Thiết lập "Chó gác cổng" Service Watchdog (Tự động phục hồi)
Trong vận hành hệ thống thực tế (DevOps & SysAdmin), mục tiêu không phải là một hệ thống không bao giờ sập, mà là một hệ thống có khả năng tự phục hồi (Self-healing) nhanh nhất khi có sự cố Zero-day. pfSense cung cấp một Package tuyệt vời cho nhiệm vụ này là Service Watchdog.
-
Vào System > Package Manager > Available Packages.
-
Tìm và cài đặt gói
Service Watchdog.

-
Sau khi cài đặt hoàn tất, truy cập Services > Service Watchdog.
-
Nhấn Add New Service.
-
Trong menu thả xuống (Service Name), chọn
haproxyvà nhấn Add.

Kể từ thời điểm này, Service Watchdog sẽ hoạt động như một tiến trình ngầm, liên tục đi tuần tra định kỳ. Nếu phát hiện dịch vụ HAProxy bị sập vì bất kỳ lý do gì (do Kernel kill hoặc lỗi phần mềm), Watchdog sẽ tự động kích hoạt lệnh Start, gọi HAProxy sống lại chỉ trong tích tắc.