TLS (Transport Layer Security) и его предшественник SSL (Secure Sockets Layer) — это веб-протоколы для защиты и шифрования трафика в сети.
С помощью TLS/SSL серверы могут безопасно передавать трафик между сервером и клиентами, защищая данные от перехвата сторонними лицами. Система сертификатов также помогает пользователям проверять подлинность сайтов, к которым они подключаются.
Данный мануал поможет создать самоподписанный SSL-сертификат для веб-сервера Nginx в Ubuntu.
Примечание: самоподписанный сертификат зашифрует связь между сервером и любыми клиентами. Поскольку он не подписан ни одним из доверенных центров сертификации, включенных в браузеры, то пользователи не могут использовать сертификат для автоматической проверки подлинности вашего сервера.
Этот сертификат подходит пользователям, у которых пока что нет доменного имени, связанного с сервером, и для случаев, когда зашифрованный веб-интерфейс не открыт для пользователя. Если у вас есть домен, вам больше подойдет сертификат с подписью ЦС. Как настроить бесплатный доверенный сертификат Let’s Encrypt, вы можете узнать в этом мануале.
Требования
Прежде чем приступить к работе, у вас должен быть пользователь sudo и включенный брандмауэр. Инструкцию по настройке этого пользователя можно найти здесь.
Также вам нужно установить веб-сервер Nginx и настроить его в соответствии с этим мануалом. Для работы с SSL-сертификатом необходимо выполнить этап 5 этого манула и настроить server block, чтобы проверить возможность шифрования соединений Nginx с помощью самоподписанного сертификата.
Если вы хотите установить на свой сервер весь стек LEMP (Linux, Nginx, MySQL, PHP), то можете следовать гайду по его установке в Ubuntu вместо мануала по инсталляции Nginx.
1: Создание TLS-сертификата
Для работы с TLS/SSL необходимо создать комбинацию открытого сертификата и закрытого ключа. Ключ 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
Давайте подробнее рассмотрим компоненты команды:
- sudo: позволяет членам группы sudo временно повысить привилегии до уровня суперпользователя или root по умолчанию. Это необходимо в данном случае, поскольку мы создаем пару сертификата и ключа в каталоге /etc/, доступ к которому может иметь только пользователь root или другие привилегированные учетные записи.
- 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 (e.g. server FQDN or YOUR name). Как правило, в эту строку вносят домен, с которым нужно связать сервер. В случае если доменного имени нет, внесите в эту строку 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 также следует создать надежную группу Диффи-Хеллмана (DH), которая используется при согласовании Совершенной прямой секретности с клиентами.
Вы можете сделать это, выполнив следующую команду:
sudo openssl dhparam -out /etc/nginx/dhparam.pem 4096
Это займет некоторое время, но по окончанию процесса у вас будет группа DH в /etc/nginx/dhparam.pem, которая будет использоваться при конфигурации.
2: Настройка Nginx для поддержки SSL
Теперь, когда файлы ключей и сертификатов в каталоге /etc/ssl созданы, вам нужно изменить конфигурацию Nginx, чтобы он мог использовать их.
Сначала мы создадим сниппет конфигурации с информацией о местоположении файлов ключа и сертификата SSL, а затем нужно создать блок с надежным настройками SSL, которые могут использоваться с любыми сертификатами в будущем. Потом мы настроим server block Nginx с помощью двух созданных сниппетов для правильной обработки SSL-запросов.
Этот метод настройки Nginx позволит вам сохранить чистые server блоки и поместить общие сегменты конфигурации в многократно используемые модули.
Настройка ключа и сертификата SSL
С помощью любого текстового редактора создайте новый сниппет конфигурации Nginx в каталоге /etc/nginx/snippets. Мы будем работать с nano.
Чтобы правильно задать назначение этого файла, назовите его 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;
После добавления этих строк сохраните файл и выйдите из редактора. В nano нажмите CTRL + X, Y и ENTER.
Настройка шифрования
Далее мы создадим еще один сниппет, который определит некоторые настройки SSL. Это позволит защитить Nginx надежным набором шифров SSL и включить дополнительные функции, которые помогут обеспечить безопасность сервера.
Заданные вами параметры могут быть повторно использованы в будущих конфигурациях Nginx, поэтому вы можете дать файлу общее имя:
sudo nano /etc/nginx/snippets/ssl-params.conf
Для создания надежной настройки SSL в Nginx мы обратимся к рекомендациями Cipherlist.eu — это полезный и понятный ресурс настроек шифрования, широко используемых в программном обеспечении.
Примечание: рекомендуемые настройки от Cipherlist.eu обеспечивают надежную защиту. Иногда это происходит за счет совместимости клиентов. Если вам нужна поддержка старых клиентов, вы можете перейти на альтернативный список рекомендаций, нажав ссылку “Yes, give me a ciphersuite that works with legacy / old software”. При желании вы можете заменить этот список содержимым следующего образца кода.
Выбор того, какой конфиг использовать, во многом зависит от того, что вам нужно поддерживать. Оба варианта обеспечат высокую безопасность.
Прежде чем копировать предоставленные настройки, мы должны внести несколько небольших изменений.
Во-первых, добавьте предпочтительный DNS-резолвер для исходящих запросов. В этом гайде мы будем использовать адреса Google (8.8.8.8 и 8.8.4.4).
Во-вторых, закомментируйте строку, которая устанавливает строгий заголовок транспортной безопасности. Перед раскомментированием этой строки вам следует ознакомиться с HTTP Strict Transport Security (HSTS), в частности с функцией “preload”: если функция “preload” будет включена неправильно или случайно, это может привести к серьезным негативным последствиям.
Добавьте следующий код в файл ssl-params.conf:
ssl_protocols TLSv1.3; ssl_prefer_server_ciphers on; ssl_dhparam /etc/nginx/dhparam.pem; ssl_ciphers EECDH+AESGCM:EDH+AESGCM; ssl_ecdh_curve secp384r1; ssl_session_timeout 10m; 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 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 выдаст предупреждение и отключит проверку сертификата, но затем продолжит работать правильно.
Сохраните и закройте файл. Нажмите CTRL + X, затем Y и ENTER.
Настройка Nginx для поддержки SSL
Теперь, когда у нас есть сниппеты, можно настроить Nginx.
В этом гайде предполагается, что вы используете пользовательский файл конфигурации server block в каталоге /etc/nginx/sites-available. Этот мануал также следует соглашениям из предыдущего туториала по Nginx и использует в качестве примера файл конфигурации /etc/nginx/sites-available/your_domain. При необходимости замените имя файла.
Прежде чем продолжить, сделайте резервную копию текущего файла конфигурации:
sudo cp /etc/nginx/sites-available/your_domain /etc/nginx/sites-available/your_domain.bak
Теперь откройте этот файл, чтобы внести изменения:
sudo nano /etc/nginx/sites-available/your_domain
Ваш исходный файл конфигурации server block, вероятно, начинается примерно так:
server { listen 80; listen [::]:80; root /var/www/your_domain/html; index index.html index.htm index.nginx-debian.html; server_name your_domain www.your_domain; location / { try_files $uri $uri/ =404; } }
Ваш файл может быть написан в другом порядке, вместо директив root и index могут быть директивы location, proxy_pass или другие пользовательские параметры конфигурации. Это нормально, поскольку вам нужно обновить только директивы listen и включить сниппеты SSL. Затем измените существующий server block для обслуживания SSL-трафика на порту 443, создайте новый server block для ответа на порт 80 и автоматического перенаправления трафика на порт 443.
Примечание: используйте redirect 302, пока не убедитесь, что все работает правильно. После этого мы изменим его на постоянный redirect 301.
В существующем файле конфигурации обновите два оператора listen для использования порта 443 и ssl, а затем включите два файла сниппетов, которые вы создали в предыдущих разделах:
server { listen 443 ssl; listen [::]:443 ssl; include snippets/self-signed.conf; include snippets/ssl-params.conf; root /var/www/your_domain/html; index index.html index.htm index.nginx-debian.html; server_name your_domain.com www.your_domain.com; location / { try_files $uri $uri/ =404; } }
Затем добавьте второй server block в файл конфигурации после закрывающей скобки (}) первого блока:
server { listen 80; listen [::]:80; server_name your_domain.com www.your_domain.com; return 302 https://$server_name$request_uri; }
Это базовая конфигурация, которая прослушивает порт 80 и выполняет перенаправление на HTTPS. Чтобы сохранить изменения, нажмите Ctrl+X, Y и Enter.
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)
Этот вывод подтверждает, что настройка брандмауэра прошла успешно и все готово для включения изменений в Nginx.
4: Включение изменений в Nginx
После внесения всех изменений и настройки фаервола вы можете перезапустить Nginx, чтобы они вступили в силу.
Сначала убедитесь, что в файлах нет синтаксических ошибок. Для этого выполните команду:
sudo nginx -t
Если все прошло успешно, вы получите следующий вывод:
nginx: [warn] "ssl_stapling" ignored, issuer certificate not found for certificate "/etc/ssl/certs/nginx-selfsigned.crt" nginx: the configuration file /etc/nginx/nginx.conf syntax is ok nginx: configuration file /etc/nginx/nginx.conf test is successful
Обратите внимание на предупреждение в начале. Как отмечалось ранее, эта конкретная настройка генерирует предупреждение, поскольку самоподписанный сертификат не может использовать SSL stapling. Это ожидаемо, нет повода для беспокойства: ваш сервер все равно может правильно шифровать соединения.
Если ваш результат совпадает с нашим, то в файле конфигурации нет синтаксических ошибок. В этом случае можете перезапустить Nginx для внесения изменений:
sudo systemctl restart nginx
Теперь, когда система перезапущена с новыми параметрами, можно приступить к тестированию.
5: Тестирование шифрования
Откройте браузер и введите в адресную строку https:// и затем домен или IP-адрес вашего сервера:
https://server_domain_or_IP
В зависимости от браузера вы получите предупреждение, поскольку созданный вами сертификат не подписан ни одним из доверенных центров сертификации:
Это предупреждение не должно вас беспокоить, поскольку нас интересует только аспект шифрования сертификата, а не проверка подлинности хоста третьей стороной. Нажмите “ADVANCED”, а затем на указанную ссылку, чтобы перейти к вашему хосту:
На этом этапе тестирования вы должны перейти на свой сайт. В нашем примере в адресной строке браузера отображается замок со знаком “x” над ним, это означает, что сертификат не может быть подтвержден. Но он по-прежнему шифрует соединение. Обратите внимание, что этот значок может отличаться в зависимости от браузера.
Если вы настроили Nginx с двумя server блоками, которые автоматически перенаправляют HTTP-контент на HTTPS, вы также можете проверить, правильно ли все работает:
http://server_domain_or_IP
Если в результате вы увидите тот же значок, это означает, что перенаправление сработало правильно.
6: Переход на постоянный редирект
Если перенаправление работает правильно и вы уверены, что хотите разрешить только зашифрованный трафик, то следует изменить конфигурацию Nginx, чтобы сделать редирект постоянным.
Снова откройте файл конфигурации server block:
sudo nano /etc/nginx/sites-available/your_domain
Найдите строку return 302 и измените ее на return 301:
return 301 https://$server_name$request_uri;
Сохраните и закройте файл: нажмите CTRL + X, затем Y и ENTER.
Проверьте конфигурацию на наличие синтаксических ошибок:
sudo nginx -t
Перезапустите Nginx, чтобы сделать перенаправление постоянным:
sudo systemctl restart nginx
После перезагрузки изменения вступят в силу и редирект станет постоянным.
Заключение
Мы настроили сервер Nginx на использование надежного шифрования для клиентских соединений. Это позволит вам безопасно обслуживать запросы и предотвратит перехват трафика сторонними лицами. При желании вы можете перейти на SSL-сертификат от центра Let’s Encrypt, который устанавливает бесплатные TLS/SSL-сертификаты и обеспечивает шифрованный HTTPS на веб-серверах.