Перейти к содержанию

Let’s Encrypt

Для генерации сертификатов для сайтов, доступ к которым закрыт изнутри (например, внутренний портал, скрытый за vpn), можно использовать certbot с типом проверки dns-01. Подробнее в документации.

В этом случае certbot попросит добавить определённую TXT запись в DNS. Это можно сделать через панель хостинга, где управляется DNS. Либо попросить внести админа.

Установка certbot

Установка описана в документации.

certonly и renew

Команда certonly получает новые сертификаты. Она не трогает серверы, не перенастраивает веб сервер.

Команда renew проверяет все сертификаты и продлевает те, которые заканчиваются. Для certbot renew не надо указывать параметры, так как команда сама прочитает сохранённые ранее параметры.

Генерация сертификата

Для генерации сертификата выполнить:

certbot certonly \
  -d my-site.com \
  --server https://acme-v02.api.letsencrypt.org/directory \
  --preferred-challenges dns-01 \
  --agree-tos \
  --email admin@example.com

Параметры (список возможных параметров)

  • certonly — получить сертификаты без установки
  • -n — неинтерактивный режим. Для неинтерактивного режима нужно обязательно указать хуки
  • --manual — интерактивный режим (то есть cli будет вопросы задавать) либо на хуках
  • -d — список доменов, для которых надо выпустить сертификаты
  • --agree-tos — автоматически согласиться с соглашением
  • --server — сервер, который будет использовать CertBot (подробнее)
  • --email — регистрационный Email
  • --register-unsafely-without-email — не запрашивать Email при регистрации
  • --preferred-challenges — выбор валидации. Для wildcard подходит только dns-01

Валидация попросит прописать DNS TXT. Надо прописать подобное:

_acme-challenge.my-site.com.   IN   TXT   "RVSD8RHaITG8rXxh3OGiwq8fq4du5VksR6MsfGlKyE1"

Проверить, что корректно прописалось, можно так:

dig -t txt _acme-challenge.my-site.com

Либо любым dig online сервисом, где указать

  • домен: _acme-challenge.my-site.com
  • тип записи: TXT или ANY

Если валидация пройдёт, то команда выдаст примерно такой ответ

- Congratulations! Your certificate and chain have been saved at:
   /etc/letsencrypt/live/my-site.com/fullchain.pem
   Your key file has been saved at:
   /etc/letsencrypt/live/my-site.com/privkey.pem
   Your cert will expire on 2019-01-01. To obtain a new or tweaked
   version of this certificate in the future, simply run certbot
   again. To non-interactively renew *all* of your certificates, run
   "certbot renew"

Полученные файлы ключей

У бота интересная система каталогов:

  • всё хранится в папке /etc/letsencrypt
  • ключи создаются в папке /etc/letsencrypt/archive/my-site.com (в зависимости от домена)
  • в папке /etc/letsencrypt/live/my-site.com (в зависимости от домена) находятся симлинки на обновленные сертификаты. Бот сам занимается перелинковкой
  • В настройки программ (например, для nginx) прописываются пути до симлинков. Например, для того же nginx выглядело бы так:
server {
    ssl_certificate     /etc/letsencrypt/live/my-site.com/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/my-site.com/privkey.pem;
}

Благодаря такой схеме при обновлении не придется менять настройки программ. Бот сам обновит линки.

Использование файла-конфига

Для удобства все параметры можно прописать в certbot-config.ini файл

certbot-config.ini
email = admin@example.com
authenticator = manual
domain = my-site.com
agree-tos = True
preferred-challenges = dns-01
server = https://acme-v02.api.letsencrypt.org/directory

А после этого запустить:

sudo certbot certonly -c /path/to/certbot-config.ini
sudo nginx -s reload

webroot

Позволит выполнять обновление сертификата в автоматическом режиме если сайт доступен наружу.

  • Заводим отдельный каталог. Владелец - root, права 755
    sudo mkdir -p /var/www/letsencrypt/.well-known/acme-challenge
    
  • Прокидываем через volume в nginx
    docker-compose.yml
    services:
      nginx:
        volumes:
         - "/var/www/my-site.ru:/var/www"                 # файлы сайта
         - "/etc/letsencrypt:/etc/letsencrypt:ro"         # letsEncrypt сертификаты
         - "/var/www/letsencrypt:/var/www/letsencrypt:ro" # ACME челенджи
    
  • Настраиваем nginx для проверки челенджей на отдельный root. Let's Encrypt не ходит по редиректам, поэтому надо настраивать 80 порт
    server {
        listen 80;
        server_name my-site.ru;
    
        location /.well-known/acme-challenge/ {
            root /var/www/letsencrypt;
            allow all;
        }
    
        location / {
            return 301 https://$server_name$request_uri;
        }
    }
    
  • Перезапуск nginx контейнера
    docker compose up -d --no-deps nginx
    
    # пересобрать контейнер nginx при необходимости
    docker compose build nginx
    docker compose up -d --no-deps --force-recreate nginx
    
  • Конфиг для certbot:
    certbot.ini
    email = admin@example.com
    authenticator = webroot
    webroot-path = /var/www/letsencrypt
    domain = my-site.ru
    agree-tos = True
    non-interactive = True
    renew-hook = docker compose -f /opt/my-site.ru/docker-compose.yml exec nginx nginx -s reload
    
  • Запуск обновления сертификата (renew, а не certonly)
    sudo certbot renew
    
  • Автопродление через cron
    17 3 * * * /snap/bin/certbot renew
    

Комментарии

  • У серверов Let’s Encrypt нет постоянных IP, поэтому в фаервол прописывать нечего.
  • wildcard сертификат (то есть сертификат вида *.my-syte.com) можно валидировать только через dns-01.
  • Не обязательно ставить certbot на той машине, для которой нужны сертификаты. Сертификаты можно сгенерировать отдельно, а потом перенести файлы на нужную машину