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

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

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

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

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

Требования

  • Сервер CentOS 7.
  • Пользователь с доступом к sudo (инструкции по созданию такого пользователя – в этой статье).

1: Установка Nginx и настройка брандмауэра

Сначала нужно установить веб-сервер Nginx.

Пакета Nginx нет в официальных репозиториях CentOS. Его можно найти в дополнительном репозитории EPEL (Extra Packages for Enterprise Linux). Добавьте EPEL на сервер, чтобы загрузить пакет веб-сервера.

sudo yum install epel-release

Чтобы установить Nginx, введите:

sudo systemctl start nginx

Убедитесь, что сервис запущен:

systemctl status nginx
nginx.service - The nginx HTTP and reverse proxy server
Loaded: loaded (/usr/lib/systemd/system/nginx.service; disabled; vendor preset: disabled)
Active: active (running) since Fri 2017-01-06 17:27:50 UTC; 28s ago
. . .
Jan 06 17:27:50 centos-512mb-nyc3-01 systemd[1]: Started The nginx HTTP and reverse proxy server.

Также нужно включить Nginx как сервис:

sudo systemctl enable nginx
Created symlink from /etc/systemd/system/multi-user.target.wants/nginx.service to /usr/lib/systemd/system/nginx.service.

Теперь нужно разблокировать в брандмауэре порты 80 и 443.

Примечание: Если на вашем сервере не настроен брандмауэр, вы можете приступать к следующему разделу.

Если вы используете firewalld, введите следующие команды, чтобы открыть порты:

sudo firewall-cmd --add-service=http
sudo firewall-cmd --add-service=https
sudo firewall-cmd --runtime-to-permanent

В iptables команды зависят от текущего набора правил. Если вы используете правила по умолчанию, должен сработать такой набор:

sudo iptables -I INPUT -p tcp -m tcp --dport 80 -j ACCEPT
sudo iptables -I INPUT -p tcp -m tcp --dport 443 -j ACCEPT

2: Создание SSL-сертификата

Для работы TLS/SSL использует комбинацию открытого сертификата и закрытого ключа. Закрытый ключ хранится на сервере и не разглашается. SSL-сертификат используется открыто, он доступен всем пользователям, запрашивающим контент.

Каталог /etc/ssl/certs, предназначенный для хранения сертификатов, существует на сервере по умолчанию. Создайте каталог для ключей, /etc/ssl/private, и ограничьте доступ к нему.

sudo mkdir /etc/ssl/private
sudo chmod 700 /etc/ssl/private

Чтобы создать самоподписанный сертификат и ключ, запустите команду:

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: эта опция позволяет одновременно создать новый сертификат и новый ключ. Поскольку ключ, необходимый для подписания сертификата, не был создан ранее, нужно создать его вместе с сертификатом. Данная опция создаст 2048-битный ключ RSA.
  • -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.

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

Итак, на данном этапе ключ и сертификат готовы. Теперь нужно отредактировать настройки Nginx.

В системе CentOS настройки Nginx по умолчанию плохо структурированы. Блок настроек HTTP находится в главном конфигурационном файле, а дополнительные настройки веб-сервер Nginx будет искать в каталоге /etc/nginx/conf.d, в файлах с расширением .conf.

Создайте в этом каталоге новый файл виртуального хоста (блока server) для обслуживания сертификата. Также можно настроить виртуальный хост по умолчанию для переадресации HTTP-запросов на HTTPS.

Виртуальный хост для TLS/SSL

Создайте и откройте файл ssl.conf в каталоге /etc/nginx/conf.d.

sudo vi /etc/nginx/conf.d/ssl.conf

Добавьте в файл блок server. По умолчанию соединения TLS/SSL используют порт 443. Укажите этот номер в директиве listen. В server_name укажите доменное имя или IP-адрес сервера (значение директивы должно совпадать с тем, что вы указали ранее в Common Name). Затем добавьте строки ssl_certificate, ssl_certificate_key и ssl_dhparam и укажите в них пути к соответствующим файлам SSL.

