1. Giới thiệu.
1.1. HAProxy là gì?
HAProxy (High Availability Proxy) là một Load Balancer và Reverse Proxy mã nguồn mở, giúp:
✅ Phân phối tải giữa nhiều server (Load Balancing).
✅ Tăng khả năng chịu lỗi và tính sẵn sàng cao (High Availability).
✅ Hoạt động như một Reverse Proxy để bảo vệ backend servers.
Trong pfSense, HAProxy thường được dùng để:
- Cân bằng tải cho nhiều server web (Web Servers).
- Proxy HTTPS với chứng chỉ SSL.
- Chạy trên TCP/HTTP mode để điều hướng request.

1.2. SSL Wildcard là gì?
SSL Wildcard là một chứng chỉ SSL/TLS có thể bảo vệ nhiều subdomain của cùng một tên miền.
🔹 Cách hoạt động
- Chứng chỉ wildcard có dạng
*.example.com
, trong đó dấu*
đại diện cho bất kỳ subdomain nào. - Ví dụ, nếu bạn có một SSL wildcard cho
*.example.com
, nó sẽ bảo vệ:www.example.com
mail.example.com
blog.example.com
api.example.com
- Nhưng không bảo vệ
sub.sub.example.com
(chỉ áp dụng cho cấp 1).
🔹 Ưu điểm của SSL Wildcard
✅ Tiết kiệm chi phí – Một chứng chỉ duy nhất thay vì nhiều chứng chỉ riêng lẻ.
✅ Dễ dàng quản lý – Không cần phát hành chứng chỉ mới khi thêm subdomain.
✅ Bảo mật giống như SSL thông thường – Dùng mã hóa TLS mạnh.
🔹 Nhược điểm
⚠ Không bảo vệ subdomain cấp 2 trở lên (*.example.com
không bảo vệ sub.sub.example.com
).
⚠ Rủi ro khi bị lộ private key – Nếu một subdomain bị lộ key, tất cả subdomains khác cũng bị ảnh hưởng.
⚠ Không phù hợp cho tất cả các CA (Certificate Authority) – Một số tổ chức có chính sách nghiêm ngặt hơn về SSL Wildcard.
🔹 So sánh với SSL thông thường
Loại | Bảo vệ | Chi phí | Quản lý |
---|---|---|---|
Single-domain SSL | 1 domain (vd: example.com ) | Rẻ hơn | Dễ quản lý |
Wildcard SSL | Tất cả subdomain cấp 1 (*.example.com ) | Cao hơn | Tiện lợi hơn |
Multi-domain SSL (SAN/UCC) | Nhiều domain riêng lẻ (example.com , site.net ) | Cao hơn | Phức tạp hơn |
🔹 Khi nào nên dùng SSL Wildcard?
✔ Khi bạn có nhiều subdomain và muốn quản lý dễ dàng.
✔ Khi subdomain không yêu cầu chứng chỉ riêng biệt.
✔ Khi bạn muốn tiết kiệm chi phí so với mua nhiều SSL riêng lẻ.
2. Quy trình triển khai SSL Wildcard trong HAProxy chạy trên pfSense
2.1. Cài đặt gói HAProxy trên pfSense
Vào pfSense → System > Package Manager > Available Packages

Tìm “HAProxy”, sau đó nhấn Install
.

Xác nhận cài đặt HAProxy.

Đợi quá trình cài đặt hoàn tất.

Sau khi cài đặt xong bạn có thể thấy HAProxy xuất hiện tại Services/HAProxy.

2.2. Kiểm tra SSL đã sẵn sàng chưa.
Vào System/Certificates kiểm tra SSL đã sẵn sàng chưa.

Mình đã có Root CA tự sinh cùng với các SSL Wildcard tự sinh từ Root CA đó là Monitoring CA và Wiki CA.

Sang tab Certificates mình có các danh sách SSL như dưới, mình sử dụng Wildcard của Monitoring để demo nhé.

2.4. Kích hoạt HAProxy & tạo backend servers
Vào Services > HAProxy

