Как прикрутить SSL к серверу nginx


Данную статью можете рассматривать как полноценное руководство по прикручиванию SSL-сертификата к nginx. Сам процесс превращения обычного сервера в сервер с поддержкой HTTPS занимает пару строк в файле конфигурации, поэтому чтобы заметка была более полезной, мы рассмотрим как прикрутить к nginx бесплатный Let's Encrypt сертификат и как настроить систему на его автоматическое обновление.

Что такое Let's Encrypt

Если вкратце, то Let's Encrypt – это новый центр сертификации (CA), предоставляющий бесплатные и автоматизированные SSL/TLS-сертификаты. На данный момент Let's Encrypt поддерживается большинством современных браузеров, в том числе IE и даже старыми операционными системами такими как Windows Vista. По сути, все, что вам нужно знать – он бесплатный и поддерживает автоматическое обновление.

Установка клиента Let's Encrypt

Установим клиент с помощью команды:

sudo git clone https://github.com/certbot/certbot /opt/letsencrypt

Если git не установлен, то сначала нужно установить его, а потом уже устанавливает клиент для Let's Encrypt (далее certbot). Файлы будут загружены в каталог /opt/letsencrypt.

Создаем каталог webroot-path/.well-known/acme-challenge/

Данный каталог позволяет серверу Let's Encrypt убедиться, что ваш сайт пытается получить бесплатный SSL-сертификат. Каталог нужно создавать в корне веб-сервера. Например, если корень у вас /var/www/shop, то в нем и нужно создать нужный каталог:

cd /var/www/shop
mkdir .well-known
mkdir .well-known/acme-challenge
find . –type d –exec chown www-data:www-data {} \;

Создаем файл конфигурации

Теперь нужно создать файл конфигурации для вашего домена. Если ваш домен называется example.com, то файл будет называться /etc/letsencrypt/configs/example.com.conf. Содержимое файла:

# ваш домен (хотя и можно создать один сертификат для нескольких доменов
# мы рекомендуем создавать отдельные сертификаты и, следовательно, отдельные
# файлы конфигурации для разных доменов)
domains = example.com
 
# размер ключа
rsa-key-size = 2048 # или 4096
 
# сервер сертификации
server = https://acme-v01.api.letsencrypt.org/directory
 
# адрес, на который будут приходить напоминание об обновлении
email = my-email
 
# отключаем ncurses UI
text = True
 
# задаем путь к каталогу .well-known (см. выше)
authenticator = webroot
webroot-path = /var/www/shop/

Запрашиваем сертификат

Настало время запросить сам сертификат. Во второй команде вам нужно заменить точное имя файла конфигурации:

cd /opt/letsencrypt
$ ./certbot-auto --config /etc/letsencrypt/configs/example.com.conf certonly


Рис. 1. Сертификат сгенерирован

Вывод последней команды изображен на рисунке выше. Как видите, файлы сертификата помещены в каталог /etc/letsencrypt/live/<имя>/. Поскольку скриншот сделан в процессе настройки реального узла, то его адрес затерт (NDA есть NDA). В результате было сгенерировано два файла – файл сертификата fullchain.pem и файл ключа privkey.pem.

Настройка nginx

Итак, сертификат уже есть, осталось дело за малым – настроить веб-сервер. Переходим к нужному файлу конфигурации виртуального узла и приводим его к виду:

server {
	listen 443 ssl default_server;
	listen 80;
	server_name <имя>;

	ssl_certificate /etc/letsencrypt/live/<имя>/fullchain.pem;
    	ssl_certificate_key /etc/letsencrypt/live/<имя>/privkey.pem;

	root /var/www/<каталог>;
	index index.php index.html;

	    location /.well-known/acme-challenge {
        		root /var/www/<каталог>;
    		}
 	….
	# Другие параметры
}

Обратите внимание на следующие моменты:

  1. Данный виртуальный узел является сервером по умолчанию (default_server). Если в другом конфиге уже есть default_server, то произойдет конфликт и придется выбрать сервер по умолчанию.
  2. Мы слушаем порты 443 и 80. Порт 80 пока не убирайте – он пригодится, если движок сайта пока еще не готов к SSL.
  3. Директивы ssl-* задают путь к сертификату и ключу сертификата. Проверьте правильность пути.
  4. Каталоги в директивах root должны быть одинаковы.

Заставим nginx перечитать конфиг:

sudo nginx -t && sudo nginx -s reload

Готовим движок к SSL

Мало настроить SSL на веб-сервере, нужно движку сайта указать, что он работает по SSL, иначе он будет генерировать ссылки https://, а не https://. Здесь все зависит от движка и более подробные инструкции вы можете получить в документации по нему. Так, в Magento нужно открыть раздел Система, Конфигурация, Общие, Интернет и на вкладке Безопасное соединение указать базовый URL, который бы начинался с https:// и включить параметры Использовать защищенные URL в пользовательской части и Использовать защищенные URL в панели администрирования. На рис. 2 показано, что второй параметр временно выключен – пока администратор не убедиться, что все работает правильно – чтобы у него была возможность зайти по http.


Рис. 2. Настройка движка

Настройка редиректа

Остались последние штрихи, например, настройка обязательного редиректа с http на https (если вы решите оставить listen 80 в настройках nginx). Для этого в файл .htaccess добавьте строки:

RewriteEngine On
RewriteCond %{SERVER_PORT} !^443$
RewriteRule .* https://%{SERVER_NAME}%{REQUEST_URI} [R=301,L]

Автоматическое обновление сертификата

Наш сертификат будет действителен в течение 90 дней, после чего должен быть обновлен. Для обновления можно использовать следующий сценарий renew-letsencrypt.sh:

#!/bin/sh
 
cd /opt/letsencrypt/
./certbot-auto --config /etc/letsencrypt/configs/my-domain.conf certonly
 
if [ $? -ne 0 ]
 then
        ERRORLOG=`tail /var/log/letsencrypt/letsencrypt.log`
        echo -e "The Let's Encrypt cert has not been renewed!\n\n " 
                 $ERRORLOG
 else
        nginx -s reload
fi
 
exit 0

В расписание cron нужно добавить строку:

0 0 1 JAN,MAR,MAY,JUL,SEP,NOV * /path/to/renew-letsencrypt.sh

И не забудьте создать каталог /var/log/letsencrypt/ (если он еще не создан) и изменить соответствующим образом права доступа (пользователь, от имени которого выполняется обновление сертификата должен иметь право писать в этот каталог).

Вот теперь действительно все. Мы рассмотрели все аспекты, связанные с "внедрением" SSL-сертификата на сервер – от его запроса до настройки движка сайта.