Let’s Encrypt крут, а вот официальный клиент настолько ужасен, что уже появилось огромное количество альтернативных решений.
Для своих проектов я выбрал acme-tiny и написал инструкцию как автоматизировать перевыпуск сертификатов каждый месяц.
Установка и настройка клиента letsencrypt
-
Создаем пользователя
letsencrypt
и необходимые директории:adduser --home /var/www/challenges \ --shell /bin/sh \ --disabled-password \ --disabled-login \ letsencrypt mkdir -p /etc/letsencrypt/domains
-
Добавляем пользователя
letsencrypt
в sudoers для перезагрузки nginx:visudo -f /etc/sudoers.d/letsencrypt letsencrypt ALL=(ALL) NOPASSWD: /usr/sbin/service nginx reload
-
Генерим основные приватные ключи:
cd /etc/letsencrypt/ openssl dhparam -out dhparam.pem 2048 openssl genrsa 4096 > account.key
-
Скачиваем клиент acme_tiny.py:
cd /var/www/challenges wget https://raw.githubusercontent.com/diafygi/acme-tiny/master/acme_tiny.py
-
Создаем скрипт
/var/www/challenges/acme-tiny.sh
, для автоматизации. Изменив переменнуюDOMAINS
добавляем имена доменов, которым необходимы сертификаты:DOMAINS=( example.com foobar.com ) DOMAIN_ROOT=/etc/letsencrypt/domains ACCOUNT_KEY=/etc/letsencrypt/account.key ACME_DIR=/var/www/challenges ACME_TINY=${ACME_DIR}/acme_tiny.py [ -d ${DOMAIN_ROOT} ] || { echo "ERROR: DOMAIN_ROOT dir does not exists"; exit 1; } [ -f ${ACCOUNT_KEY} ] || { echo "ERROR: ACCOUNT_KEY not found."; exit 1; } [ -d ${ACME_DIR} ] || { echo "ERROR: ACME_DIR dir does not exists"; exit 1; } [ -f "$ACME_TINY" ] || { echo "ERROR: ACME_TINY not found."; exit 1; } wget -O - https://letsencrypt.org/certs/lets-encrypt-x3-cross-signed.pem > ${DOMAIN_ROOT}/intermediate.pem for DOMAIN in "${DOMAINS[@]}" do if [ ! -f "${DOMAIN_ROOT}/${DOMAIN}.key" ]; then echo "INFO: Generation private key for $DOMAIN"; openssl genrsa 4096 > ${DOMAIN_ROOT}/${DOMAIN}.key openssl req -new -sha256 -key ${DOMAIN_ROOT}/${DOMAIN}.key -subj "/CN=${DOMAIN}" > ${DOMAIN_ROOT}/${DOMAIN}.csr fi echo "INFO: Generation cert for $DOMAIN"; python ${ACME_TINY} --account-key ${ACCOUNT_KEY} --csr ${DOMAIN_ROOT}/${DOMAIN}.csr --acme-dir ${ACME_DIR} > ${DOMAIN_ROOT}/${DOMAIN}.crt || exit 1 cat ${DOMAIN_ROOT}/${DOMAIN}.crt ${DOMAIN_ROOT}/intermediate.pem > ${DOMAIN_ROOT}/${DOMAIN}.pem done sudo service nginx reload
-
Устанавливаем права:
chmod 700 /etc/letsencrypt chown -R letsencrypt: /etc/letsencrypt /var/www/challenges
-
Добавляем
location
в nginx у всех доменов, которым необходимо получать сертификат:location /.well-known/acme-challenge/ { alias /var/www/challenges/; try_files $uri =404; }
-
Запускаем:
su -c 'umask 033; /bin/bash /var/www/challenges/acme-tiny.sh' letsencrypt
Настройка автоматического продления
-
Создаем log файл:
sudo touch /var/log/acme_tiny.log sudo chown letsencrypt: /var/log/acme_tiny.log
-
Добавляем ежемесячную работу в crontab:
nano /etc/cron.d/letsencrypt SHELL=/bin/sh PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin 0 0 1 * * letsencrypt /bin/bash /var/www/challenges/acme-tiny.sh >> /var/log/acme_tiny.log
Получаем класс А в Nginx
server {
listen 443;
server_name example.com;
...
ssl on;
ssl_certificate /etc/letsencrypt/domains/example.com.pem;
ssl_certificate_key /etc/letsencrypt/domains/example.com.key;
ssl_session_timeout 5m;
ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
ssl_ciphers ECDHE-RSA-AES256-GCM-SHA384:ECDHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-SHA384:ECDHE-RSA-AES128-SHA256:ECDHE-RSA-AES256-SHA:ECDHE-RSA-AES128-SHA:DHE-RSA-AES256-SHA:DHE-RSA-AES128-SHA;
ssl_session_cache shared:SSL:50m;
ssl_dhparam /etc/letsencrypt/dhparam.pem;
ssl_prefer_server_ciphers on;
...
}