介绍
本文介绍如何在负载平衡器上使用SSL证书设置Nginx负载平衡与SSL终止。 这将减少您的SSL管理开销,因为OpenSSL更新,现在可以从负载均衡器本身管理密钥和证书。
关于SSL终止
Nginx可以配置为负载均衡器,以便在几个后端服务器之间分配传入流量。 SSL终止是在处理SSL加密/解密的负载均衡器上发生的进程,以便负载均衡器和后端服务器之间的流量处于HTTP中。 后端必须通过限制对负载均衡器的IP的访问来加以保护,这将在本文后面解释。
先决条件
在本教程中,命令必须以root用户或具有sudo权限的用户身份运行。 你可以看到如何设置了在用户个别指导 。
以下指南可用作参考:
- 在Ubuntu 14.04上设置LAMP服务器
- 在Nginx上设置SSL
- 在Nginx上设置负载平衡
不需要LAMP服务器,但我们将在本教程中使用它作为示例。
建立
本教程使用以下3Droplet:
Droplet1(前端)
- 图片:Ubuntu 14.04
- 主机名:loadbalancer
- 私人IP:10.130.227.33
Droplet2(后端)
- 图片:Ubuntu 14.04
- 主机名:web1
- 私人IP:10.130.227.11
Droplet3(后端)
- 图片: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
以下指令添加到里面的虚拟主机文件(/etc/nginx/sites-available/example.com) server {}块。 这些行将在下一个示例中的上下文中显示。
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自签名证书的设置,使卷曲忽略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
需要注意的是服务器地址在每个请求的变化,这表明不同的服务器响应每个请求。
加固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;
严格传输安全指示所有支持Web浏览器仅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