Acme.sh + Freebsd + Nginx- установка и настройка SSL Letsencrypt

Кому не интересно читать небольшую предысторию, для перехода к установке и настройке жмите сюда.

Некоторое время для выпуска сертификатов Letsencrypt пользовался клиентом acme-client.sh . Но в мае 2019 он был удален из портов и перестал поддерживаться разработчиком, т.к. был включен в OpenBSD. Пользовался я им еще с пол года, хотя это доставляло некоторые неудобства при обновлении портов.

Но момент замены все же настал. В декабре попытался выпустить сертификат, а Letsencrypt сказал хрен тебе с этим клиентом, а не сертификат для нового домена, только перевыпуск для старых…. Обновляйся!

Ну что же, ладно. Иду на Letsencrypt и смотрю кто там требует минимум доп зависимостей. Оказалось на bash есть 4 клиента:

  • GetSSL
  • acme.sh
  • dehydrated
  • ght-acme.sh

dehydrated мне был уже знаком, начну думаю с него. Установил из портов, начинаю настраивать сертификаты… И тут бац:

# INFO: Using main config file /usr/local/etc/dehydrated/config
ERROR: DEHYDRATED_USER set but sudo not available. Please install sudo.
gold,pts,/usr/local/etc/dehydrated,6$id
uid=443(_letsencrypt) gid=443(_letsencrypt) groups=443(_letsencrypt)
gold,pts,/usr/local/etc/dehydrated,7$grep DEHYDRATED_USER /usr/local/etc/dehydrated/config
DEHYDRATED_USER=_letsencrypt

sudo не установлен и не хочу. С рута заводить его не хочется… :/
На GitHub есть репорт по этой проблеме еще с 20.08.2019. Разработчик обещал пофиксить, но на сегодняшний момент так этого и не сделал. Ладно, раз ты такой скоростной идем дальше.

Дальше думаю возьму acme.sh …

Установка Acme.sh

Ладно, хватит лирики. Поехали.

Клиент будет работать без рута, от юзера acme. Папка с сертификатами и конфигами тут: /var/db/acme/. (Добавляются по дефолту при установке)


# cd /usr/ports/security/acme.sh
# make config
# make install clean

Создаем необходимые папки: 1-я для проверки Letsencrypt на принадлежность домена; 2-я для сертификатов. И устанавливаем им права.


# mkdir /usr/local/www/acme-ssl
# chown acme:www  /usr/local/www/acme-ssl

# mkdir /usr/local/etc/nginx/ssl
# chown acme:www  /usr/local/etc/nginx/ssl

Создадим общий конфиг для всех доменов:


# cd /usr/local/etc/nginx/conf.d
# touch acme-ssl.conf

Далее любимым редактором в файл acme-ssl.conf пишем:


location ^~ /.well-known/acme-challenge/ {
    default_type "text/plain";
    alias /usr/local/www/acme-ssl/.well-known/acme-challenge/;
    try_files $uri =404;
}

Перед выпуском сертификата добавляем в конфиг nginx для домена:


server {
  ...
  include /usr/local/etc/nginx/conf.d/acme-ssl.conf
  ...
}

Не забываем перезагрузить конфиги:

# service nginx reload

Выпуск и установка сертификата

#  su acme -c "acme.sh --issue -d zajtcev.org  -w /usr/local/www/acme-ssl"

Выпуск сертификата для нескольких поддоменов в одном сертификате:

#  su acme -c "acme.sh --issue -d zajtcev.org -d www.zajtcev.org -d cp.zajtcev.org -w /usr/local/www/acme-ssl"

Для выпуска использую webroot. Если захотите wildcard сертификат, тогда только dns-01

Создаем папку для сертификатов:

# mkdir /usr/local/etc/nginx/ssl/zajtcev.org
# chown acme:www  /usr/local/etc/nginx/ssl/zajtcev.org

Устанавливаем сертификаты, в заранее созданную папку:

