1. Giới Thiệu
Ngày nay, hầu hết các trang web đều sử dụng giao thức HTTPS để bảo mật thông tin. Tuy nhiên, không phải tất cả các trang web đều được cấu hình tối ưu về bảo mật TLS. Bạn có thể kiểm tra mức độ an toàn của website mình thông qua công cụ SSL Labs tại https://www.ssllabs.com/ssltest/.

Bài viết này hướng dẫn bạn từng bước để cấu hình pfSense và HAProxy nhằm đạt điểm số tối đa trên SSL Labs, với hạng A+ và các tiêu chí tối ưu:
✔ Chứng chỉ: 100% ✔ Hỗ trợ giao thức: 100% ✔ Trao đổi khóa: 100% ✔ Mã hóa mạnh: 100% ✔ Hỗ trợ TLS 1.3, HSTS và DNS CAA
2. Cài Đặt pfSense.
Trước tiên, bạn cần cài đặt pfSense trên hệ thống. Nếu bạn chưa cài đặt, hãy tải về phiên bản mới nhất tại trang chính thức của pfSense.
Bạn có thể sử dụng phiên bản ổn định hoặc bản phát triển.
Sau khi cài đặt xong:
- Truy cập vào giao diện quản trị pfSense.
- Đổi giao thức WebGUI từ HTTP sang HTTPS.
- Thiết lập cổng không mặc định (ví dụ:
10443
) để tăng cường bảo mật.
Thực hiện thay đổi này tại System → Advanced → Admin Access.
3. Cài Đặt HAProxy và ACME.
Tiếp theo, ta cần cài đặt hai gói quan trọng:
- HAProxy-devel: Cung cấp khả năng Reverse Proxy với hỗ trợ SSL mạnh mẽ.
- ACME: Dùng để tự động cấp và gia hạn chứng chỉ SSL từ Let’s Encrypt.
Cách cài đặt:
- Vào System → Package Manager → Available Packages.
- Tìm kiếm haproxy-devel và acme.
- Cài đặt cả hai gói này.
4. Cấu Hình ACME để Lấy Chứng Chỉ SSL
4.1 Đăng Ký Tài Khoản Let’s Encrypt
- Truy cập Services → Acme → Account Keys.
- Nhấn Create New Account Key.
- Chọn Let’s Encrypt Production.
- Nhấn Register ACME Account Key để đăng ký.
Cả Let’s Encrypt Staging ACME v2 và Let’s Encrypt Production ACME v2 đều miễn phí hoàn toàn.
1️⃣ Staging ACME v2 (Dùng để TEST)
- Không giới hạn số lần yêu cầu chứng chỉ.
- Dùng để kiểm tra cấu hình trước khi cấp chứng chỉ thật.
- Sử dụng chứng chỉ KHÔNG ĐƯỢC TIN CẬY bởi trình duyệt (vì nó dùng CA trung gian thử nghiệm).
2️⃣ Production ACME v2 (Dùng thực tế)
- Có giới hạn số lần cấp chứng chỉ (50 chứng chỉ mỗi tuần cho cùng một domain).
- Chứng chỉ được trình duyệt tin cậy, dùng cho website thực tế.
👉 Nếu bạn đang triển khai thật, hãy chọn “Production ACME v2”.
👉 Nếu đang test cấu hình, nên dùng “Staging ACME v2” để tránh bị giới hạn request. 🚀
4.2 Tạo Chứng Chỉ SSL
- Vào Services → Acme → Certificates.
- Nhấn Add để thêm chứng chỉ mới.
- Chọn 384-bit ECDSA cho private key (Private Key). Điều này giúp đạt 100% điểm trên SSL Labs.
- Thêm tên miền của bạn vào Domain SAN List.
- Nếu cần Wildcard SSL, hãy thêm
*.example.com
vào danh sách này. - Nhấn Issue/Renew Certificate để lấy chứng chỉ.
💡 Lưu ý: Nếu sử dụng xác thực DNS, bạn có thể chọn DNS API phù hợp với nhà cung cấp DNS của mình.
5. Kiểm Tra Chứng Chỉ
Sau khi lấy chứng chỉ thành công, bạn có thể kiểm tra trong System → Cert Manager → Certificates.
Các thông tin cần có:
- OCSP: Must Staple ✅
- Key Type: ECDSA ✅
- Elliptic Curve: secp384r1 ✅
Nếu mọi thứ đúng, bạn đã sẵn sàng cấu hình HAProxy.
6. Cấu hình Advanced Options cho HAProxy.
Sau khi thiết lập chứng chỉ và SSL Offloading, bạn cần tinh chỉnh một số tùy chọn nâng cao để đảm bảo hiệu suất và bảo mật tối ưu.
6.1. Enable HAProxy.
Hãy vào Services / HAProxy / Settings và Enable HAProxy lên. Tùy vào resource mà bạn có thể cho phép lượng Maximum connections
phù hợp.

