Создание самоподписанного SSL-сертификата для Nginx в Debian 8

TLS  (Transport Layer Security) и его предшественник SSL (Secure Socket Layers) – это криптографические протоколы, которые используются для защиты передачи данных в Интернете.

Эта технология позволяет защитить обмен данными между сервером и клиентом и предотвратить перехват или несанкционированный доступ к передаваемой информации. Кроме того, эти протоколы предоставляют систему сертификатов, которая помогает пользователям проверить подлинность сайтов, на которые они заходят.

Данное руководство поможет создать самоподписанный SSL-сертификат для веб-сервера Nginx в Debian 8.

Примечание: Самоподписанный сертификат не сможет подтвердить подлинности сервера, так как он не подписан проверенным центром сертификации (ЦС); тем не менее, такой сертификат позволит шифровать взаимодействие с веб-клиентами. Самоподписанный сертификат подходит пользователям, у которых пока что нет доменного имени. При наличии домена рекомендуется обратиться за подписью сертификата к одному из надёжных ЦС. Также можно получить бесплатный доверенный сертификат от сервиса Let’s Encrypt.

 Требования

  • Сервер Debian 8.
  • Пользователь с доступом к sudo (инструкции по созданию такого пользователя – в этой статье).
  • Предварительно установленный веб-сервер Nginx. Чтобы установить стек LEMP, одним из компонентов которого является Nginx, следуйте этому руководству; чтобы установить только Nginx, обратитесь к этому руководству.

1: Создание SSL-сертификата

Для работы TLS/SSL использует комбинацию открытого сертификата и закрытого ключа. Закрытый ключ хранится на сервере и не разглашается. SSL-сертификат используется открыто и доступен всем пользователям, запрашивающим контент.

Чтобы создать самоподписанный сертификат и ключ, запустите команду:

sudo openssl req -x509 -nodes -days 365 -newkey rsa:2048 -keyout /etc/ssl/private/nginx-selfsigned.key -out /etc/ssl/certs/nginx-selfsigned.crt

Команда задаст ряд вопросов. Рассмотрим компоненты команды подробнее:

  • openssl: базовый инструмент командной строки для создания и управления сертификатами, ключами и другими файлами OpenSSL.
  • req: эта подкоманда указывает, что на данном этапе нужно использовать запрос на подпись сертификата X.509 (CSR). X.509 – это стандарт инфраструктуры открытого ключа, которого придерживаются SSL и TLS при управлении ключами и сертификатами. То есть, данная команда позволяет создать новый сертификат X.509.
  • -x509: эта опция вносит поправку в предыдущую субкоманду, сообщая утилите о том, что вместо запроса на подписание сертификата необходимо создать самоподписанный сертификат.
  • -nodes: пропускает опцию защиты сертификата парольной фразой. Нужно, чтобы при запуске сервер Nginx имел возможность читать файл без вмешательства пользователя. Установив пароль, придется вводить его после каждой перезагрузки.
  • -days 365: эта опция устанавливает срок действия сертификата (как видите, в данном случае сертификат действителен в течение года).
  • -newkey rsa:2048: эта опция позволяет одновременно создать новый сертификат и новый ключ. Поскольку ключ, необходимый для подписания сертификата, не был создан ранее, нужно создать его вместе с сертификатом. Данная опция создаст ключ RSA на 2048 бит.
  • -keyout: эта опция сообщает OpenSSL, куда поместить сгенерированный файл ключа.
  • -out: сообщает OpenSSL, куда поместить созданный сертификат.

Как уже было сказано, все эти опции сгенерируют ключ и сертификат. Заполните появившиеся поля данными о сервере, которые будут отображаться в сертификате.

Самой важной строкой является Common Name (введите полное доменное имя  сервера (FQDN) или свое имя). Как правило, в эту строку вносят доменное имя, связанное с сервером. В случае если доменного имени нет, внесите в эту строку IP-адрес сервера. В целом эти поля выглядят примерно так:

Country Name (2 letter code) [AU]:US
State or Province Name (full name) [Some-State]:New York
Locality Name (eg, city) []:New York City
Organization Name (eg, company) [Internet Widgits Pty Ltd]:Bouncy Castles, Inc.
Organizational Unit Name (eg, section) []:Ministry of Water Slides
Common Name (e.g. server FQDN or YOUR name) []:server_IP_address
Email Address []:admin@your_domain.com

Файлы ключа и сертификата будут помещены в каталог /etc/ssl.

При использовании OpenSSL нужно также создать ключи Диффи-Хеллмана, которые нужны для поддержки PFS (совершенной прямой секретности).

Для этого введите:

sudo openssl dhparam -out /etc/ssl/certs/dhparam.pem 2048

Этот процесс займёт несколько минут. Ключи DH будут помещены в /etc/ssl/certs/dhparam.pem.

2: Настройка Nginx для поддержки SSL

Итак, на данном этапе ключ и сертификат созданы и хранятся в каталоге /etc/ssl. Теперь нужно отредактировать настройки Nginx:

  1. Создать сниппет, указывающий место хранения файлов SSL-сертификата и ключа.
  2. Добавить настройки SSL.
  3. Настроить виртуальные хосты (блоки server) для обслуживания запросов SSL и поддержки новых настроек.

Местонахождение ключа и сертификата

Создайте новый сниппет Nginx в каталоге /etc/nginx/snippets.

Рекомендуется указать в названии файла его назначение (к примеру, self-signed.conf):

sudo nano /etc/nginx/snippets/self-signed.conf

В этот файл нужно добавить директиву ssl_certificate, которая будет указывать путь к сертификату, и директиву ssl_certificate_key, которая задаёт путь к соответствующему закрытому ключу.

ssl_certificate /etc/ssl/certs/nginx-selfsigned.crt;
ssl_certificate_key /etc/ssl/private/nginx-selfsigned.key;

Сохраните и закройте файл.

Настройка SSL

Теперь нужно создать другой сниппет, предназначенный для настроек SSL. Он позволит серверу Nginx использовать надёжный механизм шифрования и включит некоторые дополнительные функции безопасности.

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

sudo nano /etc/nginx/snippets/ssl-params.conf

Для безопасной настройки SSL обратимся к рекомендациям Remy van Elst на сайте Cipherli.st. Этот сайт предназначен для распространения простых и надёжных параметров шифрования для популярного программного обеспечения. Больше параметров для Nginx можно найти здесь.

Примечание: Данный список настроек подходит для более новых клиентов. Чтобы получить настройки для других клиентов, перейдите по ссылке Yes, give me a ciphersuite that works with legacy / old software.

Скопируйте все предложенные параметры. Затем нужно добавить в них DNS распознаватель для восходящего канала запросов (в руководстве для этого используется Google) и параметр ssl_dhparam, чтобы настроить поддержку ключей Диффи-Хеллмана.

Также нужно ознакомиться с HTTP Strict Transport Security (HSTS). Особое внимание уделите разделу «preload». Это обеспечит повышенную безопасность, но может иметь далеко идущие последствия при случайном или неправильном включении/выключении. В данном руководстве мы не будем подгружать эти параметры.

# from https://cipherli.st/
# and https://raymii.org/s/tutorials/Strong_SSL_Security_On_nginx.html
ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
ssl_prefer_server_ciphers on;
ssl_ciphers "EECDH+AESGCM:EDH+AESGCM:AES256+EECDH:AES256+EDH";
ssl_ecdh_curve secp384r1;
ssl_session_cache shared:SSL:10m;
ssl_session_tickets off;
ssl_stapling on;
ssl_stapling_verify on;
resolver 8.8.8.8 8.8.4.4 valid=300s;
resolver_timeout 5s;
# Disable preloading HSTS for now.  You can use the commented out header line that includes
# the "preload" directive if you understand the implications.
#add_header Strict-Transport-Security "max-age=63072000; includeSubdomains; preload";
add_header Strict-Transport-Security "max-age=63072000; includeSubdomains";
add_header X-Frame-Options DENY;
add_header X-Content-Type-Options nosniff;
ssl_dhparam /etc/ssl/certs/dhparam.pem;

Примечание: Поскольку сертификат является самоподписанным, SSL stapling не будет использоваться. Nginx выдаст предупреждение, отключит stapling для данного сертификата и продолжит работу.

