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

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

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

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

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

Читайте также: Создание сертификата Let’s Encrypt для Nginx в Debian 9

Требования

  • Сервер Debian 9, настроенный по этому мануалу.
  • Предварительно установленный веб-сервер Nginx. Можно установить стек LEMP, одним из компонентов которого является Nginx; чтобы установить только Nginx, выполните инструкции мануала Установка Nginx в Debian 9.

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/nginx/dhparam.pem 4096

Этот процесс займёт несколько минут. Ключи DH будут помещены в /etc/nginx/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. Этот сайт предназначен для распространения простых и надёжных параметров шифрования для популярного программного обеспечения.

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

Остаётся только добавить в них DNS резолвер для upstream запросов. В руководстве для этого используется Google.

Также нужно отключить заголовок Strict-Transport-Security (HSTS). Предварительная загрузка заголовка HSTS обеспечивает повышенную безопасность, но может иметь далеко идущие последствия, если заголовок был включен случайно или некорректно. В этом мануале мы не будем включать эту опцию, но вы можете изменить это позже, если уверены, что понимаете последствия.

Перед тем, как принять решение, узнайте больше о HTTP Strict Transport Security, или HSTS, и, в частности, о функциях предварительной загрузки.

Скопируйте этот сниппет и вставьте его в ssl-params.conf:

ssl_protocols TLSv1.2;
ssl_prefer_server_ciphers on;
ssl_dhparam /etc/nginx/dhparam.pem;
ssl_ciphers ECDHE-RSA-AES256-GCM-SHA512:DHE-RSA-AES256-GCM-SHA512:ECDHE-RSA-AES256-GCM-SHA384:DHE-RSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-SHA384;
ssl_ecdh_curve secp384r1; # Requires nginx >= 1.1.0
ssl_session_timeout  10m;
ssl_session_cache shared:SSL:10m;
ssl_session_tickets off; # Requires nginx >= 1.5.9
ssl_stapling on; # Requires nginx >= 1.3.7
ssl_stapling_verify on; # Requires nginx => 1.3.7
resolver 8.8.8.8 8.8.4.4 valid=300s;
resolver_timeout 5s;
# Disable strict transport security for now. You can uncomment the following
# line if you understand the implications.
# add_header Strict-Transport-Security "max-age=63072000; includeSubDomains; preload";
add_header X-Frame-Options DENY;
add_header X-Content-Type-Options nosniff;
add_header X-XSS-Protection "1; mode=block";

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

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

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

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

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

sudo cp /etc/nginx/sites-available/example.com /etc/nginx/sites-available/example.com.bak

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

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

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

server {
listen 80;
listen [::]:80;
server_name example.com www.example.com;
root /var/www/example.com/html;
index index.html index.htm index.nginx-debian.html;
. . .
}

Ваш файл может быть составлен в другом порядке, и вместо директив root и index у вас может быть location, proxy_pass или другие пользовательские конфигурации. Это нормально, вам нужно только обновить директивы listen и включить сниппеты SSL. Этот блок нужно настроить для поддержки трафика SSL по порту 443, а затем создать новый блок server для обработки трафика по порту 80 и автоматической переадресации трафика на порт 443.

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

В текущем файле обновите директивы listen для поддержки порта 443 и ssl, а затем включите два новых сниппета:

server {
listen 443 ssl;
listen [::]:443 ssl;
include snippets/self-signed.conf;

include snippets/ssl-params.conf;

server_name example.com www.example.com;
root /var/www/example.com/html;
index index.html index.htm index.nginx-debian.html;
. . .
}

Затем добавьте второй блок server в этот файл (после закрывающей фигурной скобки (}) первого блока):

. . .
server {
listen 80;
listen [::]:80;
server_name example.com www.example.com;
return 302 https://$server_name$request_uri;
}

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

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

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

Чтобы просмотреть доступные профили, введите:

sudo ufw app list
Available applications:
. . .
Nginx Full
Nginx HTTP
Nginx HTTPS
. . .

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

sudo ufw status

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

Status: active
To                         Action      From
--                         ------      ----
OpenSSH                    ALLOW       Anywhere
Nginx HTTP                 ALLOW       Anywhere
OpenSSH (v6)               ALLOW       Anywhere (v6)
Nginx HTTP (v6)            ALLOW       Anywhere (v6)

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

sudo ufw allow 'Nginx Full'
sudo ufw delete allow 'Nginx HTTP'

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

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

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

5: Тестирование шифрования

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

https://server_domain_or_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 и кликните по предложенной ссылке.

После этого вы получите доступ к своему сайту. В адресной строке браузера вы увидите «x». В этом случае это означает, что подлинность сертификата невозможно проверить. Но он все еж шифрует ваше соединение.

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

http://server_domain_or_IP

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

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

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

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

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

return 301 https://$server_name$request_uri;

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

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

sudo nginx -t

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

sudo systemctl restart nginx

Заключение

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

Tags: , , , ,