Создание самоподписанного SSL-сертификата для Nginx в Debian 8
Debian, LEMP Stack | Комментировать запись
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:
- Создать сниппет, указывающий место хранения файлов SSL-сертификата и ключа.
- Добавить настройки SSL.
- Настроить виртуальные хосты (блоки 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: Debian 8, NGINX, SSL, TLS