在Nginx反向代理架构中,与上游(后端)服务建立SSL双向认证,是保障敏感API接口通信安全的重要手段。它能有效验证通信双方身份的合法性,确保数据在传输链路上的机密性与完整性。本文将深入解析相关配置指令,并通过实战演示完整的配置流程。
Nginx反向代理SSL指令详解
在与上游HTTPS服务器建立连接时,Nginx提供了一系列以 proxy_ssl_ 开头的指令,用于配置证书、协议和验证行为。
-
proxy_ssl_certificate: 指定PEM格式的证书文件,用于Nginx向上游服务器证明自身身份。
Syntax: proxy_ssl_certificate file;
Default: —
Context: http, server, location
-
proxy_ssl_certificate_key: 指定与证书对应的PEM格式私钥文件。
Syntax: proxy_ssl_certificate_key file;
Default: —
Context: http, server, location
-
proxy_ssl_verify: 启用或禁用对上游服务器证书的验证。为确保安全,建议在生产环境中开启(on)。
Syntax: proxy_ssl_verify on | off;
Default: proxy_ssl_verify off;
Context: http, server, location
-
proxy_ssl_trusted_certificate: 指定PEM格式的受信任CA证书文件,用于验证上游服务器的证书。
Syntax: proxy_ssl_trusted_certificate file;
Default: —
Context: http, server, location
-
proxy_ssl_name: 允许覆盖用于验证上游服务器证书的服务器名称,并会在SNI(服务器名称指示)中传递。
Syntax: proxy_ssl_name name;
Default: proxy_ssl_name $proxy_host;
Context: http, server, location
-
proxy_ssl_server_name: 控制是否在与上游服务器建立TLS连接时传递SNI信息。
Syntax: proxy_ssl_server_name on | off;
Default: proxy_ssl_ssl_server_name off;
Context: http, server, location
-
proxy_ssl_protocols: 启用与上游服务器通信的特定SSL/TLS协议。
Syntax: proxy_ssl_protocols [SSLv2] [SSLv3] [TLSv1] [TLSv1.1] [TLSv1.2] [TLSv1.3];
Default: proxy_ssl_protocols TLSv1.2 TLSv1.3;
Context: http, server, location
-
proxy_ssl_ciphers: 定义与上游服务器通信使用的加密套件。
Syntax: proxy_ssl_ciphers ciphers;
Default: proxy_ssl_ciphers DEFAULT;
Context: http, server, location
其他辅助指令如 proxy_ssl_password_file(密钥密码文件)、proxy_ssl_verify_depth(验证深度)、proxy_ssl_session_reuse(会话复用)等,可根据实际场景按需配置。
实战:配置Nginx与上游服务SSL双向认证
本实践基于两台主机:213作为上游服务端,214作为反向代理服务器。我们将使用自签名CA签发三套证书:CA证书、服务器证书(供上游服务使用)、客户端证书(供Nginx代理使用)。
步骤一:环境与证书准备
假设证书文件已通过CA签发流程生成,分别拷贝至两台主机的Nginx证书目录。
# 在代理服务器(214)上
cp /tmp/certs/ca.crt /usr/local/nginx/certs/
cp /tmp/certs/server.crt /tmp/certs/server.key /usr/local/nginx/certs/
cp /tmp/certs/client.crt /tmp/certs/client.key /usr/local/nginx/certs/
# 在上游服务器(213)上
cp /tmp/certs/ca.crt /usr/local/nginx/certs/
cp /tmp/certs/app.crt /tmp/certs/app.key /usr/local/nginx/certs/
步骤二:配置上游服务端(213主机)
在上游服务器上配置两个HTTPS服务,监听不同端口,并强制要求客户端(即Nginx代理)提供证书。
# /usr/local/nginx/conf.d/upstream_server.conf
server {
listen 8443 ssl;
server_name app1.weiyigeek.top;
# 上游服务自身的证书
ssl_certificate /usr/local/nginx/certs/app.crt;
ssl_certificate_key /usr/local/nginx/certs/app.key;
# 要求并验证客户端证书(来自Nginx代理)
ssl_client_certificate /usr/local/nginx/certs/ca.crt; # 信任的CA,用于验证客户端证书
ssl_verify_client on; # 开启客户端证书验证
ssl_verify_depth 2;
ssl_protocols TLSv1.2 TLSv1.3;
# ... 其他SSL优化配置(如ciphers, session_cache等)可在此添加
location /certificate {
return 200 'Upstream Received Request.\nClient Cert Verified: $ssl_client_verify\nClient Subject: $ssl_client_s_dn';
}
}
server {
listen 9443 ssl;
server_name app2.weiyigeek.top;
# 配置同上,略...
}
配置完成后重启Nginx。此时,任何直接访问 https://app1.weiyigeek.top:8443/certificate 且未提供有效客户端证书的请求都将被拒绝。
步骤三:配置反向代理服务器(214主机)
在代理服务器上配置反向代理,并启用向上游服务的SSL双向认证。这是实现数据库与中间件安全通信的关键环节。
# /usr/local/nginx/conf.d/proxy_ssl_server.conf
upstream backend_servers {
zone backend_zone 64k;
server app1.weiyigeek.top:8443 max_fails=2 fail_timeout=10s;
server app2.weiyigeek.top:9443 max_fails=2 fail_timeout=10s;
keepalive 10;
}
server {
listen 80;
server_name server.weiyigeek.top;
location /api/ {
rewrite ^/api/(.*)$ /$1 break;
proxy_pass https://backend_servers;
# 关键配置:启用与上游的SSL双向认证
proxy_ssl_certificate /usr/local/nginx/certs/client.crt; # 代理持有的客户端证书
proxy_ssl_certificate_key /usr/local/nginx/certs/client.key; # 对应的私钥
proxy_ssl_protocols TLSv1.2 TLSv1.3;
# 验证上游服务器的证书
proxy_ssl_verify on;
proxy_ssl_trusted_certificate /usr/local/nginx/certs/ca.crt; # 信任的CA,用于验证上游证书
proxy_ssl_verify_depth 2;
# 传递SNI信息,重要!
proxy_ssl_server_name on;
# proxy_ssl_name app.weiyigeek.top; # 可按需覆盖SNI值
}
}
此配置完成了证书的生成与管理流程,是运维与DevOps工作中保障服务间通信安全的标准实践之一。配置完成后重启Nginx代理服务。
步骤四:验证测试
- 成功场景:访问
http://server.weiyigeek.top/api/certificate。Nginx代理会使用client.crt向上游服务认证自己,同时验证上游的证书。请求成功,并返回上游服务的响应信息,其中应包含 Client Cert Verified: SUCCESS。
- 失败场景:注释掉代理配置中的
proxy_ssl_certificate 和 proxy_ssl_certificate_key 指令并重载Nginx。再次访问上述地址,上游服务因未收到有效客户端证书而拒绝连接,Nginx代理将返回 400 Bad Request 或 502 Bad Gateway 错误。
总结
通过配置 proxy_ssl_certificate、proxy_ssl_verify 等指令,我们可以在Nginx反向代理与上游服务之间建立起坚固的SSL双向认证通道。这种方案特别适用于微服务内部、敏感API网关等需要高等级身份鉴别和数据安全的环境。在实际部署时,请务必使用由可信CA签发的证书,并妥善保管私钥文件。
|