Создание самоподписанного SSL-сертификата для Nginx в Ubuntu 16.04
Мы покажем вам как создать сертификат, а также настроить веб-сервер Nginx для поддержки SSL
SSL (Secure Socket Layers) представляет собой криптографический протокол для защиты, передаваемых в интернете между клиентом и сервером. Протокол делает невозможным перехват данных злоумышленниками. SSL также помогают пользователям проверять подлинность посещаемые ресурсов. В этой статье мы покажем вам как можно сделать для веб-сервера Nginx на Ubuntu 16.04 самоподписанный сертификат.
Имейте ввиду, что такой SSL не способен подтвердить подлинность сервера из-за отсутствия подтверждения от специального сертификационного центра. Сертификат способен лишь обеспечивать шифрование канала передачи данных. Его можно применять пользователям без доменного имени. Если домен у вас уже есть, то SSL придется заверить в центре сертификации. Вы также можете получить от сервиса Let’s Encrypt бесплатный доверенный сертификат.
Нам потребуется:
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
На экране вы увидите несколько вопросов. Из компонентов команды можно выделить:
С помощью вышеописанных опций вы сможете сгенерировать одновременно сертификат с ключом. Вам нужно лишь указать данные сервера, отображающиеся в SSL.
Строка common name очень важна. В нее нужно написать свое имя или полное доменное имя вашего сервера. Простыми словами: она нужна для связи с сервером доменного имени. Если его нет, укажите IР сервера. Поля будут выглядеть как-то так:
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
Подождите несколько минут пока сгенерируются ключи. Они будут размещены в каталоге /etc/ssl/certs/dhparam.pem.
Созданные нами ключи хранятся в папке: /etc/ssl. Теперь нам нужно будет внести правки в настройки веб-сервера Nginx:
1) В первую очередь – создать сниппет, показывающий папку, в которой хранятся SSL и ключ. Новый сниппет для Nginx создаем в папке /etc/nginx/snippets. Мы советуем вам отразить его назначение в названии. Наберите в консоли:
sudo nano /etc/nginx/snippets/self-signed.conf
В файл добавим правило ssl_sertificate, указывающее путь к нашему сертификату. Кроме того, нам потребуется директива ssl_sertificate_key для пути к ключу:
ssl_certificate /etc/ssl/certs/nginx-selfsigned.crt;
ssl_certificate_key /etc/ssl/private/nginx-selfsigned.key;
2) Теперь потребуется добавить настройки сертификата с помощью еще одного сниппета. Это позволит нам получить надежный механизм шифрования с помощью дополнительных возможностей безопасности. Заданные параметры получится применять в будущих конфигурациях веб-сервера Nginx. Дайте файлу какое-нибудь общее имя:
sudo nano /etc/nginx/snippets/ssl-params.conf
Настроим DNS-распознаватель для запросов с восходящего канала, а также добавим 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 для этого SSL и продолжит работать. Теперь сохраним изменения и закроем файл.
3) И последнее: настроить блоки server, чтобы они могли обслуживать запросы SSL и поддерживать новые настройки. В нашей статье рассматривается случай применения виртуального хоста default (блок server). Он хранится в папке /etc/nginx/sites-available. Если захотите пользоваться другим файлом, нужно указать его имя. Создадим резервную копию файла блока server с помощью:
sudo cp /etc/nginx/sites-available/default /etc/nginx/sites-available/default.bak
Теперь этот блок откроем в редакторе:
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. Если же вам требуется поддержка двух протоколов, то мы такой случай рассмотрим позже. Делим настройки на два отдельных блока. Правило server_name будет идти после двух директив listen. В нем требуется указать 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, для комбинаций портов и IP-адресов, включающая модификатор default_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, то объедините два блока 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;
. . .
Эти изменения нужно сохранить. После этого закрывайте файл.
Мы будем настраивать брандмауэр 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 HTTP и настроим Nginx Full. Наберите в командной строке:
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)
После корректировки настроек веб-сервера и брандмауэра нужно перезапустить 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
Предупреждение появляется в первой строке, поскольку мы используем самоподписанный сертификат. Не обращайте внимания, соединение все равно будет корректно шифроваться. В случае обнаружения ошибок их необходимо исправить. После этого потребуется перезапуск веб-сервера Nginx с помощью:
sudo systemctl restart nginx
Нам нужно убедиться, что трафик между клиентом и сервером шифруется. Это можно сделать, открыв в браузере ссылку:
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», а также кликнув по показанной ссылке. Это даст вам доступ к вашему сайту. Нам нужно будет также проверить, работает ли переадресация трафика с HTTP на HTTPS, если ранее настраивали два блока server:
http://server_domain_or_IP
Если работа всех настроек сервера правильная, можно вместо временного редиректа ставить постоянный. Для этого откроем файл блока server:
sudo nano /etc/nginx/sites-available/default
В нем нужно найти return 302 и заменить значение на 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 в сертификационном центре.
Опубликовано: Июнь 19, 2017