Подключаем 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 месяца будет виднее.