Поиск по сайту:

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


Введение

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

О терминации SSL

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

Предпосылки

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

В качестве справочных материалов можно использовать следующие руководства:

  • Настройка сервера LAMP в Ubuntu 14.04
  • Настройка SSL на Nginx
  • Настройка балансировки нагрузки в Nginx

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

Настраивать

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

Капля 1 (интерфейс)

  • Изображение: Ubuntu 14.04
  • Имя хоста: loadbalancer
  • Частный IP-адрес: 10.130.227.33

Капля 2 (Бэкенд)

  • Изображение: Ubuntu 14.04
  • Имя хоста: web1
  • Частный IP-адрес: 10.130.227.11

Капля 3 (Бэкенд)

  • Изображение: Ubuntu 14.04
  • Имя хоста: web2
  • Частный IP-адрес: 10.130.227.22

Доменное имя — example.com

Все эти капли должны иметь включенную частную сеть.

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

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

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

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

  • server.key — закрытый ключ
  • ca-certs.pem — набор корневых и промежуточных сертификатов ЦС. Присутствует только в том случае, если вы получили действительный сертификат от ЦС.
  • 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-адрес. Этого можно избежать, настроив веб-серверы на внутренних серверах так, чтобы они прослушивали только частный интерфейс. Шаги, чтобы сделать это в Apache, следующие.

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

nano /etc/apache2/ports.conf

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

Listen 80

Замените его на собственный частный IP-адрес внутреннего сервера:

Listen 10.130.227.22:80

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

service apache2 restart

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

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-адрес пользователя и доступный порт.

<?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

Обратите внимание, что адрес сервера меняется при каждом запросе, указывая на то, что на каждый запрос отвечает другой сервер.

Усиление SSL-конфигурации

В этом разделе объясняется, как настроить SSL в соответствии с рекомендациями по устранению уязвимостей старых шифров и протоколов. В этом разделе показаны отдельные строки, а полный файл конфигурации показан в последнем разделе этого руководства.

Включение кэширования сеанса SSL повышает производительность веб-сайтов HTTPS. Следующие директивы должны быть размещены после ssl_trusted_certificate. Они обеспечивают совместное кэширование размером 20 МБ со временем жизни кэша 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

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

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