Có 2 thiết lập quan trọng trong HAProxy liên quan đến bảo mật SSL/TLS:
- SSL/TLS Compatibility Mode
- Old Mode:
- Tắt SSLv3 (rất cũ, không an toàn).
- Intermediate Mode(Khuyến nghị):
- Tắt các cipher HIGH, SHA1, TLS 1.0 và TLS 1.1.
- Chỉ hỗ trợ TLS 1.2 và TLS 1.3, giúp cân bằng giữa bảo mật và khả năng tương thích.
- Modern Mode:
- Chỉ hỗ trợ TLS 1.3 và các AEAD cipher (ciphers an toàn hơn như AES-GCM, ChaCha20).
- Cực kỳ bảo mật nhưng có thể khiến một số thiết bị hoặc trình duyệt cũ không kết nối được.
- Auto(Mặc định nếu không chọn gì):
- HAProxy tự động chọn cấu hình dựa trên cài đặt mặc định của phiên bản đang chạy.
- Old Mode:
- Max SSL Diffie-Hellman size
- Giá trị hiện tại: 2048 (Mặc định)
- Khuyến nghị: 4096 để đạt điểm tối đa (100%) trên SSL Labs.
- Đây là độ dài của khóa Diffie-Hellman (DHE) dùng trong trao đổi khóa tạm thời (ephemeral key exchange).
- Bigger values = More security nhưng cũng tốn CPU hơn.
- Nếu không thiết lập, HAProxy sẽ cảnh báo khi khởi động.
🔹 Tóm lại:
- Chọn “Intermediate” nếu bạn muốn cân bằng giữa bảo mật và tương thích.
- Chọn “Modern” nếu bạn muốn bảo mật tối đa, nhưng có nguy cơ không hỗ trợ thiết bị cũ.
- Nâng Max SSL Diffie-Hellman size lên 4096 nếu muốn đạt 100% điểm SSL Labs, dù có thể tốn tài nguyên CPU hơn.

6.2. Enable Backend.
Cấu hình backend server trong HAProxy của pfSense.
Bạn cần đặt một tên (name) cho backend server để dễ quản lý. Chọn địa chỉ IP của backend server (server chạy ứng dụng web, ví dụ như một server Apache hoặc Nginx).
Nên sử dụng port 443 và bật “Encrypt(SSL)”. Có thể sử dụng HTTP (port 80) nhưng sẽ không an toàn (mình không chọn Encrypt SSL vì backend của mình chạy ở port 80). Khi bật tùy chọn này, mọi kết nối từ pfSense đến backend server sẽ được mã hóa bằng SSL 🔒. Nếu tắt HAProxy vẫn có thể cung cấp HTTPS trên frontend, nhưng lưu lượng giữa firewall và backend server sẽ không được mã hóa. Điều này có thể tạo rủi ro bảo mật nếu mạng nội bộ không an toàn hoặc có thể bị xâm nhập.
Nếu backend server có chứng chỉ hợp lệ (được cấp bởi CA như Let’s Encrypt, DigiCert…), bạn có thể bật “SSL checks” để HAProxy kiểm tra chứng chỉ.
Nếu backend server chỉ có chứng chỉ tự ký (self-signed certificate), việc bật SSL checks có thể gây lỗi xác thực, vì vậy tác mình đã không chọn tùy chọn này.

