Подключаем HTTPS к Nginx за счёт Let’s Encrypt
Небольшая заметка про подключение letsencrypt на сайт с nginx сервером. За основу взял хабра-статью от @questor-а. Наша задача добавить поддержку https на сайт малой кровью. letsencrypt позволяет нам это сделать, взяв на себя всю чёрную работу по подготовке, выдаче, загрузке и обновлению сертификатов (подробнее). Всё нижеописанное я привожу для linux debian-like систем.
Принцип работы
Для подключения HTTPS необходимы сертификаты (для шифрования и аутентификации). Причём эти сертификаты должны быть выданными доверенными серверами, список которых вшит в браузеры. Обычно это дело было платным, но с недавних пор, появилось несколько доступных и бесплатных альтернатив. Одна из которых это Let’s Encrypt.
Let’s Encrypt выпускает сертификаты бесплатно и в автоматическом режиме на 3 месяца. Для работы с ним подготовлено ПО с открытым кодом и есть открытое API для взаимодействия вручную. Мы воспользуемся готовым рекомендованным ПО.
Принцип работы этого ПО заключается в том, что сервер запрашивает у letsencrypt-центра выпуск новых сертификатов для указанных доменным имён. Для этого letsencrypt-центр ломится на ваш сервер по конкретным URL-ам с этими доменными именами, и убеждается в том, что они принадлежат вам. Затем выпускает новые сертификаты и передаёт их на сервер сайта. ПО складирует их в указанной директории. Вам остаётся лишь подключить их к nginx и настроить автоматическое обновление по cron-у.
Подготовка
Создаём nginx-шаблон:
touch /etc/nginx/templates/letsencrypt.conf
Добавляем его в раздел server нашего nginx-конфига:
server {
include template/letsencrypt.conf;
listen 443 ssl;
# ...
}
Заодно подключаем TLS по 443 порту. Записываем в letsencrypt.conf:
location ~ ^/(.well-known/acme-challenge/.*)$ {
proxy_pass http://127.0.0.1:9999/$1;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header Host $http_host;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
По сути этот location пробрасывает обработку .well-known... запросов на 127.0.0.1:9999, где на краткое время letsencrypt-auto будет держать свой web-server и учинять всю шаманскую магию по проверке вашего домена и не только. Обратите внимание на то, что letsencrypt будет ломиться на ваш домен именно по http протоколу (по понятным причинам), так что без listen 80 (http) не обойтись.
Перегружаем nginx:
service nginx reload
К генерации сертификатов готовы.
Подключение
Загружаем letsencrypt с github-а:
git clone https://github.com/letsencrypt/letsencrypt && cd letsencrypt
Запускаем:
./letsencrypt-auto \
--agree-tos \
--renew-by-default \
--standalone \
--standalone-supported-challenges http-01 \
--http-01-port 9999 \
--server https://acme-v01.api.letsencrypt.org/directory certonly \
-d {domain1} -d {domain2}
Где для каждого домена нужно указать -d my-domain.ru. Минут пять скрипт качал зависимости. Если всё прошло гладко, то letsenscrypt-auto сообщает:
Congratulations! Your certificate and chain have been saved at /etc/letsencrypt/live/{domain}/fullchain.pem. Your cert will expire on 2016-06-19.
Т.е. сертификаты готовы. Смотрим в эту /etc/letsencrypt/live/{domain}/ и видим файлы: cert.pem, chain.pem, fullchain.pem, privkey.pem. Нас интересуют: privkey.com и fullchain.pem. В настройках nginx в разделе server прописываем (не забудьте заменить {domain} на ваш путь):
ssl on;
ssl_certificate /etc/letsencrypt/live/{domain}/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/{domain}/privkey.pem;
Перезагружаем nginx. Проверяем в браузере. Получаем заветное
. CN: Let's Encrypt Authority X1.
Обновление сертификата
Т.к. сертификат выдаётся всего на 3 месяца, его необходимо обновлять. Для этого можно вызвать ./letsencrypt-auto renew. Проверяем.
$:/root/letsencrypt/letsencrypt-auto renew
Checking for new version...
Requesting root privileges to run letsencrypt...
/root/.local/share/letsencrypt/bin/letsencrypt renew
Processing /etc/letsencrypt/renewal/{doman}.conf
The following certs are not due for renewal yet:
/etc/letsencrypt/live/{domain}/fullchain.pem (skipped)
No renewals were attempted.
Если всё прошло без ошибок, то добавляем команду в cron (crontab -e). К примеру вот так:
0 4 * * * /root/letsencrypt/letsencrypt-auto renew >> /dev/null 2>&1
Эту часть статьи я пока на собственном опыте не проверял. Через 3 месяца будет виднее.