介绍
本文向您展示了如何使用负载均衡器上的一个 SSL 证书设置带有 SSL 终止的 Nginx 负载均衡。 这将减少您的 SSL 管理开销,因为现在可以从负载均衡器本身管理 OpenSSL 更新以及密钥和证书。
关于 SSL 终止
Nginx 可以配置为负载均衡器,以在多个后端服务器之间分配传入流量。 SSL 终止是发生在负载均衡器上的过程,它处理 SSL 加密/解密,以便负载均衡器和后端服务器之间的流量在 HTTP 中。 必须通过限制对负载均衡器 IP 的访问来保护后端,本文稍后将对此进行解释。
先决条件
在本教程中,命令必须以 root 用户或具有 sudo 权限的用户身份运行。 您可以在 用户教程 中查看如何设置它。
以下指南可作为参考:
LAMP 服务器不是必需的,但我们将在本教程中使用它作为示例。
设置
本教程使用以下 3 个液滴:
液滴 1(前端)
- 图片:Ubuntu 14.04
- 主机名:负载均衡器
- 私有 IP:10.130.227.33
液滴 2(后端)
- 图片:Ubuntu 14.04
- 主机名:web1
- 私有 IP:10.130.227.11
Droplet 3(后端)
- 图片:Ubuntu 14.04
- 主机名:web2
- 私有 IP:10.130.227.22
域名 - example.com
所有这些 Droplet 都必须启用 私有网络 。
更新和升级所有三台服务器上的软件:
apt-get update && apt-get upgrade -y
重新启动每个服务器以应用升级。 这很重要,因为 OpenSSL 需要使用最新版本才能确保安全。
我们将为域名设置一个新的 Nginx 虚拟主机,其中上游模块负载平衡后端。
在设置 Nginx 负载平衡之前,您应该在您的 VPS 上安装 Nginx。 您可以使用 apt-get
快速安装它:
apt-get install nginx
在两个后端服务器上,更新您的存储库并安装 Apache:
apt-get install apache2
在两个后端服务器上安装 PHP:
apt-get install php5 libapache2-mod-php5 php5-mcrypt
有关详细信息,请参阅这篇文章。
生成密钥并创建 SSL 证书
在本节中,您将完成创建 SSL 证书所需的步骤。 这篇文章详细讲解了Nginx上的SSL证书。
创建 SSL 证书目录并切换到它。
mkdir -p /etc/nginx/ssl/example.com cd /etc/nginx/ssl/example.com
创建私钥:
openssl genrsa -des3 -out server.key 2048
删除其密码:
openssl rsa -in server.key -out server.key
创建 CSR(证书签名请求):
openssl req -new -key server.key -out server.csr
使用此 CSR 从 证书颁发机构 获取有效证书,或使用以下命令生成自签名证书。
openssl x509 -req -days 365 -in server.csr -signkey server.key -out server.crt
完成此操作后,此目录将包含以下文件:
- server.key - 私钥
- ca-certs.pem - CA 的根证书和中间证书的集合。 仅当您从 CA 获得有效证书时才存在。
- server.crt - 您的域名的 SSL 证书
虚拟主机文件和上游模块
在 Nginx 目录中创建一个虚拟主机文件
nano /etc/nginx/sites-available/example.com
添加包含后端服务器私有 IP 地址的上游模块
upstream mywebapp1 { server 10.130.227.11; server 10.130.227.22; }
在 这一行之后开始服务器块。 此块包含域名、对上游服务器的引用以及应传递给后端的标头。
server { listen 80; server_name example.com www.example.com; location / { proxy_pass http://mywebapp1; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Forwarded-Proto $scheme; } }
proxy_set_header
指令用于将有关请求的重要信息传递给上游服务器。
保存此文件并创建指向 sites-enabled
目录的符号链接。
ln -s /etc/nginx/sites-available/example.com /etc/nginx/sites-enabled/example.com
执行配置测试以检查错误。
service nginx configtest
如果没有报错,重新加载nginx服务。
service nginx reload
现在已经为 HTTP 配置了负载平衡。
启用 SSL
将以下指令添加到 server {}
块内的虚拟主机文件 (/etc/nginx/sites-available/example.com)。 这些行将在下一个示例的上下文中显示。
listen 443 ssl; ssl on; ssl_certificate /etc/nginx/ssl/example.com/server.crt; ssl_certificate_key /etc/nginx/ssl/example.com/server.key; ssl_trusted_certificate /etc/nginx/ssl/example.com/ca-certs.pem;
如果您使用自签名证书,请忽略 ssl_trusted_certificate
指令。 现在 server
块应该如下所示:
server { listen 80; listen 443 ssl; server_name example.com www.example.com; ssl on; ssl_certificate /etc/nginx/ssl/example.com/server.crt; ssl_certificate_key /etc/nginx/ssl/example.com/server.key; ssl_trusted_certificate /etc/nginx/ssl/example.com/ca-certs.pem; location / { proxy_pass http://mywebapp1; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Forwarded-Proto $scheme; } }
检查配置错误并重新加载 Nginx 服务。
service nginx configtest && service nginx reload
保护后端服务器
目前,任何知道其公共 IP 地址的人都可以直接访问托管在后端服务器上的网站。 这可以通过将后端的 Web 服务器配置为仅在私有接口上侦听来防止。 在 Apache 中执行此操作的步骤如下。
编辑 ports.conf
文件。
nano /etc/apache2/ports.conf
找到以下行:
Listen 80
将其替换为 后端服务器的 自己的私有 IP 地址:
Listen 10.130.227.22:80
在所有后端服务器上执行此操作并重新启动 Apache。
service apache2 restart
下一步是限制对 负载平衡器的 私有 IP 的 HTTP 访问。 以下防火墙规则实现了这一点。
iptables -I INPUT -m state --state NEW -p tcp --dport 80 ! -s 10.130.227.33 -j DROP
将示例替换为负载均衡器的私有 IP 地址,并在所有后端服务器上执行此规则。
测试设置
在所有后端服务器(本例中为 web1 和 web2)上创建一个 PHP 文件。 这是为了测试,一旦设置完成就可以删除。
nano /var/www/html/test.php
它应该打印访问的域名,服务器的IP地址,用户的IP地址和访问的端口。
<?php header( 'Content-Type: text/plain' ); echo 'Host: ' . $_SERVER['HTTP_HOST'] . "\n"; echo 'Remote Address: ' . $_SERVER['REMOTE_ADDR'] . "\n"; echo 'X-Forwarded-For: ' . $_SERVER['HTTP_X_FORWARDED_FOR'] . "\n"; echo 'X-Forwarded-Proto: ' . $_SERVER['HTTP_X_FORWARDED_PROTO'] . "\n"; echo 'Server Address: ' . $_SERVER['SERVER_ADDR'] . "\n"; echo 'Server Port: ' . $_SERVER['SERVER_PORT'] . "\n\n"; ?>
使用浏览器或使用 curl
多次访问此文件。 在自签名证书设置上使用 curl -k
以使 curl 忽略 SSL 错误。
curl https://example.com/test.php https://example.com/test.php https://example.com/test.php
输出将类似于以下内容。
Host: example.com Remote Address: 10.130.245.116 X-Forwarded-For: 117.193.105.174 X-Forwarded-Proto: https Server Address: 10.130.227.11 Server Port: 80 Host: example.com Remote Address: 10.130.245.116 X-Forwarded-For: 117.193.105.174 X-Forwarded-Proto: https Server Address: 10.130.227.22 Server Port: 80 Host: example.com Remote Address: 10.130.245.116 X-Forwarded-For: 117.193.105.174 X-Forwarded-Proto: https Server Address: 10.130.227.11 Server Port: 80
请注意,Server Address 在每次请求时都会发生变化,表明不同的服务器正在响应每个请求。
强化 SSL 配置
本节说明根据最佳实践配置 SSL 以消除旧密码和协议的漏洞。 本节显示了各个行,本教程的最后一节显示了完整的配置文件。
启用 SSL 会话缓存可提高 HTTPS 网站的性能。 以下指令必须放在 之后 ssl_trusted_certificate
。 它们启用大小为 20MB 的共享缓存,缓存寿命为 10 分钟 。
ssl_session_cache shared:SSL:20m; ssl_session_timeout 10m;
指定要在 SSL 连接中使用的协议和密码。 在这里,我们省略了 SSLv2 并禁用了 MD5 和 DSS 等不安全密码。
ssl_prefer_server_ciphers on; ssl_protocols TLSv1 TLSv1.1 TLSv1.2; ssl_ciphers ECDH+AESGCM:DH+AESGCM:ECDH+AES256:DH+AES256:ECDH+AES128:DH+AES:ECDH+3DES:DH+3DES:RSA+AESGCM:RSA+AES:RSA+3DES:!aNULL:!MD5:!DSS;
严格传输安全指示所有支持的网络浏览器只使用HTTPS。 使用 add_header
指令启用它。
add_header Strict-Transport-Security "max-age=31536000";
检查配置错误并重新加载 Nginx 服务。
service nginx configtest && service nginx reload
完成配置
配置和加固 SSL 终止后,完整的配置文件将如下所示:
/etc/nginx/sites-available/example.com
upstream mywebapp1 { server 10.130.227.11; server 10.130.227.22; } server { listen 80; listen 443 ssl; server_name example.com www.emxaple.com; ssl on; ssl_certificate /etc/nginx/ssl/example.com/server.crt; ssl_certificate_key /etc/nginx/ssl/example.com/server.key; ssl_trusted_certificate /etc/nginx/ssl/example.com/ca-certs.pem; ssl_session_cache shared:SSL:20m; ssl_session_timeout 10m; ssl_prefer_server_ciphers on; ssl_protocols TLSv1 TLSv1.1 TLSv1.2; ssl_ciphers ECDH+AESGCM:DH+AESGCM:ECDH+AES256:DH+AES256:ECDH+AES128:DH+AES:ECDH+3DES:DH+3DES:RSA+AESGCM:RSA+AES:RSA+3DES:!aNULL:!MD5:!DSS; add_header Strict-Transport-Security "max-age=31536000"; location / { proxy_pass http://mywebapp1; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Forwarded-Proto $scheme; } }
进行 SSL 服务器测试,此设置应获得 A+ 级。 再次运行 curl 测试以检查一切是否正常。
curl https://example.com/test.php https://example.com/test.php https://example.com/test.php
延伸阅读
要了解有关负载平衡算法的更多信息,请阅读 这篇文章 。