certbot тянет за собой интерпретатор Python и набор pip-пакетов — на обычном сервере это не проблема, но на урезанном образе, роутере с OpenWRT или в минимальном Docker-контейнере без python3 установка такого клиента превращается в отдельный квест. acme.sh написан целиком на POSIX shell — работает под bash, dash, busybox ash, не требует ничего, кроме curl или wget и стандартных утилит, которые есть почти в любом дистрибутиве по умолчанию.

Устанавливается сам в ~/.acme.sh одной командой и не требует root:

curl https://get.acme.sh | sh -s email=my@example.com

Выпуск сертификата через DNS-01 (acme.sh поддерживает больше 180 DNS-провайдеров под этот режим) не требует даже открытого 80/443 порта наружу:

~/.acme.sh/acme.sh --issue --dns dns_cf -d example.com -d '*.example.com'

а установка в целевые пути с перезагрузкой сервиса — отдельным шагом, который можно переиспользовать при каждом продлении:

~/.acme.sh/acme.sh --install-cert -d example.com \
  --cert-file /etc/nginx/ssl/example.com.crt \
  --key-file /etc/nginx/ssl/example.com.key \
  --reloadcmd "systemctl reload nginx"

При установке acme.sh сам прописывает себе cron-задачу (--install-cronjob), которая раз в день дёргает --cron и тихо продлевает сертификаты, которым пора. В духе CLAUDE.md-привычки предпочитать systemd timer cron’у — ничто не мешает вынести этот же вызов в .service/.timer пару вместо строки в crontab -l, acme.sh никак не привязан к механизму планировщика, ему важен только сам факт регулярного запуска --cron.

Отдельный плюс чистого shell-скрипта — его тривиально прочитать целиком и понять, что он делает, прежде чем доверить ему приватный ключ: никакой скрытой логики за слоями абстракций виртуального окружения Python, один файл с понятным потоком выполнения.

#linux #nginx #security