Cấu hình Health Check (kiểm tra tình trạng backend server) trong HAProxy trên pfSense để đảm bảo backend server vẫn đang hoạt động.
- Bật Health Checking ✅
- Mình sử dụng tính năng Health Check của HAProxy để kiểm tra trạng thái của backend server.
- Nếu backend server không phản hồi hoặc phản hồi lỗi, HAProxy sẽ tự động ngừng gửi lưu lượng đến backend đó.
- Chọn phương thức kiểm tra sức khỏe (Health Check Method)
- Phương thức được chọn:
HTTP
- Khi sử dụng HTTP làm phương thức kiểm tra, HAProxy sẽ gửi một request HTTP đến backend server và xem xét phản hồi.
- Phương thức được chọn:
- Ghi log (Log Checks) 📜
- Bật tùy chọn “Log checks” để lưu lại kết quả kiểm tra vào log của HAProxy.
- Điều này giúp dễ dàng theo dõi nếu có vấn đề xảy ra.
- Chọn phương thức HTTP để kiểm tra
- Mình chọn phương thức
OPTIONS
OPTIONS
là một phương thức HTTP nhẹ, cho phép kiểm tra xem backend có phản hồi được không mà không tải thêm dữ liệu nhưGET
.- Nếu
OPTIONS
không hoạt động, có thể thửGET
.
- Mình chọn phương thức
- Xử lý vấn đề với IIS (Internet Information Services)
- Nếu Backend server của bạn là IIS (server web của Microsoft).
- IIS không phản hồi tốt với HTTP/1.0, vì mặc định HAProxy gửi request bằng
HTTP/1.0
. - Để khắc phục bạn có thể chủ động đặt phiên bản HTTP là
HTTP/1.1
, bằng cách nhập dòng sau vào HAProxyHTTP/1.1\r\nHost:\ www.goldhammer.se
- Dòng này yêu cầu HAProxy gửi request với HTTP/1.1, kèm theo header “Host” để IIS xử lý đúng request.

✔ Mục đích: Đảm bảo backend server đang hoạt động bằng cách gửi request kiểm tra sức khỏe.
✔ Cách làm: Sử dụng HTTP Health Check với phương thức OPTIONS
hoặc GET
.
✔ Xử lý lỗi: Nếu backend là IIS, cần đặt HTTP/1.1 để tránh lỗi.
Lưu lại và chúng ta có kết quả.

6.3. Enable Frontend.
Cấu hình Frontend Listener trong HAProxy trên pfSense tuân theo quy trình sau:
- Chuyển hướng HTTP sang HTTPS
- Cấu hình SSL Offloading
- Thiết lập Access Control List (ACL)
Tạo Frontend Listener đầu tiên (HTTP → HTTPS)
- Vào HAProxy / Frontend, bấm Add để thêm một Frontend Listener.
- Chuyển hướng HTTP (port 80) sang HTTPS (port 443):
- Listen address chọn WAN address (IPv4) -> mình chọn WAN address (IPv4) vì mình sẽ truy cập website từ IP WAN.
- Nhập 443 vào ô Port.
- Chọn http / https(offloading) trong phần Type.
- Mục tiêu: Chuyển hướng toàn bộ HTTP traffic sang HTTPS.

Tạo Access Control List (ACL) để xử lý chuyển hướng.
- Tạo một ACL với điều kiện:
- Tất cả traffic đi qua cổng 80.
- Tên miền chứa từ “goldhammer” sẽ bị chuyển hướng đến HTTPS trên port 443.
- Tạo Action cho ACL này:
- http-request redirect location → Chuyển hướng sang HTTPS.

Cấu hình SSL Offloading.
- Chọn SSL Certificate đã tạo trước đó.
- Bật OCSP (Online Certificate Status Protocol) để kiểm tra trạng thái chứng chỉ SSL trong thời gian thực.

Bật HSTS (HTTP Strict Transport Security)
HSTS giúp trình duyệt tự động chuyển hướng mọi kết nối HTTP sang HTTPS, ngăn chặn các cuộc tấn công downgrade (hạ cấp giao thức). Để bật HSTS, thêm quy tắc sau vào phần Advanced pass thru trong Frontend:
http-response set-header Strict-Transport-Security "max-age=31536000; includeSubDomains; preload"
Hình ảnh đã thêm quy tắc trên vào phần Advanced pass thru trong Frontend.

