Nginx使用HTTPS建立与上游服务器的网络通信
本文介绍了如何加密NGINX与上游组或代理服务器之间的HTTP通信。
先决条件
- NGINX开源或NGINX Plus
- 甲代理服务器或服务器的上游组
- SSL证书和私钥
获取SSL服务器证书
您可以从受信任的证书颁发机构(CA)购买服务器证书,也可以使用OpenSSL库创建自己的内部CA 并生成自己的证书。服务器证书以及私钥应放在每个上游服务器上。
获取SSL客户端证书
NGINX将使用SSL客户端证书向上游服务器标识自己。此客户端证书必须由受信任的CA签名,并在NGINX上与相应的私钥一起配置。
您还需要配置上游服务器,以要求所有传入的SSL连接都需要客户端证书,并信任颁发NGINX客户端证书的CA。然后,当NGINX连接到上游时,它将提供其客户端证书,而上游服务器将接受它。
配置NGINX
首先,将URL更改为上游组以支持SSL连接。在NGINX配置文件中,https
为proxy_pass
伪指令中的代理服务器或上游组指定“ ”协议:
location /upstream {
proxy_pass https://backend.example.com;
}
使用proxy_ssl_certificate
和proxy_ssl_certificate_key
指令添加客户端证书和将用于在每个上游服务器上对NGINX进行身份验证的密钥:
location /upstream {
proxy_pass https://backend.example.com;
proxy_ssl_certificate /etc/nginx/client.pem;
proxy_ssl_certificate_key /etc/nginx/client.key;
}
如果您对上游或您自己的CA使用自签名证书,请同时添加proxy_ssl_trusted_certificate
。该文件必须为PEM格式。(可选)包括proxy_ssl_verify
和proxy_ssl_verfiy_depth
指令,以使NGINX检查安全证书的有效性:
location /upstream {
#...
proxy_ssl_trusted_certificate /etc/nginx/trusted_ca_cert.crt;
proxy_ssl_verify on;
proxy_ssl_verify_depth 2;
#...
}
每个新的SSL连接都需要在客户端和服务器之间进行完整的SSL握手,这会占用大量CPU。要让NGINX代理先前协商过连接参数并使用所谓的缩写握手,请包含以下proxy_ssl_session_reuse
指令:
location /upstream {
#...
proxy_ssl_session_reuse on;
#...
}
(可选)您可以指定使用哪些SSL协议和密码:
location /upstream {
#...
proxy_ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
proxy_ssl_ciphers HIGH:!aNULL:!MD5;
}
配置上游服务器
每个上游服务器应配置为接受HTTPS连接。对于每个上游服务器,使用ssl_certificate
和ssl_certificate_key
指令指定服务器证书和私钥的路径:
server {
listen 443 ssl;
server_name backend1.example.com;
ssl_certificate /etc/ssl/certs/server.crt;
ssl_certificate_key /etc/ssl/certs/server.key;
#...
location /yourapp {
proxy_pass http://url_to_app.com;
#...
}
}
使用ssl_client_certificate
伪指令指定客户端证书的路径:
server {
#...
ssl_client_certificate /etc/ssl/certs/ca.crt;
ssl_verify_client optional;
#...
}
完整的例子
http {
#...
upstream backend.example.com {
server backend1.example.com:443;
server backend2.example.com:443;
}
server {
listen 80;
server_name www.example.com;
#...
location /upstream {
proxy_pass https://backend.example.com;
proxy_ssl_certificate /etc/nginx/client.pem;
proxy_ssl_certificate_key /etc/nginx/client.key;
proxy_ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
proxy_ssl_ciphers HIGH:!aNULL:!MD5;
proxy_ssl_trusted_certificate /etc/nginx/trusted_ca_cert.crt;
proxy_ssl_verify on;
proxy_ssl_verify_depth 2;
proxy_ssl_session_reuse on;
}
}
server {
listen 443 ssl;
server_name backend1.example.com;
ssl_certificate /etc/ssl/certs/server.crt;
ssl_certificate_key /etc/ssl/certs/server.key;
ssl_client_certificate /etc/ssl/certs/ca.crt;
ssl_verify_client optional;
location /yourapp {
proxy_pass http://url_to_app.com;
#...
}
server {
listen 443 ssl;
server_name backend2.example.com;
ssl_certificate /etc/ssl/certs/server.crt;
ssl_certificate_key /etc/ssl/certs/server.key;
ssl_client_certificate /etc/ssl/certs/ca.crt;
ssl_verify_client optional;
location /yourapp {
proxy_pass http://url_to_app.com;
#...
}
}
}
在此示例中,伪指令中的“ https
”协议proxy_pass
指定由NGINX转发到上游服务器的流量得到保护。
当安全连接第一次从NGINX传递到上游服务器时,将执行完整的握手过程。该proxy_ssl_certificate
伪指令定义上游服务器所需的PEM格式证书proxy_ssl_certificate_key
的位置,该伪指令定义证书的私钥的位置,并且proxy_ssl_protocols
和proxy_ssl_ciphers
伪指令控制使用哪些协议和密码。
下次NGINX将连接传递到上游服务器时,由于该proxy_ssl_session_reuse
指令,会话参数将被重用,并且安全连接的建立速度更快。
proxy_ssl_trusted_certificate
指令命名的文件中的受信任CA证书用于在上游验证证书。该proxy_ssl_verify_depth
伪指令指定检查证书链中的两个证书,并且该proxy_ssl_verify
伪指令验证证书的有效性。