文章目录
前言
之前的一篇文章《自建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 的转发