Reverse Proxy & TLS
Trên trang này
Nalix không tự kết thúc TLS. WebSocketListenerBase bind một socket TCP thô qua TcpListenerBase và tự phân tích HTTP/1.1 WebSocket Upgrade — không có việc kết thúc TLS wss:// trong tiến trình, trên bất kỳ hệ điều hành nào. Dữ liệu ứng dụng đã được bảo vệ khi truyền bằng handshake X25519 và mã hóa phiên ChaCha20-Poly1305 tích hợp sẵn (xem Handshake), nhưng điều đó không cung cấp wss://, chứng chỉ hợp lệ cho trình duyệt, hay SNI/xoay vòng chứng chỉ. Để có những thứ đó, hãy đặt một reverse proxy phía trước và để nó quản lý TLS.
Hướng dẫn này bao gồm các proxy thường được ghép cùng Nalix nhất: nginx (chứng chỉ thủ công qua certbot), Caddy (chứng chỉ tự động, không cần cấu hình gia hạn) và Cloudflare Tunnel (Cloudflare kết thúc TLS công khai và chuyển tiếp HTTP thuần tới origin).
Proxy phải làm gì
- Kết thúc TLS trên
:443và nói WebSocket thuần tới Nalix trênNetworkWebSocketOptions.Portđã cấu hình (mặc định57207). - Giữ nguyên các header
Upgrade/Connectioncho handshake WebSocket. - Chuyển tiếp IP client thật để
ConnectionGuardvà giới hạn tốc độ nhìn thấy client thực, không phải IP của proxy. - Gửi header
Originkhớp vớiNetworkWebSocketOptions.AllowedOriginsnếu bạn dùng kiểm tra origin CSWSH (xem WebSocket Options).
nginx
server {
listen 443 ssl http2;
server_name example.com;
ssl_certificate /etc/letsencrypt/live/example.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/example.com/privkey.pem;
ssl_protocols TLSv1.2 TLSv1.3;
location /ws/ {
proxy_pass http://127.0.0.1:57207;
proxy_http_version 1.1;
# WebSocket upgrade
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
# Real client IP + origin
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header CF-Connecting-IP ""; # not behind Cloudflare: drop client-supplied value
proxy_set_header Host $host;
# WebSocket connections are long-lived; don't let nginx kill them early
proxy_read_timeout 3600s;
proxy_send_timeout 3600s;
}
}
server {
listen 80;
server_name example.com;
return 301 https://$host$request_uri;
}
Gia hạn chứng chỉ (certbot, cron/systemd timer đã được gói cài đặt sẵn):
sudo certbot --nginx -d example.com
sudo systemctl status certbot.timer # auto-renewal, runs twice daily
Caddy
Caddy cho bạn wss:// với chứng chỉ Let’s Encrypt và gia hạn tự động, không cần certbot, không cần cron job:
example.com {
reverse_proxy /ws/* 127.0.0.1:57207 {
header_up X-Real-IP {remote_host}
header_up X-Forwarded-For {remote_host}
header_up -CF-Connecting-IP
}
}
Đó là toàn bộ cấu hình — Caddy tự cấp, cài đặt và gia hạn chứng chỉ ở yêu cầu đầu tiên.
Cloudflare Tunnel
Cloudflare Tunnel là cách thiết lập đơn giản nhất khi bạn không muốn lộ máy chủ Nalix ra ngoài hoặc tự quản lý chứng chỉ origin. Client kết nối tới wss://example.com/ws/; Cloudflare sở hữu chứng chỉ công khai và cloudflared chuyển tiếp lưu lượng WebSocket HTTP thuần tới Nalix.
Ví dụ ingress của cloudflared:
tunnel: nalix
credentials-file: /etc/cloudflared/nalix.json
ingress:
- hostname: example.com
service: http://127.0.0.1:57207
- service: http_status:404
Nalix vẫn nên bind vào loopback:
[NetworkWebSocket]
Host = 127.0.0.1
Port = 57207
AllowedOrigins = https://example.com
AllowMissingOrigin = false
[ForwardedHeaders]
Enabled = true
RequireTrustedProxy = true
Cloudflare gửi CF-Connecting-IP tới origin. Nalix đọc header đó trước X-Real-IP và X-Forwarded-For, nhưng chỉ chấp nhận từ một peer vật lý đáng tin cậy. Với Tunnel, hãy thêm peer cloudflared cục bộ vào trusted_proxies.txt; với cấu hình loopback ở trên, thường là 127.0.0.1 (và ::1 nếu dùng loopback IPv6).
CF-Connecting-IP chỉ đáng tin nếu không có gì ngoài Cloudflare có thể truy cập origin. Hãy giữ Nalix bind vào loopback phía sau cloudflared, hoặc, với origin được proxy (đám mây cam) mà không dùng Tunnel, hãy tường lửa origin chỉ cho phép dải IP của Cloudflare (hoặc proxy của bạn) — nếu không, một client kết nối trực tiếp có thể tự đặt header này.
Bạn không cần TLS giữa cloudflared và Nalix khi service dùng http://127.0.0.1:57207. Chỉ dùng origin service HTTPS khi bạn cố ý muốn TLS cục bộ tới origin.
Cấu hình phía Nalix
Khớp cấu hình proxy ở phía Nalix:
[NetworkWebSocket]
Host = 127.0.0.1 ; only listen on loopback, proxy is the public edge
Port = 57207
AllowedOrigins = https://example.com
AllowMissingOrigin = false
[ForwardedHeaders]
Enabled = true ; trust X-Forwarded-For / X-Real-IP / CF-Connecting-IP
RequireTrustedProxy = true
ClientIpHeader = Auto ; Auto, CfConnectingIp, XRealIp or XForwardedFor
ClientIpHeader chọn header nào mang IP client. Auto (mặc định) dùng header đầu tiên có mặt trong CF-Connecting-IP, X-Real-IP, X-Forwarded-For; bất kỳ giá trị nào khác chỉ đọc đúng header đó và bỏ qua các header còn lại, nên hãy đặt nó thành header duy nhất mà proxy của bạn luôn gửi (ví dụ XRealIp cho nginx/Caddy như cấu hình ở trên).
RequireTrustedProxy = true nghĩa là các header IP được chuyển tiếp chỉ được chấp nhận từ các IP có trong trusted_proxies.txt (TrustedProxyOptions.StoreFileName, nạp từ Directories.ConfigurationDirectory) — hãy thêm IP của máy nginx/Caddy (hoặc 127.0.0.1 nếu nó chạy cục bộ) vào file đó. Nếu không có điều này, bất kỳ client nào cũng có thể giả mạo X-Forwarded-For và vượt qua giới hạn tốc độ theo IP.
Xem Trusted Proxy Options để có tài liệu tham chiếu đầy đủ về tùy chọn. Bản thân ForwardedHeadersOptions (src/Nalix.Network/Options/ForwardedHeadersOptions.cs) có ba trường: Enabled, RequireTrustedProxy và ClientIpHeader.
Danh mục kiểm tra
-
Hostcủa Nalix bind vào127.0.0.1hoặc một interface nội bộ, không phải*, khi đã có proxy phía trước. -
ForwardedHeaders.Enabled = true,RequireTrustedProxy = true. - IP của proxy đã được thêm vào
trusted_proxies.txt. -
AllowedOriginsđược đặt thành (các) origin thật của bạn;AllowMissingOrigin = falsecho triển khai chỉ dành cho trình duyệt. -
proxy_read_timeout/ tương đương của proxy dài hơn kỳ vọng về idle timeout cho các kết nối WebSocket sống lâu. - Client kết nối tới
wss://example.com/ws/, không phải cổng Nalix thô. - Với Cloudflare Tunnel, ingress của
cloudflaredtrỏ tớihttp://127.0.0.1:57207trừ khi bạn cố ý chạy TLS ở origin.