Tùy chọn này sẽ:
- max-age=31536000: Buộc trình duyệt chỉ sử dụng HTTPS trong 1 năm (31.536.000 giây).
- includeSubDomains: Áp dụng HSTS cho tất cả các subdomains.
- preload: Cho phép website được thêm vào danh sách preload HSTS toàn cầu của trình duyệt.
Cấu hình X-Forwarded-For và X-Forwarded-Proto
Để đảm bảo rằng các backend server nhận biết đúng giao thức gốc và địa chỉ IP của client, bạn cần thêm các header sau:
http-request set-header X-Forwarded-Proto https if { ssl_fc }
http-request set-header X-Forwarded-For %[src]
X-Forwarded-Proto
: Cho backend biết rằng kết nối ban đầu là HTTPS.X-Forwarded-For
: Giữ lại IP gốc của client thay vì hiển thị IP của HAProxy.

Cấu hình Security Headers để tối đa hóa bảo mật.
Bổ sung các header bảo mật quan trọng giúp bảo vệ website khỏi XSS, Clickjacking và các mối đe dọa khác:
http-response set-header X-Frame-Options DENY
http-response set-header X-XSS-Protection "1; mode=block"
http-response set-header X-Content-Type-Options nosniff
http-response set-header Referrer-Policy "no-referrer-when-downgrade"
http-response set-header Content-Security-Policy "default-src 'self'; script-src 'self'"
X-Frame-Options DENY
: Chặn việc nhúng trang web vào iframe để tránh Clickjacking.X-XSS-Protection
: Ngăn chặn tấn công XSS bằng cách chặn các script độc hại.X-Content-Type-Options nosniff
: Ngăn trình duyệt đoán kiểu dữ liệu để tránh lỗ hổng MIME-sniffing.Referrer-Policy
: Kiểm soát cách trình duyệt gửi thông tin referrer.Content-Security-Policy
: Giới hạn tài nguyên mà trang web có thể tải, chỉ cho phép script từ chính domain.

Kiểm tra lại và lưu cấu hình.

7. Đừng quên mở Firewall Rule TCP/443 cho cổng WAN nhé.

8. Verify.
Sau khi hoàn tất các thiết lập, hãy kiểm tra lại toàn bộ cấu hình bằng cách:
- Kiểm tra logs của HAProxy:
- Vào Status > HAProxy để xem trạng thái backend và frontend.
- Mở Diagnostics > System Logs > HAProxy để kiểm tra lỗi.
- Kiểm tra chứng chỉ SSL tại SSLLabs:
- Truy cập SSL Labs Test và nhập tên miền để kiểm tra độ bảo mật của cấu hình SSL.
- Nếu có cảnh báo về cipher hoặc giao thức, bạn có thể điều chỉnh lại SSL/TLS Compatibility Mode trong HAProxy.
- Thử nghiệm truy cập từ trình duyệt:
- Kiểm tra xem trang web có tự động chuyển hướng từ HTTP sang HTTPS không.
- Kiểm tra Developer Tools (F12) > Network xem các header bảo mật đã được áp dụng đúng chưa.
Quay sát đây là điểm số trước lúc mình chưa cấu hình.

Hãy tăng cường bảo mật cho HAProxy bằng cách loại bỏ các cipher suite yếu và chỉ sử dụng các thuật toán mã hóa mạnh theo khuyến nghị của SSL Labs. Mục tiêu là đạt điểm tối đa (100%) trên SSL Labs SSL Test.
Vấn đề ban đầu.
- Mặc định, HAProxy sử dụng cả 128-bit và 256-bit ciphers.
- SSL Labs khuyến nghị chỉ sử dụng các cipher suite có 256-bit để tăng cường bảo mật.
- Một số cipher suite yếu (128-bit) vẫn còn trong cấu hình, đặc biệt là trong TLS 1.2 và TLS 1.3.