Сохраните и закройте файл.

Настройка Nginx для поддержки SSL

Примечание: В руководстве предполагается, что вы используете виртуальный хост (блок server) default, который хранится в каталоге /etc/nginx/sites-available. Если вы используете другой файл, пожалуйста, укажите его имя.

Для начала создайте резервную копию файла блока server.

sudo cp /etc/nginx/sites-available/default /etc/nginx/sites-available/default.bak

Затем откройте файл блока server в текстовом редакторе:

sudo nano /etc/nginx/sites-available/default

Файл должен выглядеть примерно так:

server {
listen 80 default_server;
listen [::]:80 default_server;
# SSL configuration
# listen 443 ssl default_server;
# listen [::]:443 ssl default_server;
. . .

Теперь нужно отредактировать настройки, чтобы незашифрованные запросы HTTP были автоматически перенаправлены на HTTPS. Если вы хотите поддерживать и HTTP, и HTTPS, используйте альтернативный вариант настроек, о котором речь пойдёт ниже.

Настройки нужно разделить на два отдельных блока. После двух директив listen будет идти директива server_name, в которой нужно указать доменное имя или IP. После этого нужно настроить переадресацию на второй блок server.

Примечание: Во время настройки рекомендуется использовать временный редирект 302. Убедившись в правильности настроек, можно включить постоянный редирект 301.

server {
listen 80 default_server;
listen [::]:80 default_server;
server_name server_domain_or_IP;
return 302 https://$server_name$request_uri;
}
# SSL configuration
# listen 443 ssl default_server;
# listen [::]:443 ssl default_server;
. . .

Ниже нужно добавить новый блок server и поместить в него оставшиеся настройки. Раскомментируйте директивы listen, которые используют порт 443. После этого нужно просто выключить в файл созданные ранее сниппеты.

Примечание: В файле может быть только одна директива listen, включающая модификатор default_server для комбинаций IP и портов. Если модификатор default_server встречается в нескольких блоках server, оставьте его только в одном блоке, а из остальных удалите.

server {
listen 80 default_server;
listen [::]:80 default_server;
server_name server_domain_or_IP;
return 302 https://$server_name$request_uri;
}
server {
# SSL configuration
listen 443 ssl default_server;
listen [::]:443 ssl default_server;
include snippets/self-signed.conf;
include snippets/ssl-params.conf;
. . .

Сохраните и закройте файл.

Альтернативный вариант настройки: поддержка HTTP и HTTPS

Чтобы сайт поддерживал и HTTP, и HTTPS, используйте описанные в этом разделе настройки. Имейте в виду: такой вариант настройки использовать не рекомендуется.

В целом нужно только объединить два отдельных блока server в один блок и удалить редирект.

server {
listen 80 default_server;
listen [::]:80 default_server;
listen 443 ssl default_server;
listen [::]:443 ssl default_server;
server_name server_domain_or_IP;
include snippets/self-signed.conf;
include snippets/ssl-params.conf;
. . .

Сохраните и закройте файл.

3: Настройка брандмауэра

Если вы включили брандмауэр ufw (согласно руководству по начальной настройке), на данном этапе его нужно настроить для поддержки трафика SSL.

Брандмауэр UFW

Чтобы просмотреть текущие настройки, введите:

sudo ufw status

Если разрешен только трафик HTTP, они будут иметь такой вид:

Status: active
To                         Action      From
--                         ------      ----
SSH                        ALLOW       Anywhere
WWW                        ALLOW       Anywhere
SSH (v6)                   ALLOW       Anywhere (v6)
WWW (v6)                   ALLOW       Anywhere (v6)

Чтобы добавить поддержку трафика HTTPS, нужно настроить профиль WWW Full и отключить профиль WWW.

sudo ufw allow 'WWW Full'
sudo ufw delete allow 'WWW'

После этого настройки брандмауэра должны выглядеть так:

sudo ufw status
Status: active
To                         Action      From
--                         ------      ----
SSH                        ALLOW       Anywhere
WWW Full                   ALLOW       Anywhere
SSH (v6)                   ALLOW       Anywhere (v6)
WWW Full (v6)              ALLOW       Anywhere (v6)

Теперь сервер может принимать запросы HTTPS.

IPTables

Чтобы просмотреть текущие правила iptables, введите:

sudo iptables -S

На экране появится список правил. Он будет выглядеть примерно так:

-P INPUT DROP
-P FORWARD ACCEPT
-P OUTPUT ACCEPT
-A INPUT -i lo -j ACCEPT
-A INPUT -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT
-A INPUT -p tcp -m tcp --dport 22 -j ACCEPT
-A INPUT -p tcp -m tcp --dport 80 -j ACCEPT

Команда, которая разблокирует трафик SSL, во многом зависит от текущего набора правил. В большинстве случаев сработает такая команда:

sudo iptables -I INPUT -p tcp -m tcp --dport 443 -j ACCEPT

Чтобы убедиться, что список правил обновился, введите:

sudo iptables -S
-P INPUT DROP
-P FORWARD ACCEPT
-P OUTPUT ACCEPT
-A INPUT -p tcp -m tcp --dport 443 -j ACCEPT
-A INPUT -i lo -j ACCEPT
-A INPUT -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT
-A INPUT -p tcp -m tcp --dport 22 -j ACCEPT
-A INPUT -p tcp -m tcp --dport 80 -j ACCEPT

Если правила iptables загружаются автоматически, вам нужно сохранить новое правило.

4: Обновление настроек Nginx

Итак, теперь настройки веб-сервера и брандмауэра откорректированы. Перезапустите Nginx, чтобы изменения вступили в силу.

Сначала нужно проверить синтаксис на наличие ошибок.

sudo nginx -t

Если ошибок не обнаружено, команда вернёт:

nginx: [warn] "ssl_stapling" ignored, issuer certificate not found
nginx: the configuration file /etc/nginx/nginx.conf syntax is ok
nginx: configuration file /etc/nginx/nginx.conf test is successful

Обратите внимание на предупреждение в начале. Как говорилось ранее, веб-сервер будет возвращать предупреждение в случае использования самоподписанного сертификата. Соединения всё рано шифруются правильно.

Если в синтаксисе обнаружены ошибки, исправьте их. Затем перезапустите веб-сервер:

sudo systemctl restart nginx

Теперь сервер поддерживает HTTPS.

5: Тестирование настроек

Теперь нужно убедиться, что трафик между сервером и клиентом шифруется. Откройте в браузере следующую ссылку:

https://домен_или_IP_сервера

Поскольку сертификат был подписан самостоятельно, браузер сообщит о его ненадёжности:

Your connection is not private
Attackers might be trying to steal your information
(for example, passwords,messages, or credit cards). NET::ERR_CERT_AUTHORITY_INVALID

Это нормальное поведение программы в подобной ситуации, поскольку браузер не может проверить подлинность хоста. Однако в данном случае нужно только шифровать трафик, с чем самоподписанный сертификат вполне справляется, потому предупреждение браузера можно пропустить. Для этого нажмите кнопку ADVANCED и кликните по предложенной ссылке.

После этого вы получите доступ к своему сайту.

Если вы настроили два блока server для переадресации трафика HTTP на HTTPS, проверьте, работает ли переадресация:

http://server_domain_or_IP

6: Постоянный редирект

Если все настройки сервера работают должным образом, настройте постоянный редирект вместо временного.

Откройте файл блока server:

sudo nano /etc/nginx/sites-available/default

Найдите в нём return 302 и замените значение строки на return 301.

server {
listen 80 default_server;
listen [::]:80 default_server;
server_name server_domain_or_IP;
return 301 https://$server_name$request_uri;
}
. . .

Сохраните и закройте файл.

Проверьте синтаксис на ошибки:

sudo nginx -t

Если ошибок нет, перезапустите Nginx:

sudo systemctl restart nginx

Заключение

Теперь сервер Nginx может шифровать передаваемые данные, что защитит взаимодействие сервера с клиентами и предотвратит перехват трафика злоумышленниками.

Конечно, при разработке сайта рекомендуется подписать SSL-сертификат в надежном центре сертификации, что позволит избежать появления отпугивающих предупреждений.

Tags: , , ,

Добавить комментарий