文章目錄
- 前言
- 配置SSL證書
- SSL證書放在 Nginx 而不放在應用服務器上的好處
- Nginx只能轉發http協議嗎
- Nginx轉發TCP協議會收到端口限制嗎
- Nginx本身能將Websocket數據轉化成TCP數據嗎
- 總結
前言
之前的一篇文章《自建CA并生成自簽名SSL證書》中講到為什么要自建CA和自簽名SSL證書,是因為買證書得花錢,對于內部或小規模項目,使用自建SSL證書可能更為方便,不需要支付費用,而且不涉及復雜的驗證過程。正式對外的服務一般都是要買公共證書頒發機構(CA)簽發的SSL證書的,但是在對外發布前可以先使用自建證書打通流程
配置SSL證書
創建SSL證書的流程參考上文中提到的文章吧,本文只講怎樣把自建SSL證書配置到nginx,實際上非常簡單。
假設我們的自建證書是 /root/ca/server.crt
,服務器私鑰是 /root/ca/server.key
,nginx配置文件我以《記錄一下第一次安裝和配置Nginx》 這篇文章的配置文件為例,初始配置為:
upstream go_entrance {server localhost:4101;server localhost:4102;
}server {listen 4100;server_name localhost;location / {proxy_pass http://go_entrance;proxy_set_header Host $host;proxy_set_header X-Real-IP $remote_addr;proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;}
}
4100端口監聽http協議轉發到本機的4101端口和4102端口,如果把SSL證書配置到這個端口上,就相當于這個端口支持了https,配置修改如下:
upstream go_entrance {server localhost:4101;server localhost:4102;
}server {listen 4100 ssl;server_name localhost;ssl_certificate /root/ca/server.crt;ssl_certificate_key /root/ca/server.key;ssl_session_cache shared:SSL:10m;ssl_session_timeout 10m;ssl_protocols TLSv1 TLSv1.1 TLSv1.2;ssl_ciphers HIGH:!aNULL:!MD5;ssl_prefer_server_ciphers on; location / { proxy_pass http://go_entrance;proxy_set_header Host $host;proxy_set_header X-Real-IP $remote_addr;proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;}
}
只需要將4100端口后面加上 ssl,再配置幾個ssl相關的參數就可以了,含義如下:
-
ssl_certificate
: 指定 SSL 證書文件路徑 /root/ca/server.crt -
ssl_certificate_key
: 指定私鑰文件路徑 /root/ca/server.key -
ssl_session_cache
: 配置用于存儲 SSL 會話的緩存。shared:SSL:10m 表示使用共享的內存區域,最大占用內存為 10MB -
ssl_session_timeout
: 配置 SSL 會話的超時時間,這里設置為 10 分鐘 -
ssl_protocols
: 指定支持的 SSL/TLS 協議版本,這里包括 TLSv1、TLSv1.1 和 TLSv1.2 -
ssl_ciphers
: 指定支持的加密套件,這里配置為 HIGH:!aNULL:!MD5,表示使用高強度的加密套件,不支持空加密和 MD5
SSL證書放在 Nginx 而不放在應用服務器上的好處
正如上面的配置一樣,4100端口收到https請求后轉發到4101和4102上的是http協議,說明使用這種方式一些僅支持http協議的應用服務也可以通過nginx配置證書來達到支持https的目的,具體好處如下:
-
集中管理: 使用反向代理服務器管理 SSL 證書可以實現集中式管理。這意味著你可以在一個地方管理證書,而不需要在每個應用服務器上都安裝和維護證書。這樣能夠簡化證書的更新和維護流程。
-
簡化配置: 通過在反向代理服務器上配置 SSL,你可以簡化應用服務器的配置。應用服務器可以專注于處理應用程序邏輯,而無需關心 SSL 配置。這樣有助于提高系統的可維護性和簡化配置過程。
-
負載均衡和擴展: 如果你使用負載均衡,SSL終止(SSL Termination)在負載均衡器上執行可以減輕應用服務器的負擔。負載均衡器負責處理SSL握手,將非加密的請求轉發給后端應用服務器。這樣,后端服務器就可以專注于處理業務邏輯,而無需處理加密和解密操作。
-
性能優化: SSL 握手和加解密操作可能是計算密集型的任務,將這些任務從應用服務器中移除,可以在 SSL 握手和加解密方面提高性能。
-
統一的安全策略: 通過在反向代理服務器上管理 SSL,可以實施統一的安全策略,確保所有傳入和傳出的流量都經過相同的安全設置。
Nginx只能轉發http協議嗎
不,Nginx 不僅僅能夠轉發 HTTP 協議,還支持其他多種協議的代理轉發。主要的協議包括:
-
HTTPS協議: 通過在配置中啟用 SSL/TLS,Nginx 可以用作安全的 HTTPS 服務器和反向代理,處理加密的 HTTP 流量。
listen 443 ssl; ssl_certificate /path/to/certificate.crt; ssl_certificate_key /path/to/private-key.key;location / {proxy_pass https://backend_server; }
-
TCP協議: 從1.9版本開始 Nginx 可以用于代理 TCP 流量,例如數據庫連接、消息隊列等。
stream {server {listen 3306;proxy_pass backend_server:3306;} }
-
UDP協議: 從Nginx 1.9.13版本開始,開始支持 UDP 代理。這使得它可以用于代理 UDP 流量,如 DNS 請求等。
stream {server {listen 53 udp;proxy_pass backend_dns_server:53;} }
-
WebSocket協議: WebSocket 是一種在單個 TCP 連接上提供全雙工通信的協議,常用于實時應用程序,如在線游戲、聊天應用等。
map $http_upgrade $connection_upgrade {default upgrade;'' close; }server {listen 80;server_name your_domain.com;location /websocket {proxy_pass http://backend_server;proxy_http_version 1.1;proxy_set_header Upgrade $http_upgrade;proxy_set_header Connection $connection_upgrade;} }
Nginx轉發TCP協議會收到端口限制嗎
是的,TCP是一種面向連接的全雙工通信的協議,當轉發TCP消息時,Nginx不僅是一個服務器接受客戶端的連接,再它連接應用服務器時還表現成一個客戶端,每個連接需要消耗一個端口,以理論值65535個端口來計算,nginx最多轉發65535個連接,但是可以通過 proxy_bind
來突破限制,或者配置多個IP或虛擬IP也可以。
這種方式還沒測過,感興趣可以參考官方說明的看一下 https://nginx.org/r/proxy_bind
Nginx本身能將Websocket數據轉化成TCP數據嗎
只使用Nginx是做不到的,但是搭配Websockify就可以做到WSS(WebSocket Secure)到 TCP 的轉發
-
安裝 Nginx:
確保你的系統上已經安裝了 Nginx。你可以使用系統包管理器或從 Nginx 官方網站下載并安裝 -
安裝 Websockify:
安裝 Websockify,可以使用 pip 執行以下命令:pip install websockify
-
創建 Websockify 啟動腳本:
創建一個用于啟動 Websockify 的腳本,例如start_websockify.sh
。腳本內容可能如下所示:#!/bin/bash websockify --web /path/to/webroot 1234 localhost:5678
這里
1234
是用于 WebSocket 連接的端口,localhost:5678
是實際 TCP 服務的地址 -
配置 Nginx:
修改 Nginx 配置文件,將 WSS 請求轉發到 Websockify 啟動腳本。示例配置如下:server {listen 443 ssl;server_name your_domain.com;ssl_certificate /root/ca/server.crt;ssl_certificate_key /root/ca/server.key;location / {proxy_pass http://localhost:1234;proxy_http_version 1.1;proxy_set_header Upgrade $http_upgrade;proxy_set_header Connection "upgrade";proxy_set_header Host $host;} }
這里的
listen 443
表示監聽 HTTPS 請求,proxy_pass http://localhost:1234
將請求代理到 Websockify 啟動腳本 -
啟動服務:
啟動 Websockify 服務:chmod +x start_websockify.sh ./start_websockify.sh
啟動 Nginx 服務:
systemctl start nginx
-
測試:
使用支持 WebSocket 的客戶端連接到 WSS 地址,例如wss://your_domain.com
,并驗證是否成功將 WebSocket 請求轉發到 TCP 服務
總結
- nginx配置自建SSL證書,只需要修改nginx配置文件,在端口后配置添加 ssl 并指定證書和私鑰路徑即可
- nginx上配置SSL證書可以將證書統一管理,減輕應用服務器加密解密的負擔,專注于業務邏輯開發
- nginx不僅支持http協議轉發,還支持https、tcp、udp、websocket等協議的轉發
- nginx轉發tcp協議時會收到端口號個數限制,理論上限6萬,通過proxy_bind可以突破上限
- nginx搭配websockify可以做到WSS 到 TCP 的轉發
寒風終究是刮到我這里了