Как настроить балансировку нагрузки Nginx с помощью SSL-терминации

Вступление

В этой статье показано, как настроить балансировку нагрузки Nginx с прекращением SSL только с одним сертификатом SSL на балансировщике нагрузки. Это уменьшит ваши накладные расходы на управление SSL, поскольку обновлениями OpenSSL, ключами и сертификатами теперь можно управлять из самого балансировщика нагрузки.

О прекращении SSL

Nginx можно настроить в качестве балансировщика нагрузки для распределения входящего трафика по нескольким внутренним серверам. Завершение SSL - это процесс, который происходит на балансировщике нагрузки, который обрабатывает шифрование / дешифрование SSL, поэтому трафик между балансировщиком нагрузки и внутренними серверами передается по протоколу HTTP. Бэкэнды должны быть защищены путем ограничения доступа к IP-адресу балансировщика нагрузки, что будет объяснено ниже в этой статье.

SSL Termination Diagram

Предпосылки

В этом руководстве команды должны запускаться как пользователь root или как пользователь с привилегиями sudo. Вы можете увидеть, как настроить это вUsers Tutorial.

Следующие руководства могут быть использованы в качестве ссылки:

Сервер LAMP не требуется, но мы будем использовать его в качестве примера в этом руководстве.

Настроить

В этом уроке используются следующие 3 капли:

Дроплет 1 (внешний интерфейс)

  • Изображение: Ubuntu 14.04

  • Имя хоста: loadbalancer

  • Частный IP: 10.130.227.33

Droplet 2 (бэкэнд)

  • Изображение: Ubuntu 14.04

  • Имя хоста: web1

  • Частный IP: 10.130.227.11

Дроплет 3 (бэкэнд)

  • Изображение: Ubuntu 14.04

  • Имя хоста: web2

  • Частный IP: 10.130.227.22

Domain name - example.com

Для всех этих капель должен быть включенprivate networking.

Обновите и обновите программное обеспечение на всех трех серверах:

apt-get update && apt-get upgrade -y

Reboot each server to apply the upgrades. Это важно, поскольку для обеспечения безопасности 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

Для получения дополнительной информации см.this article.

Генерация ключей и создание SSL-сертификата

В этом разделе вы пройдете через шаги, необходимые для создания сертификата SSL. This article подробно объясняет SSL-сертификаты на Nginx.

Создайте каталог сертификатов 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 для получения действительного сертификата отa certificate authority или создания самоподписанного сертификата с помощью следующей команды.

openssl x509 -req -days 365 -in server.csr -signkey server.key -out server.crt

Как только это будет сделано, этот каталог будет содержать следующие файлы:

  • server.key - The private key

  • ca-certs.pem - A collection of your CA’s root and intermediate certificates. Представлять только в том случае, если вы получили действительный сертификат от CA.

  • server.crt - The SSL certificate for your domain name

Файл виртуального хоста и вышестоящий модуль

Создайте файл виртуальных хостов в каталоге Nginx

nano /etc/nginx/sites-available/example.com

Добавьте модуль upstream, содержащий частные IP-адреса внутренних серверов.

upstream mywebapp1 {
    server 10.130.227.11;
    server 10.130.227.22;
}

Начните серверный блокafter с этой строки. Этот блок содержит имя домена, ссылки на вышестоящие серверы и заголовки, которые следует передать бэкэнду.

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-адрес. Этого можно избежать, настроив веб-серверы на бэкэндах для прослушивания только на частном интерфейсе. Шаги для этого в Apache следующие.

Отредактируйте файлports.conf.

nano /etc/apache2/ports.conf

Найдите следующую строку:

Listen 80

Замените его собственным частным IP-адресомbackend server’s:

Listen 10.130.227.22:80

Сделайте это на всех внутренних серверах и перезапустите Apache.

service apache2 restart

Следующим шагом является ограничение доступа HTTP к частному IP-адресуload balancer’s. Следующее правило брандмауэра достигает этого.

iptables -I INPUT -m state --state NEW -p tcp --dport 80 ! -s 10.130.227.33 -j DROP

Замените пример частным IP-адресом балансировщика нагрузки и выполните это правило на всех внутренних серверах.

Тестирование установки

Создайте файл PHP на всех внутренних серверах (в данном примере web1 и web2). Это для тестирования и может быть удалено после завершения установки.

nano /var/www/html/test.php

На нем должно быть напечатано имя домена, к которому осуществляется доступ, IP-адрес сервера, IP-адрес пользователя и доступ к порту.

Получите доступ к этому файлу несколько раз с помощью браузера или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. Следующие директивы должны быть размещеныafterssl_trusted_certificate. Они обеспечивают совместное кэширование размером20MB со временем жизни кеша10 minutes.

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;

Strict Transport Security указывает всем поддерживающим веб-браузерам использовать только 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 Server Test, и эта установка должна получить оценку A +. Снова запустите проверку скручивания, чтобы проверить, все ли работает правильно.

curl https://example.com/test.php https://example.com/test.php https://example.com/test.php

Дальнейшее чтение

Чтобы узнать больше об алгоритмах балансировки нагрузки, прочтитеthis article.

Related