server {
listen 443 http2 ssl;
listen [::]:443 http2 ssl;
server_name server_IP_address;
ssl_certificate /etc/ssl/certs/nginx-selfsigned.crt;
ssl_certificate_key /etc/ssl/private/nginx-selfsigned.key;
ssl_dhparam /etc/ssl/certs/dhparam.pem;
}

Далее нужно определить дополнительные параметры SSL, которые обеспечивают безопасность сайта. Для этого обратимся к рекомендациям Remy van Elst на сайте Cipherli.st. Этот сайт предназначен для распространения простых и надёжных параметров шифрования для популярного программного обеспечения. Больше параметров для Nginx можно найти здесь.

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

Некоторые параметры можно откорректировать. Также нужно добавить DNS распознаватель для восходящего канала запросов (в руководстве для этого используется Google).

Также нужно ознакомиться с HTTP Strict Transport Security (HSTS). Особое внимание уделите функции«preload». Это обеспечит повышенную безопасность, но может иметь далеко идущие последствия при случайном или неправильном включении/выключении. В данном руководстве мы не будем подгружать эти параметры.

server {
listen 443 http2 ssl;
listen [::]:443 http2 ssl;
server_name server_IP_address;
ssl_certificate /etc/ssl/certs/nginx-selfsigned.crt;
ssl_certificate_key /etc/ssl/private/nginx-selfsigned.key;
ssl_dhparam /etc/ssl/certs/dhparam.pem;
########################################################################
# 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;
##################################
# END https://cipherli.st/ BLOCK #
##################################
}

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

Теперь добавьте остальные настройки Nginx. Список дополнительных настроек зависит от потребностей сайта. Просто скопируйте из блока location по умолчанию директивы, которые настраивают document root и включают поддержку страниц ошибок.

server {
listen 443 http2 ssl;
listen [::]:443 http2 ssl;
server_name server_IP_address;
ssl_certificate /etc/ssl/certs/nginx-selfsigned.crt;
ssl_certificate_key /etc/ssl/private/nginx-selfsigned.key;
ssl_dhparam /etc/ssl/certs/dhparam.pem;
########################################################################
# from https://cipherli.st/                                            #
# and https://raymii.org/s/tutorials/Strong_SSL_Security_On_nginx.html #
########################################################################
. . .
##################################
# END https://cipherli.st/ BLOCK #
##################################
root /usr/share/nginx/html;
location / {
}
error_page 404 /404.html;
location = /404.html {
}
error_page 500 502 503 504 /50x.html;
location = /50x.html {
}
}

Сохраните и закройте файл. Теперь Nginx будет использовать SSL-сертификат для шифрования трафика. В настройках указаны только самые безопасные протоколы и шифры.

Примечание: Приведённый выше пример конфигурации будет обслуживать страницу Nginx по умолчанию.

Настройка редиректа с HTTP на HTTPS (опционально)

На данный момент Nginx поддерживает шифрованные (порт 443) и нешифрованные соединения (порт 80). То есть, сайт поддерживает шифрование, но использует его не во всех случаях. Однако из соображений безопасности рекомендуется использовать шифрование на постоянной основе. Особенно это важно при передаче конфиденциальных данных.

К счастью, Nginx позволяет добавить в server-блок порта 80 по умолчанию специальные директивы редиректа. Для этого нужно просто добавить файл в каталог /etc/nginx/default.d.

Создайте новый файл ssl-redirect.conf и откройте его.

sudo vi /etc/nginx/default.d/ssl-redirect.conf

Добавьте в него строку:

return 301 https://$host$request_uri/;

Сохраните и закройте файл. Теперь все запросы, направленные на порт 80, будут переадресованы на порт 443, который поддерживает шифрование.

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

После этого вы получите доступ к своему сайту.

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

http://server_domain_or_IP

Заключение

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

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

Tags: , , , ,

Добавить комментарий