Создание самоподписанного SSL-сертификата для Nginx в Ubuntu 18.04
Ubuntu | Комментировать запись
TLS (Transport Layer Security) и его предшественник SSL (Secure Socket Layers) – это криптографические протоколы, которые используются для защиты передачи данных в Интернете.
Эта технология позволяет защитить обмен данными между сервером и клиентом и предотвратить перехват или несанкционированный доступ к передаваемой информации. Кроме того, эти протоколы предоставляют систему сертификатов, которая помогает пользователям проверить подлинность сайтов, на которые они заходят.
Данный мануал поможет создать самоподписанный SSL-сертификат для веб-сервера Nginx в Ubuntu 18.04.
Примечание: Самоподписанный сертификат не сможет подтвердить подлинности сервера, так как он не подписан проверенным центром сертификации (ЦС); тем не менее, такой сертификат позволит шифровать взаимодействие с веб-клиентами. Самоподписанный сертификат подходит пользователям, у которых пока что нет доменного имени. При наличии домена рекомендуется обратиться за подписью сертификата к одному из надёжных ЦС. Также можно получить бесплатный доверенный сертификат от сервиса Let’s Encrypt.
Читайте также: Создание сертификата Let’s Encrypt для Nginx в Ubuntu 18.04
Требования
- Сервер Ubuntu 18.04, настроенный по этому мануалу.
- Предварительно установленный веб-сервер Nginx. Можно установить стек LEMP, одним из компонентов которого является Nginx (для этого следуйте руководству Установка стека LEMP в Ubuntu 18.04); чтобы установить только Nginx, выполните инструкции мануала Установка Nginx в Ubuntu 18.04.
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:
- Создать сниппет, указывающий место хранения файлов 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. Этот сайт предназначен для распространения простых и надёжных параметров шифрования для популярного программного обеспечения.
Примечание: Данный список настроек подходит для более новых клиентов. Чтобы получить настройки для других клиентов, перейдите по ссылке 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) default, который хранится в каталоге /etc/nginx/sites-available. Если вы используете другой файл, пожалуйста, укажите его имя.
Для начала создайте резервную копию файла блока server.
sudo cp /etc/nginx/sites-available/example.com /etc/nginx/sites-available/example.com.bak
Затем откройте файл блока server в текстовом редакторе:
sudo nano /etc/nginx/sites-available/default
Файл должен выглядеть примерно так:
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
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://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 и кликните по предложенной ссылке.
После этого вы получите доступ к своему сайту.
Если вы настроили два блока 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 может шифровать передаваемые данные, что защитит взаимодействие сервера с клиентами и предотвратит перехват трафика злоумышленниками.
Конечно, при разработке сайта рекомендуется подписать SSL-сертификат в надежном центре сертификации, что позволит избежать появления отпугивающих предупреждений.
Tags: NGINX, SSL, Ubuntu 18.04