Cách giải quyết.
- Loại bỏ tất cả các cipher suite 128-bit.
- Chỉ cho phép sử dụng các thuật toán mã hóa 256-bit.
- Chuyển đổi tên cipher từ IANA sang OpenSSL (do HAProxy sử dụng OpenSSL trong khi SSL Labs dùng IANA).
Cấu hình cipher suite cho TLS 1.2
Câu lệnh này sẽ giới hạn TLS 1.2 chỉ sử dụng các thuật toán mã hóa 256-bit:
ciphers ECDHE-RSA-AES256-GCM-SHA384:DHE-RSA-AES256-GCM-SHA384:ECDHE-RSA-CHACHA20-POLY1305:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-ECDSA-AES256-GCM-SHA384
- ECDHE-RSA-AES256-GCM-SHA384 → Mã hóa mạnh với ECDHE + AES-256 + SHA-384.
- DHE-RSA-AES256-GCM-SHA384 → Sử dụng DHE thay vì ECDHE.
- ECDHE-RSA-CHACHA20-POLY1305 → Sử dụng thuật toán ChaCha20, tối ưu cho thiết bị di động.
- ECDHE-ECDSA-CHACHA20-POLY1305 → Phiên bản ECDSA của ChaCha20.
- ECDHE-ECDSA-AES256-GCM-SHA384 → Sử dụng ECDSA thay vì RSA.
📌 Mục đích: Đảm bảo rằng chỉ các thuật toán ECDHE/DHE + AES-256 hoặc ChaCha20 mới được sử dụng.
Cấu hình cipher suite cho TLS 1.3
Câu lệnh sau chỉ giữ lại các cipher mạnh nhất cho TLS 1.3:
ciphersuites TLS_AES_256_GCM_SHA384:TLS_CHACHA20_POLY1305_SHA256
- TLS_AES_256_GCM_SHA384 → AES-256 với GCM mode.
- TLS_CHACHA20_POLY1305_SHA256 → ChaCha20 với SHA-256, hiệu quả hơn trên CPU không hỗ trợ AES-NI.
📌 Mục đích: Chặn các cipher yếu TLS_AES_128_GCM_SHA256 và chỉ giữ lại 256-bit.
Cấu hình độ dài đường cong elliptic
Thêm vào danh sách elliptic curve mạnh nhất:
curves secp384r1:secp521r1
- secp384r1 (NIST P-384) → Mạnh hơn secp256r1 (NIST P-256).
- secp521r1 (NIST P-521) → Độ bảo mật cao nhất.
📌 Mục đích: Đảm bảo HAProxy sử dụng elliptic curve mạnh hơn secp256r1.
🔹 Cấu hình đầy đủ trong HAProxy
curves secp384r1:secp521r1 ciphers ECDHE-RSA-AES256-GCM-SHA384:DHE-RSA-AES256-GCM-SHA384:ECDHE-RSA-CHACHA20-POLY1305:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-ECDSA-AES256-GCM-SHA384 ciphersuites TLS_AES_256_GCM_SHA384:TLS_CHACHA20_POLY1305_SHA256
📌 Tất cả phải nằm trên một dòng duy nhất trong HAProxy trên pfSense.
🔹 Kết quả
✔ Loại bỏ hoàn toàn cipher 128-bit.
✔ Chỉ sử dụng cipher mạnh (256-bit, ChaCha20, AES-GCM).
✔ Điểm bảo mật trên SSL Labs sẽ tăng lên mức tối đa.
✔ Tương thích tốt với thiết bị hiện đại và di động.
🔹 Nếu cần đơn giản hóa
Nếu muốn cấu hình ngắn hơn nhưng vẫn an toàn:
ssl-default-bind-options no-sslv3 no-tlsv10 no-tlsv11
ssl-default-bind-ciphers ECDHE+AESGCM:ECDHE+CHACHA20
ssl-default-bind-ciphersuites TLS_AES_256_GCM_SHA384:TLS_CHACHA20_POLY1305_SHA256
Kết quả tổng thể.

Kết quả của Cipher Suites.

📌 Đây là một cách viết đơn giản hơn nhưng vẫn đảm bảo bảo mật.
Trong báo cáo kiểm tra bảo mật (có thể là của SSL Labs), có một cảnh báo liên quan đến DNS CAA (Certification Authority Authorization).