Chuyển đến tab “Settings” và Enable HAProxy: ✅ Check. Phần Maximum connections tùy vào resource mà bạn có để lựa chọn cho phù hợp.

Kéo xuống phần Tunning, tại SSL/TLS Compatibility Mode. Trong pfSense, phần Tuning của HAProxy có một tùy chọn SSL/TLS Compatibility Mode, cho phép bạn chọn mức độ tương thích SSL/TLS giữa máy khách và server backend.
🔹 Các tùy chọn trong SSL/TLS Compatibility Mode:
- Auto (Khuyến nghị nếu không chắc chắn) – Tự động chọn chế độ tốt nhất dựa trên phiên bản HAProxy và hệ thống.
- Old mode – Tắt SSLv3 và một số cipher yếu nhưng vẫn hỗ trợ TLS 1.0/1.1 (KHÔNG nên dùng trừ khi cần hỗ trợ hệ thống cũ).
- Intermediate mode (Khuyến nghị cho hầu hết các trường hợp) –
- Tắt TLS 1.0, TLS 1.1, SHA1 và các ciphers mạnh (HIGH)
- Chỉ hỗ trợ TLS 1.2 và TLS 1.3
- Thích hợp cho các trình duyệt và hệ thống hiện đại.
- Modern mode –
- Chỉ hỗ trợ TLS 1.3
- Không hỗ trợ TLS 1.2 (có thể gây lỗi nếu client chưa hỗ trợ TLS 1.3).
✔ Gợi ý:
- Nếu bạn không có hệ thống cũ cần hỗ trợ → Chọn Intermediate mode.
- Nếu chỉ muốn hỗ trợ trình duyệt mới nhất và server mới → Chọn Modern mode.
- Nếu không chắc chắn → Để Auto.
🔹 Max SSL Diffie-Hellman size là kích thước tối đa của khóa Diffie-Hellman (DH) khi sử dụng ciphers dựa trên DH để thiết lập kết nối SSL/TLS. Cách chọn giá trị phù hợp.
- 2048-bit (Mặc định, Khuyến nghị) – Cân bằng giữa bảo mật và hiệu suất. Được khuyến nghị cho hầu hết các trường hợp.
- 4096-bit (Bảo mật cao hơn) – Tăng cường bảo mật nhưng ảnh hưởng đến hiệu suất vì tiêu tốn nhiều tài nguyên CPU hơn.
- 1024-bit hoặc thấp hơn (Không khuyến nghị) – Không đủ an toàn, có thể bị tấn công.
✔ Gợi ý: Nếu hệ thống của bạn có tài nguyên đủ mạnh, hãy chọn 4096-bit để tối đa bảo mật. Nếu cần cân bằng hiệu suất, 2048-bit là lựa chọn an toàn.

2.5. Tạo Backend Servers.
Chuyển đến tab Backend → Nhấn Add và điền backend server đầu tiên vào, ví dụ prometheus_backend
. Do chỉ là lab chính về ssl wildcard nên mình chỉ sử dụng 1 server cho 1 dịch vụ.

Tiếp theo hãy tiếp tục chuyển đến tab Backend → Nhấn Add và điền backend server thứ 2 vào. Ví dụ prometheus_backend
.

Sau khi tạo xong 2 backend, bạn có kết quả như dưới. Hiện tại chúng chưa được sử dụng nên chúng sẽ có màu xám.

2.6. Tạo Frontend để nhận request từ người dùng
- Vào tab “Frontend” → Nhấn Add
- Điền thông tin:
- Name:
monitoring_frontend
- Listen Address: WAN interface hoặc
0.0.0.0:10443
- Type:
http/https(offloading)
- Port (port của frontend): 10443
- SSL Offloading (nếu cần):
- Nếu bạn có chứng chỉ SSL, bật tùy chọn
Enable SSL Offloading
. - Chọn chứng chỉ phù hợp (Let’s Encrypt hoặc tự cấp).
- Mình đang muốn lab demo SSL Wildcard nên mình sử dụng SSL Offloading.
- Nếu bạn có chứng chỉ SSL, bật tùy chọn
- Name:

Tại Default backend, access control lists and actions
hãy tạo các ACL như sau:
- Access Control lists:
- Đặt tên ACL 1 là
prometheus_backend
:- Value (tên domain mà client sẽ request): prometheus.hoanghd.com
- Đặt tên ACL 2 là
grafana_backend
:- Value (tên domain mà client sẽ request): grafana.hoanghd.com
- Đặt tên ACL 1 là
- Actions (lựa chọn tên ACL tương ứng với backend) như hình.

Kéo xuống tiếp phần Advanced settings thêm tùy chọn sau vào Advanced pass thru
. Dòng này giúp backend biết request ban đầu là HTTPS, tránh lỗi chuyển hướng hoặc nội dung hỗn hợp (mixed content).
http-request set-header X-Forwarded-Proto https if { ssl_fc }
Kết quả sẽ như hình.

🔹 Chức năng:
Dòng này thiết lập header X-Forwarded-Proto
thành https
khi yêu cầu đến HAProxy sử dụng SSL/TLS (ssl_fc = frontend connection đang sử dụng SSL).
🔹 Tại sao cần dùng?
- Khi HAProxy xử lý SSL và chuyển tiếp request đến backend qua HTTP, backend không tự biết request gốc là HTTPS.
- Một số ứng dụng hoặc backend server cần header này để phát hiện và xử lý request HTTPS đúng cách (ví dụ: chuyển hướng, xác định đường dẫn an toàn).
🔹 Ví dụ thực tế:
Giả sử bạn có HAProxy làm load balancer cho Nginx backend.
- Người dùng truy cập
https://example.com
- HAProxy xử lý SSL, nhưng chuyển tiếp đến backend qua HTTP (
http://backend.local
). - Backend thấy request đến bằng HTTP và có thể chuyển hướng sai hoặc không bật HTTPS các tài nguyên.
⚡ Giải pháp:
Bằng cách thêm X-Forwarded-Proto: https
, backend nhận biết request gốc là HTTPS và xử lý đúng (giữ HTTPS, không chuyển hướng sai).
✔ Khi nào nên dùng?
- Khi HAProxy chấm dứt SSL (SSL Termination) trước backend.
- Khi backend dựa vào
X-Forwarded-Proto
để phân biệt HTTP/HTTPS.
Kéo xuống tiếp SSL Offloading
, đơn giản chỗ này bạn chỉ cần chọn SSL Wildcard mà bạn muốn sử dụng. Trường hợp của mình, mình lựa chọn Grafana And Prometheus SSL (CA: Monitoring CA) [Server cert]
.

Thiết lập frontend đã xong, kéo xuống dưới cùng lưu lại thay đổi và bạn có kết quả.

Phần backend lúc này cũng đã được enable.

2.7. Cấu hình Firewall Rules
Vào Firewall > Rules > WAN

- Nhấn Add Rule để mở cổng 10443 (HTTPS) cho HAProxy:
- Action: Pass
- Interface: WAN
- Protocol: TCP
- Destination Port:
10443
- Nhấn Save & Apply.

Bạn được kết quả.

3. Verify.
Kiểm tra kêt quả mở port 10443 từ client.
shell> telnet grafana.hoanghd.com 10443
Trying 113.161.233.3...
Connected to grafana.hoanghd.com.
Escape character is '^]'.
shell> telnet prometheus.hoanghd.com 10443
Trying 113.161.233.3...
Connected to prometheus.hoanghd.com.
Escape character is '^]'.
Kết quả cho https://prometheus.hoanghd.com:10443/query.

Kết quả cho https://grafana.hoanghd.com:10443/login.

Muốn xanh lá thì các bạn có thể sử dụng SSL của các nhà cung cấp SSL ví dụ như Let’s Encrypt hoặc trust SSL hiện tại vào client của bạn nhé.