前言
本文解释了怎么对 nginx 和后端服务器组或代理服务器进行加密 http 通信。
内容提纲
- 前提条件
- 获取 SSL 服务端证书
- 获取 SSL 客户端证书
- 配置 nginx
- 配置后端服务器
- 完整示例
前提条件
- nginx 源码或 nginx plus 源码
- 一个代理服务器或一个代理服务器组
- SSL 证书和私钥
获取 SSL 服务端证书
你可以从一个可信证书颁发机构 (CA) 购买一个服务器证书, 或者你可以使用 openssl 库创建一个内部 CA, 并给自己颁发证书。这个服务器端证书和私钥需要部署在后端的每一个服务器上。
获取 SSL 客户端证书
nignx 使用一个 SSL 客户端证书来对后端服务器组来标识自己。这个客户端证书必须是被一个可信 CA 签名的,并且和相匹配的私钥一起部署在 nginx 中。
你还需要在后端服务器上配置好所有的来源 SSL 连接都需要客户端证书,并信任这个 CA 颁发的 nginx 客户端证书。 然后当 nginx 连接后端时,将提供客户端证书,并且后端将会接收这个连接。
配置 nginx
首先,改变相应 URL 到支持 SSL 连接的后端服务器组。在 nginx 的配置文件中,指明 proxy_pass 指令在代理服务器或后端服务器组中使用 "https" 协议:
location /upstream {
proxy_pass https://backend.example.com;
}
增加客户端证书和私钥,用于验证 nginx 和每个后端服务器。使用proxy_ssl_certificate
和 proxy_ssl_certificate_key
指令:
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
指令, 用来验证安全证书:
location /upstream {
...
proxy_ssl_trusted_certificate /etc/nginx/trusted_ca_cert.crt;
proxy_ssl_verify on;
proxy_ssl_verify_depth 2;
...
}
每一个新的 SSL 连接都需要在服务端和客户端进行一个完整的 SSL 握手过程,这非常耗费 CPU 计算资源。为了是 nignx 代理预先协商连接参数,使用一种简略的握手过程,增加proxy_ssl_session_reuse
指令配置:
location /upstream {
...
proxy_ssl_session_reuse on;
...
}
可选的,你也可以配置使用的 SSL 协议和 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_certificat
指令来设定客户端证书的文件路径:
server {
...
ssl_client_certificate /etc/ssl/certs/ca.crt;
ssl_verify_client off;
...
}
完整示例
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 off;
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 off;
location /yourapp {
proxy_pass http://url_to_app.com;
...
}
}
}
在这个示例中, proxy_pass
指令设置使用了 "https" 协议,所以 nginx 转发到后端服务器的流量是安全的。
当一个安全的连接第一次从 nginx 转发到后端服务器,将会实施一次完整的握手过程。proxy_ssl_certificate
指令设置了后端服务器需要的 PEM 格式证书的文件位置。proxy_ssl_certificate_key
指令设置了证书的私钥位置。proxy_ssl_protocols
和proxy_ssl_ciphers
指令控制使用的协议和秘钥算法。
因为proxy_ssl_session_reuse
指令配置,当下一次 nginx 转发一个连接到后端服务器时,会话参数会被重复使用,从而更快的建立安全连接。
proxy_ssl_trusted_certificate
指令设置的那个可信 CA 证书文件是用来验证后端服务器的证书。proxy_ssl_verify_depth
指令指定了证书链检查的深度。proxy_ssl_verify
指令验证证书的有效性。
译注
本文为翻译,英文原文地址:https://www.nginx.com/resources/admin-guide/nginx-https-upstreams/ ,尽量遵循原文,不准确的地方,还请指正,谢谢。
Comments | NOTHING