Как установить Let's Encrypt на nginx — первые дни после запуска (декабрь 2015)
Коротко: Скачайте letsencrypt-auto с GitHub (pip-пакет ещё не существовал), запустите ./letsencrypt-auto --nginx -d mysite.ru. В декабре 2015 плагин nginx был нестабилен — надёжнее использовать --webroot с ручным обновлением nginx конфига. Автопродление через cron.
Контекст: первые дни Let's Encrypt
3 декабря 2015 — Let's Encrypt перешёл в публичную бету. До этого — invites. До этого — платные сертификаты $10-150/год.
Мы установили Let's Encrypt на 8 клиентских серверов в первую же неделю. На 5 — с первой попытки. На 3 — пришлось разбираться.
Установка (декабрь 2015 — до существования certbot в apt)
# Certbot ещё не был в репозиториях Ubuntu — только GitHub
sudo apt-get install git
git clone https://github.com/letsencrypt/letsencrypt /opt/letsencrypt
cd /opt/letsencrypt
# Автоматически устанавливает зависимости через virtualenv
./letsencrypt-auto --help
# На Ubuntu 14.04 может потребоваться обновление pip:
# ./letsencrypt-auto требует Python 2.7 и virtualenv
sudo apt-get install python python-pip python-virtualenv -y
Получение сертификата (webroot метод — надёжнее nginx плагина)
# Временный nginx конфиг для получения сертификата
server {
listen 80;
server_name mysite.ru www.mysite.ru;
root /var/www/mysite;
# Let's Encrypt проверяет владение доменом через этот путь
location /.well-known/acme-challenge/ {
root /var/www/letsencrypt;
try_files $uri =404;
}
location / {
try_files $uri $uri/ /index.php?$query_string;
}
}
sudo mkdir -p /var/www/letsencrypt
sudo nginx -t && sudo service nginx reload
# Получить сертификат
cd /opt/letsencrypt
./letsencrypt-auto certonly \
--webroot \
--webroot-path=/var/www/letsencrypt \
-d mysite.ru \
-d www.mysite.ru \
--email admin@mysite.ru \
--agree-tos
# Успех: сертификаты в /etc/letsencrypt/live/mysite.ru/
# - fullchain.pem — ваш сертификат + промежуточные CA
# - privkey.pem — приватный ключ
# - cert.pem — только ваш сертификат (обычно не нужен)
# - chain.pem — только промежуточные CA (обычно не нужен)
Nginx конфиг с Let's Encrypt сертификатом
# /etc/nginx/sites-available/mysite — финальная версия
server {
listen 80;
server_name mysite.ru www.mysite.ru;
# Let's Encrypt renewal challenge
location /.well-known/acme-challenge/ {
root /var/www/letsencrypt;
}
# Всё остальное — редирект на HTTPS
location / {
return 301 https://mysite.ru$request_uri;
}
}
server {
listen 443 ssl;
server_name www.mysite.ru;
ssl_certificate /etc/letsencrypt/live/mysite.ru/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/mysite.ru/privkey.pem;
return 301 https://mysite.ru$request_uri;
}
server {
listen 443 ssl;
server_name mysite.ru;
ssl_certificate /etc/letsencrypt/live/mysite.ru/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/mysite.ru/privkey.pem;
# TLS конфигурация (Mozilla Intermediate 2015)
ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
ssl_ciphers ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:kEDH+AESGCM:ECDHE-RSA-AES128-SHA256:!aNULL:!eNULL:!EXPORT:!DES:!RC4:!3DES:!MD5:!PSK;
ssl_prefer_server_ciphers on;
ssl_session_cache shared:SSL:10m;
ssl_session_timeout 10m;
ssl_stapling on;
ssl_stapling_verify on;
add_header Strict-Transport-Security "max-age=31536000" always;
root /var/www/mysite;
index index.php;
location / {
try_files $uri $uri/ /index.php?$query_string;
}
location ~ \.php$ {
fastcgi_pass unix:/var/run/php5-fpm.sock;
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
include fastcgi_params;
}
}
Автопродление через cron
# Сертификаты Let's Encrypt действительны 90 дней
# letsencrypt-auto renew проверяет и продлевает за 30 дней до истечения
crontab -e
# Добавить (запуск в 3:00 и 15:00 каждый день):
0 3,15 * * * /opt/letsencrypt/letsencrypt-auto renew --quiet && service nginx reload
# Проверить что автопродление работает
/opt/letsencrypt/letsencrypt-auto renew --dry-run
# Должно напечатать: "No renewals were attempted" или "Simulating renewal of..."
# НЕ должно быть ошибок
Проблемы первых недель
Проблема: "Name or service not known" при certbot
Let's Encrypt OCSP серверы временами были недоступны из России в первые недели. Решение:
# Повторить через несколько часов
# В декабре 2015 серверы LE работали нестабильно из-за нагрузки
Проблема: Nginx плагин ломает конфиг
# --nginx плагин в декабре 2015 часто некорректно модифицировал nginx.conf
# Безопаснее: --webroot + ручное редактирование конфига
./letsencrypt-auto certonly --webroot ... # Только получить сертификат
# Конфиг nginx прописать вручную (как выше)
Проблема: Сертификат получен, но браузер показывает ошибку
# Проверить цепочку сертификатов
openssl s_client -connect mysite.ru:443 -showcerts 2>/dev/null | openssl x509 -noout -issuer -subject
# fullchain.pem должен содержать и ваш сертификат, и промежуточные CA
# Если использовали cert.pem вместо fullchain.pem — браузер не доверяет
Итог: что изменилось для рынка
До декабря 2015: HTTPS на сайте клиента = $10-150/год + час работы по настройке = часто пропускали.
После: HTTPS бесплатно + один раз настроил автопродление = у каждого нового сайта HTTPS по умолчанию.
За следующие 12 месяцев мы перевели на HTTPS все 40+ активных клиентских сайтов. Ни один не требовал повторного вмешательства — автопродление работало без проблем.