#  su acme -c 'acme.sh --install-cert -d zajtcev.org --key-file  /usr/local/etc/nginx/ssl/zajtcev.org/privkey.pem --ca-file  /usr/local/etc/nginx/ssl/zajtcev.org/chain.pem --cert-file  /usr/local/etc/nginx/ssl/zajtcev.org/cert.pem --fullchain-file  /usr/local/etc/nginx/ssl/zajtcev.org/fullchain.pem --reloadcmd  "touch /var/db/acme/.restart_nginx"'

Сертификаты будут скопированы в папку для nginx и эти пути будут прописаны в конфигах для последующих обновлений.

Отдельно стоит отметить —reloadcmd. Но к этому вернемся чуть ниже.

Далее пропишем сертификаты в nginx.

server {
...
    listen      443 ssl http2;
    listen [::]:443 ssl http2;
	
    ssl_certificate /usr/local/etc/nginx/ssl/zajtcev.org/fullchain.pem;
    ssl_certificate_key /usr/local/etc/nginx/ssl/zajtcev.org/privkey.pem;
    ssl_trusted_certificate /usr/local/etc/nginx/ssl/zajtcev.org/fullchain.pem;
...
}

Ну и конечно же проверяем и применяем конфиги nginx:

# service nginx configtest
# service nginx reload

Если до этого момента ошибок не возникло, Поздравляю! Сертификаты установлены и сайт даже возможно уже работает по https. :)
Осталось дело за малым — настроить автоматический перевыпуск сертификатов. Поехали.

Перевыпуск сертификатов —cron

Теперь вернемся к -reloadcmd.
Т.к. клиент будет работать от юзера acme, а не от рута, то он не сможет перезагрузить nginx.
Сначала пытался разобраться с кодами ответов при проверке/обновлении сертификатов, но вне зависимости от обновления сертификатов или нет, он постоянно отвечал 0.
На форуме freebsd один пользователь подсказал идею с файлом. Т.е. если обновится сертификат будет создан файл .restart_nginx. А мы уже от рута будем проверять есть ли этот файл или нет и перегружать nginx.

# touch /home/scripts/acme_deploy.sh

Ну и сам простенький код:

#!/bin/sh

set -e

if [ -f /var/db/acme/.restart_nginx ]; then
  service nginx reload
  rm -rf /var/db/acme/.restart_nginx
fi

Теперь Добавим в крон обновление сертификатов для юзера acme

# su acme
# crontab -e
#minute hour    mday    month   wday    command
10 05 * * * /usr/local/sbin/acme.sh --cron --home "/var/db/acme/.acme.sh"

Возвращаемся к руту

#exit

Теперь для рута добавим задание

# crontab -e
#minute hour    mday    month   wday    who command
15   05   *   *   *       /bin/sh /home/scripts/acme_deploy.sh

Выше я проверяю сертификаты в 05:10 и в 05:15 проверяю наличие файла для применения сертификатов каждый день. Но сейчас подумываю делать это раз в неделю, как было у меня раньше.

И так, Практически готово. Осталось добавить ротацию логов и все.

# ee /usr/local/etc/newsyslog.conf.d/newsyslog.conf
/var/log/acme.sh.log  acme:acme       640  90    *    @T00   BC

Ну Вот вроде и все. :)

Послесловие

Для расширенного просмотра ответов acme.sh добавляйте —debug

Ручное обновление сертификата для одного домена:

# su acme -c "acme.sh --renew -d zajtcev.org --force"

Ручное обновление сертификатов для всех доменов:

# su acme -c "acme.sh --renew-all  --force "

Если установите /usr/sbin/nologin для юзера acme, тогда все команды su делаем с -m модификатором и прописываем пути для home и log. Пример:

#  su -m acme -c "acme.sh --issue -d zajtcev.org  --home /var/db/acme/certs -w /usr/local/www/acme-ssl --log /var/log/acme.sh.log"

PS. Если что-то упустил или столкнулись с трудностью пишите в комментах.

Запись опубликована в рубрике: Заметки о FreeBSD.

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *

Комментарии