如何设置Nginx的负载与SSL终止平衡

使用SSL终止,以减少对负载平衡服务器的SSL证书和软件管理开销。本教程使用一个Nginx的负载均衡器和后端灯。

介绍

本文介绍如何在负载平衡器上使用SSL证书设置Nginx负载平衡与SSL终止。 这将减少您的SSL管理开销,因为OpenSSL更新,现在可以从负载均衡器本身管理密钥和证书。

关于SSL终止

Nginx可以配置为负载均衡器,以便在几个后端服务器之间分配传入流量。 SSL终止是在处理SSL加密/解密的负载均衡器上发生的进程,以便负载均衡器和后端服务器之间的流量处于HTTP中。 后端必须通过限制对负载均衡器的IP的访问来加以保护,这将在本文后面解释。

SSL终端图

先决条件

在本教程中,命令必须以root用户或具有sudo权限的用户身份运行。 你可以看到如何设置了在用户个别指导

以下指南可用作参考:

不需要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配置了负载平衡。

启用S​​SL

以下指令添加到里面的虚拟主机文件(/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以使用较早的密码和协议消除漏洞。 本节中显示了各个行,完整的配置文件显示在本教程的最后一部分。

启用S​​SL会话缓存可提高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

深入阅读

要了解更多关于读取负载均衡算法这篇文章