- Mặc định, nếu không có CAA record, bất kỳ Certificate Authority (CA) nào cũng có thể cấp chứng chỉ SSL cho domain.
- Điều này có thể tạo ra rủi ro bảo mật nếu một CA không đáng tin cậy cấp chứng chỉ cho domain của bạn.
Giải pháp: Sử dụng CAA record
CAA (Certification Authority Authorization) là một loại bản ghi DNS giúp chủ sở hữu domain chỉ định CA nào được phép cấp chứng chỉ SSL cho domain.
Ví dụ:
0 issue "letsencrypt.org"
Điều này có nghĩa là chỉ có Let’s Encrypt mới được phép cấp chứng chỉ SSL cho domain của bạn.
Cách thêm CAA record
- Vào trang quản lý DNS của bạn (Cloudflare, GoDaddy, Namecheap, v.v.).
- Thêm một bản ghi DNS kiểu CAA với giá trị:
0 issue "letsencrypt.org"
- Nếu sử dụng một CA khác (ví dụ: DigiCert), bạn cần thay đổi thành:
0 issue "digicert.com"
Bạn không cần mua tên miền từ Cloudflare để sử dụng DNS của Cloudflare. Chỉ cần bạn trỏ nameserver (NS) của tên miền về Cloudflare, thì bạn có thể quản lý DNS trên Cloudflare và thêm CAA record bình thường.
Cách làm:
1️⃣ Đăng ký tài khoản Cloudflare (nếu chưa có).
2️⃣ Thêm tên miền của bạn vào Cloudflare.
3️⃣ Cloudflare sẽ cung cấp nameservers mới (ví dụ: alice.ns.cloudflare.com
, bob.ns.cloudflare.com
).
4️⃣ Vào trang quản lý tên miền (nơi bạn mua domain) và thay đổi nameservers theo Cloudflare.
5️⃣ Chờ DNS cập nhật (thường từ 5 phút đến vài giờ).
6️⃣ Sau khi domain hoạt động trên Cloudflare vào DNS Settings và thêm CAA record như sau:
Type: CAA
Name: @
Value: 0 issue "letsencrypt.org"
Vậy là xong! Bạn có thể tiếp tục dùng Let’s Encrypt mà vẫn có bảo mật cao hơn với CAA record. ✅
Ý nghĩa của các giá trị trong CAA record
0 issue "letsencrypt.org"
0
→ Flag (thường là 0, nghĩa là không yêu cầu xử lý đặc biệt).issue
→ Chỉ định CA nào được phép cấp chứng chỉ."letsencrypt.org"
→ CA được phép cấp chứng chỉ.
Ngoài ra, có thể dùng:
issuewild
→ Chỉ định CA nào được phép cấp chứng chỉ wildcard (*.domain.com
).iodef
→ Xác định email hoặc URL để nhận thông báo khi có yêu cầu cấp chứng chỉ trái phép.
Ví dụ nâng cao:
0 issue "letsencrypt.org"
0 issuewild "letsencrypt.org"
0 iodef "mailto:hoanghd164@gmail.com"
Kết quả mong đợi
Sau khi thêm CAA record:
✅ Chỉ Let’s Encrypt có thể cấp chứng chỉ cho domain của bạn.
✅ Hạn chế rủi ro bị cấp chứng chỉ trái phép bởi các CA khác.
✅ Cải thiện bảo mật SSL/TLS cho website.

💡 Kết luận
- Cấu hình này giúp tối ưu bảo mật cho HAProxy trên pfSense bằng cách chỉ giữ lại các thuật toán mã hóa mạnh nhất.
- Đạt điểm tối đa trên SSL Labs bằng cách loại bỏ hoàn toàn cipher 128-bit.
- Hỗ trợ tốt cả thiết bị di động lẫn hệ thống mạnh nhờ ChaCha20 và AES-GCM.
- Chạy ổn định trên HAProxy và giảm nguy cơ tấn công MITM.
9. Kết luận.
Sau khi hoàn tất các bước trên, bạn sẽ có một cấu hình HAProxy bảo mật, đạt điểm tối đa tại SSLLabs và hỗ trợ đầy đủ TLS 1.3. Điều này giúp tăng cường bảo mật cho hệ thống và đảm bảo kết nối an toàn cho người dùng.