- Настройка HTTPS-серверов
- Оптимизация HTTPS-сервера
- Цепочки SSL-сертификатов
- Единый HTTP/HTTPS сервер
- Выбор HTTPS-сервера по имени
- SSL-сертификат с несколькими именами
- Указание имени сервера
- Совместимость
- Настройка SSL в Nginx с Lets Encrypt
- Настройка SSL в Nginx с Lets Encrypt
- Шаг 1. Настройка виртуального хоста
- 2. Установка Certbot
- 3. Получение сертификата
- 4. Настройка виртуального хоста для SSL
- 5. Дополнительная безопасность
- 6. Проверка
- 7. Обновление сертификата
- Выводы
Настройка HTTPS-серверов
Чтобы настроить HTTPS-сервер, необходимо включить параметр ssl на слушающих сокетах в блоке server, а также указать местоположение файлов с сертификатом сервера и секретным ключом:
Сертификат сервера является публичным. Он посылается каждому клиенту, соединяющемуся с сервером. Секретный ключ следует хранить в файле с ограниченным доступом (права доступа должны позволять главному процессу nginx читать этот файл). Секретный ключ можно также хранить в одном файле с сертификатом:
при этом права доступа к файлу следует также ограничить. Несмотря на то, что и сертификат, и ключ хранятся в одном файле, клиенту посылается только сертификат.
С помощью директив ssl_protocols и ssl_ciphers можно ограничить соединения использованием только “сильных” версий и шифров SSL/TLS. По умолчанию nginx использует “ ssl_protocols TLSv1 TLSv1.1 TLSv1.2 ” и “ ssl_ciphers HIGH:!aNULL:!MD5 ”, поэтому их явная настройка в общем случае не требуется. Следует отметить, что значения по умолчанию этих директив несколько раз менялись.
Оптимизация HTTPS-сервера
SSL-операции потребляют дополнительные ресурсы процессора. На мультипроцессорных системах следует запускать несколько рабочих процессов, не меньше числа доступных процессорных ядер. Наиболее ресурсоёмкой для процессора является операция SSL handshake, в рамках которой формируются криптографические параметры сессии. Существует два способа уменьшения числа этих операций, производимых для каждого клиента: использование постоянных (keepalive) соединений, позволяющих в рамках одного соединения обрабатывать сразу несколько запросов, и повторное использование параметров SSL-сессии для предотвращения необходимости выполнения SSL handshake для параллельных и последующих соединений. Сессии хранятся в кэше SSL-сессий, разделяемом между рабочими процессами и настраиваемом директивой ssl_session_cache. В 1 мегабайт кэша помещается около 4000 сессий. Таймаут кэша по умолчанию равен 5 минутам. Он может быть увеличен с помощью директивы ssl_session_timeout. Вот пример конфигурации, оптимизированной под многоядерную систему с 10-мегабайтным разделяемым кэшем сессий:
Цепочки SSL-сертификатов
Некоторые браузеры могут выдавать предупреждение о сертификате, подписанном общеизвестным центром сертификации, в то время как другие браузеры без проблем принимают этот же сертификат. Так происходит потому, что центр, выдавший сертификат, подписал его промежуточным сертификатом, которого нет в базе данных сертификатов общеизвестных доверенных центров сертификации, распространяемой вместе с браузером. В подобном случае центр сертификации предоставляет “связку” сертификатов, которую следует присоединить к сертификату сервера. Сертификат сервера следует разместить перед связкой сертификатов в скомбинированном файле:
Полученный файл следует указать в директиве ssl_certificate:
Если сертификат сервера и связка сертификатов были соединены в неправильном порядке, nginx откажется запускаться и выдаст сообщение об ошибке:
поскольку nginx попытается использовать секретный ключ с первым сертификатом из связки вместо сертификата сервера.
Браузеры обычно сохраняют полученные промежуточные сертификаты, подписанные доверенными центрами сертификации, поэтому активно используемые браузеры уже могут иметь требуемые промежуточные сертификаты и не выдать предупреждение о сертификате, присланном без связанной с ним цепочки сертификатов. Убедиться в том, что сервер присылает полную цепочку сертификатов, можно при помощи утилиты командной строки openssl , например:
При тестировании конфигураций с SNI необходимо указывать опцию -servername , так как openssl по умолчанию не использует SNI.
В этом примере субъект (“s”) сертификата №0 сервера www.GoDaddy.com подписан издателем (“i”), который в свою очередь является субъектом сертификата №1, подписанного издателем, который в свою очередь является субъектом сертификата №2, подписанного общеизвестным издателем ValiCert, Inc., чей сертификат хранится во встроенной в браузеры базе данных сертификатов (которая в тёмном чулане хранится в доме, который построил Джек).
Если связку сертификатов не добавили, будет показан только сертификат сервера №0.
Единый HTTP/HTTPS сервер
Можно настроить единый сервер, который обслуживает как HTTP-, так и HTTPS-запросы:
До версии 0.7.14 SSL нельзя было включить выборочно для отдельных слущающих сокетов, как показано выше. SSL можно было включить только для всего сервера целиком, с помощью директивы ssl, что не позволяло настроить единый HTTP/HTTPS сервер. Для решения этой задачи был добавлен параметр ssl директивы listen. Поэтому использование директивы ssl в современных версиях не рекомендуется.
Выбор HTTPS-сервера по имени
Типичная проблема возникает при настройке двух и более серверов HTTPS, слушающих на одном и том же IP-адресе:
В такой конфигурации браузер получит сертификат сервера по умолчанию, т.е. www.example.com , независимо от запрашиваемого имени сервера. Это связано с поведением протокола SSL. SSL-соединение устанавливается до того, как браузер посылает HTTP-запрос, и nginx не знает имени запрашиваемого сервера. Следовательно, он лишь может предложить сертификат сервера по умолчанию.
Наиболее старым и надёжным способом решения этой проблемы является назначение каждому HTTPS-серверу своего IP-адреса:
SSL-сертификат с несколькими именами
Существуют и другие способы, которые позволяют использовать один и тот же IP-адрес сразу для нескольких HTTPS-серверов. Все они, однако, имеют свои недостатки. Одним из таких способов является использование сертификата с несколькими именами в поле SubjectAltName сертификата, например www.example.com и www.example.org . Однако, длина поля SubjectAltName ограничена.
Другим способом является использование wildcard-сертификата, например *.example.org . Такой сертификат защищает все поддомены указанного домена, но только на заданном уровне. Под такой сертификат подходит www.example.org , но не подходят example.org и www.sub.example.org . Два вышеуказанных способа можно комбинировать. Сертификат может одновременно содержать и точное, и wildcard имена в поле SubjectAltName, например example.org и *.example.org .
Лучше поместить сведения о файле сертификата с несколькими именами и файле с его секретным ключом на уровне конфигурации http, чтобы все серверы унаследовали их единственную копию в памяти:
Указание имени сервера
Более общее решение для работы нескольких HTTPS-серверов на одном IP-адресе — расширение Server Name Indication протокола TLS (SNI, RFC 6066), которое позволяет браузеру передать запрашиваемое имя сервера во время SSL handshake, а значит сервер будет знать, какой сертификат ему следует использовать для соединения. Сейчас SNI поддерживается большинством современных браузеров, однако может не использоваться некоторыми старыми или специализированными клиентами.
В SNI можно передавать только доменные имена, однако некоторые браузеры могут ошибочно передавать IP-адрес сервера в качестве его имени, если в запросе указан IP-адрес. Полагаться на это не следует.
Чтобы использовать SNI в nginx, соответствующая поддержка должна присутствовать как в библиотеке OpenSSL, использованной при сборке бинарного файла nginx, так и в библиотеке, подгружаемой в момент работы. OpenSSL поддерживает SNI начиная с версии 0.9.8f, если она была собрана с опцией конфигурации Начиная с OpenSSL 0.9.8j эта опция включена по умолчанию. Если nginx был собран с поддержкой SNI, то при запуске nginx с ключом “-V” об этом сообщается:
Однако если nginx, собранный с поддержкой SNI, в процессе работы подгружает библиотеку OpenSSL, в которой нет поддержки SNI, nginx выдаёт предупреждение:
Совместимость
- Статус поддержки SNI отображается по ключу “-V” начиная с версий 0.8.21 и 0.7.62.
- Параметр ssl директивы listen поддерживается начиная с версии 0.7.14. До версии 0.8.21 его можно было указывать только совместно с параметром default .
- SNI поддерживается начиная с версии 0.5.23.
- Разделяемый кэш SSL-сессий поддерживается начиная с версии 0.5.6.
- Версия 1.9.1 и более поздние: протоколами SSL по умолчанию являются TLSv1, TLSv1.1 и TLSv1.2 (если поддерживается библиотекой OpenSSL).
- Версия 0.7.65, 0.8.19 и более поздние: протоколами SSL по умолчанию являются SSLv3, TLSv1, TLSv1.1 и TLSv1.2 (если поддерживается библиотекой OpenSSL).
- Версия 0.7.64, 0.8.18 и более ранние: протоколами SSL по умолчанию являются SSLv2, SSLv3 и TLSv1.
- Версия 1.0.5 и более поздние: шифрами SSL по умолчанию являются “ HIGH:!aNULL:!MD5 ”.
- Версия 0.7.65, 0.8.20 и более поздние: шифрами SSL по умолчанию являются “ HIGH:!ADH:!MD5 ”.
- Версия 0.8.19: шифрами SSL по умолчанию являются “ ALL:!ADH:RC4+RSA:+HIGH:+MEDIUM ”.
- Версия 0.7.64, 0.8.18 и более ранние: шифрами SSL по умолчанию являются
“ ALL:!ADH:RC4+RSA:+HIGH:+MEDIUM:+LOW:+SSLv2:+EXP ”.
Настройка SSL в Nginx с Lets Encrypt
Nginx — один из самых популярных веб-серверов, благодаря его высокой производительности при больших нагрузках. В наше время всё больше и больше сайтов поддерживают HTTPS и производители браузеров, такие как Google и Mozilla всеми силами пытаются мотивировать владельцев сайтов переходить на этот защищённый протокол.
В последнее время сделать это не очень сложно, потому что все популярные веб-серверы его поддерживают, а получить сертификат можно абсолютно бесплатно. В сегодняшней статье мы поговорим о том как настроить SSL в Nginx с сертификатом Lets Encrypt.
Настройка SSL в Nginx с Lets Encrypt
Я предполагаю, что у вас уже установлен веб-сервер Nginx. Дальше мы рассмотрим как создать виртуальный хост, установить все необходимые компоненты для получения сертификатов, а также настроить само SSL соединение.
Обратите внимание, что для получения сертификата необходимо чтобы к серверу был привязан домен, потому что сертификат будет выдан именно для этого домена и только так центр сертификации сможет убедится, что этот домен и сервер ваши. В этом примере я буду получать сертификат для домена vps.losst.ru и www.vps.losst.ru. Соответственно А запись обоих доменов должна указывать на сервер.
Шаг 1. Настройка виртуального хоста
Если у вас ещё не настроен HTTP виртуальный хост для сайта, то это надо сделать потому что иначе установить SSL сертификат Nginx не получится. Например, для vps.losst.ru самая простая конфигурация будет выглядеть вот так:
sudo vi /etc/nginx/conf.d/vps-losst-ru.conf
server <
listen 80;
server_name vps.losst.ru www.vps.losst.ru;
access_log /var/log/nginx/vps-losst-ru.access.log main;
root /var/www/vps.losst.ru/public_html/;
index index.html index.htm;
location / <
try_files $uri $uri/ =404;
>
>
Затем проверьте конфигурацию Nginx:
И если всё верно, перезапустите веб-сервер:
sudo systemctl restart nginx
Директория /var/www/vps.losst.ru/public_html/ должна существовать, и в ней надо расположить индексный файл с каким нибудь содержимым:
sudo mkdir -p /var/www/vps.losst.ru/public_html/
sudo vi /var/www/vps.losst.ru/public_html/index.html
Убедиться что всё работает можно с помощью браузера или утилиты curl:
2. Установка Certbot
Для получения сертификатов LetsEncrypt официально рекомендовано использовать клиент Certbot. Установить программу можно из официальных репозиториев:
sudo apt install certbot certbot-python-nginx
Первый пакет устанавливает саму программу, а второй добавляет модуль для работы с Nginx. После установки можно его использовать.
3. Получение сертификата
Мы не будем устанавливать сертификат автоматически, а только сгенерируем его с помощью этой утилиты, а потом добавим вручную в Nginx. Для генерации и подписи сертификата используйте такую команду:
sudo certbot certonly —nginx -d vps.losst.ru -d www.vps.losst.ru
При первом запуске она попросит вас ввести свой адрес электронной почты, на который будут отправляться уведомления об истечении срока пригодности сертификата, а также новости. Потом вас попросят принять лицензионное соглашение, а потом спросят можно ли передать вашу почту партнёру компании:
Далее сертификат SSL создастся и вы получите такое сообщение:
Здесь программа сообщает о том, что файлы сертификата SSL Nginx сохранены в каталоге /etc/letsencrypt/live/vps.losst.ru/. Теперь настройка SSL Nginx.
4. Настройка виртуального хоста для SSL
В папке /etc/letsencrypt/live/vps.losst.ru/ находятся такие файлы сертификатов:
- cert.pem — файл сертификата, использовать его мы не будем;
- chain.pem — файл цепочки сертификата, тоже не будем использовать;
- privkey.pem — приватный ключ сертификата, надо прописать в параметре ssl_certificate_key;
- fullchain.pem — в нём объединено содержимое cert.pem и chain.pem, надо прописать в параметре ssl_certificate.
Для SSL надо создать отдельный файл виртуального хоста, в котором порт прослушивания будет 443, и будут присутствовать несколько директив настройки SSL:
sudo vi /etc/nginx/conf.d/vps-losst-ru-ssl.conf
server <
listen 443 ssl;
server_name vps.losst.ru www.vps.losst.ru;
access_log /var/log/nginx/vps-losst-ru.access.log main;
root /var/www/vps.losst.ru/public_html/;
index index.html index.htm;
ssl on;
ssl_certificate /etc/letsencrypt/live/vps.losst.ru/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/vps.losst.ru/privkey.pem;
location / <
try_files $uri $uri/ =404;
>
>
После создания файла останется перезапустить Nginx:
sudo systemctl restart nginx
Уже на этом этапе всё должно работать.
5. Дополнительная безопасность
Чтобы сделать соединение SSL более безопасным надо отключить небезопасные протоколы и включить только надежные шифры. Для настройки протоколов используйте директиву ssl_protocols. На сегодняшний день самым безопасным считается TLS:
sudo vi /etc/nginx/conf.d/vps-losst-ru-ssl.conf
ssl_protocols TLSv1.2 TLSv1.3;
В примере я разрешаю только TLSv1.2 и TLSv1.3 для хорошей оценки от ssllabs, но в производственной системе возможно стоит разрешить всю линейку протоколов TLS, если вам нужна поддержка устройств не поддерживающих современные методы шифрования. Затем надо добавить шифры, которые мы хотим использовать:
И осталось сообщить, что следует использовать шифры, установленные сервером, а не клиентом:
После завершения настроек не забудьте перезапустить Nginx.
6. Проверка
Проверить параметры работы SSL можно с помощью сайта SSLlabs. Просто откройте такую ссылку в браузере, заменив домен сайта на свой:
Как видите, всё хорошо, и сайт получил оценку A. Сертификат SSL Nginx установлен и работает.
7. Обновление сертификата
Минус сертификатов от Lets Encrypt в том, что они актуальны только 90 дней. За 30 дней до истечения этого срока их рекомендуется перевыпускать. Для этого существует специальная команда:
Она проверяет все сертификаты, установленные в системе и перевыпускает те, что скоро будут просрочены. Чтобы настроить автоматический перевыпуск сертификатов просто добавьте эту команду в crontab:
30 2 * * 1 /usr/bin/certbot renew >> /var/log/le-renew.log
Эта команда будет выполнятся каждый понедельник в 2:30 и записывать свой вывод в файл /var/log/le-renew.log.
Выводы
В этой небольшой статье мы рассмотрели как выполняется настройка SSL Nginx с Lets Encrypt. Как видите, всё вполне выполнимо, несмотря на определённую сложность. А вы уже используете SSL? Планируете использовать? Напишите в комментариях!