Site icon 8HOST.COM

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

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

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

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

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

Требования

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

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

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

Самой важной строкой является 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/nginx/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, чтобы настроить поддержку ключей Диффи-Хеллмана.

# 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;
add_header Strict-Transport-Security "max-age=63072000; includeSubdomains; preload";
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. Затем добавьте директиву http2, которая отвечает за поддержку HTTP/2. После этого нужно просто выключить в файл созданные ранее сниппеты.

Примечание: В файле может быть только одна директива 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 http2 default_server;
listen [::]:443 ssl http2 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 http2 default_server;
listen [::]:443 ssl http2 default_server;
server_name server_domain_or_IP;
include snippets/self-signed.conf;
include snippets/ssl-params.conf;
. . .

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

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

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

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

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

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

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://домен_или_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-сертификат в надежном центре сертификации, что позволит избежать появления отпугивающих предупреждений.