Linux-сервер

Бесплатный SSL сертификат без панели: Certbot, acme.sh, wildcard через Cloudflare DNS

7 шагов 16 мин чтения 81 просмотров 0
Содержание

Для HTTPS не нужна панель управления. С помощью Certbot или acme.sh можно получить бесплатные сертификаты Let's Encrypt для любого сайта на Nginx, выпустить wildcard-сертификат вида *.example.com через Cloudflare DNS API и настроить автоматическое продление. В статье: оба инструмента на Debian/Ubuntu и Rocky Linux/AlmaLinux, настройка HTTPS в Nginx, сайты за прокси Cloudflare и проверка того, что продление действительно работает.

Сертификаты Let's Encrypt действуют 90 дней, а с 2025 года Let's Encrypt больше не присылает письма с напоминанием об истечении срока. После настройки обязательно проверьте автопродление пробным запуском (dry run), иначе сайт без всякого предупреждения перестанет открываться, когда сертификат истечёт.

Перед началом

  • A-запись домена (и AAAA-запись, если используете IPv6) указывает на IP вашего сервера. Проверьте командой dig +short example.com.
  • Порты 80 и 443 открыты в файрволе сервера (см. открытие портов в firewalld и ufw).
  • Nginx установлен и уже отдаёт сайт по HTTP.

Вариант A: Certbot с плагином Nginx (самый простой)

Certbot умеет сам запросить сертификат и отредактировать server-блок Nginx, включая редирект с HTTP на HTTPS.

# Debian / Ubuntu
apt update
apt install -y certbot python3-certbot-nginx

# Rocky Linux / AlmaLinux (EPEL)
dnf install -y epel-release
dnf install -y certbot python3-certbot-nginx

# Request and install a certificate for the domain and www
certbot --nginx -d example.com -d www.example.com \
  --agree-tos -m [email protected] --redirect

# Renewal is scheduled automatically; confirm the timer and run a test renewal
systemctl list-timers | grep -i certbot
certbot renew --dry-run

Сертификаты хранятся в /etc/letsencrypt/live/example.com/. Если не хотите, чтобы Certbot менял файл конфигурации Nginx, используйте certbot certonly --nginx -d example.com и пропишите пути к сертификату сами, как показано ниже в разделе о настройке HTTPS в Nginx.

Вариант B: acme.sh (лёгкий, без Python)

acme.sh — это один shell-скрипт, который запускается по cron. Учтите, что по умолчанию он использует удостоверяющий центр ZeroSSL; при желании переключите его на Let's Encrypt.

# Install (creates ~/.acme.sh and a daily cron job)
curl https://get.acme.sh | sh -s [email protected]
source ~/.bashrc

# Use Let's Encrypt as the default CA
acme.sh --set-default-ca --server letsencrypt

# Issue using your site's web root (HTTP-01 validation)
acme.sh --issue -d example.com -d www.example.com -w /var/www/example

# Install the certificate where Nginx expects it and reload Nginx on every renewal
mkdir -p /etc/nginx/ssl
acme.sh --install-cert -d example.com \
  --key-file       /etc/nginx/ssl/example.com.key \
  --fullchain-file /etc/nginx/ssl/example.com.crt \
  --reloadcmd      "systemctl reload nginx"

Никогда не указывайте в Nginx файлы прямо из ~/.acme.sh; всегда используйте --install-cert — эта команда копирует файлы и выполняет команду перезагрузки после каждого продления.

Wildcard-сертификаты через Cloudflare DNS API

Для wildcard-сертификатов (*.example.com) нужна проверка через DNS. Если домен обслуживается в Cloudflare DNS, создайте API-токен в панели Cloudflare в разделе My Profile → API Tokens по шаблону «Edit zone DNS» с доступом только к нужной зоне.

# acme.sh: dns_cf reads the token from the environment and saves it for renewals
export CF_Token="your-cloudflare-api-token"
export CF_Zone_ID="your-zone-id"        # shown on the domain's Overview page in Cloudflare
acme.sh --issue --dns dns_cf -d example.com -d '*.example.com'

# Certbot alternative
apt install -y python3-certbot-dns-cloudflare
mkdir -p ~/.secrets && chmod 700 ~/.secrets
echo 'dns_cloudflare_api_token = your-cloudflare-api-token' > ~/.secrets/cloudflare.ini
chmod 600 ~/.secrets/cloudflare.ini
certbot certonly --dns-cloudflare \
  --dns-cloudflare-credentials ~/.secrets/cloudflare.ini \
  -d example.com -d '*.example.com'

Проверка через DNS работает, даже если порт 80 закрыт или сайт ещё недоступен, поэтому она удобна для внутренних сервисов и новых серверов.

Настройка HTTPS в Nginx

Если сертификат выпущен через certonly или acme.sh, добавьте HTTPS server-блок вручную. Пути к сертификату укажите в соответствии с использованным инструментом.

server {
    listen 80;
    listen [::]:80;
    server_name example.com www.example.com;
    return 301 https://$host$request_uri;
}

server {
    listen 443 ssl;
    listen [::]:443 ssl;
    http2 on;                      # Nginx 1.25.1+; older versions: "listen 443 ssl http2;"
    server_name example.com www.example.com;

    ssl_certificate     /etc/letsencrypt/live/example.com/fullchain.pem;   # acme.sh: /etc/nginx/ssl/example.com.crt
    ssl_certificate_key /etc/letsencrypt/live/example.com/privkey.pem;     # acme.sh: /etc/nginx/ssl/example.com.key
    ssl_protocols TLSv1.2 TLSv1.3;
    ssl_session_cache shared:SSL:10m;

    root /var/www/example;
    index index.html index.php;
}
nginx -t && systemctl reload nginx

Сайты за прокси Cloudflare

При включённом проксировании (оранжевое облако) проверка по HTTP обычно всё равно проходит, потому что Cloudflare пересылает запросы к /.well-known/acme-challenge/ на ваш сервер. Когда на origin-сервере появится действительный сертификат, установите в Cloudflare режим SSL/TLS Full (strict); режим «Flexible» передаёт трафик на ваш сервер без шифрования и часто приводит к циклическим редиректам. Можно также использовать проверку через DNS или бесплатный Cloudflare Origin Certificate, если сайт всегда открывается только через Cloudflare. Чтобы посетители не могли обойти Cloudflare, см. как скрыть IP origin-сервера.

Проверка срока действия и продления

# Expiry date of the certificate your site actually serves
echo | openssl s_client -connect example.com:443 -servername example.com 2>/dev/null | openssl x509 -noout -dates

# Certbot: all certificates and their expiry
certbot certificates

# acme.sh: list certificates and force a test renewal
acme.sh --list
acme.sh --renew -d example.com --force

Частые вопросы

Проверка завершается ошибкой «Timeout during connect» или 404

Порт 80 заблокирован, DNS-запись указывает на другой адрес или на домен отвечает другой server-блок. Проверьте файрвол, выполните dig +short example.com и убедитесь, что /.well-known/acme-challenge/ не перенаправляется и не запрещён в конфигурации Nginx. Если это не помогает, перейдите на проверку через DNS.

Во время тестов я упёрся в лимит запросов

Let's Encrypt ограничивает число сертификатов, которые можно выпустить для одних и тех же доменных имён за неделю. Пока экспериментируете, используйте --dry-run (Certbot) или --staging (acme.sh) и запрашивайте настоящий сертификат только после того, как всё заработает.

Можно ли использовать один сертификат для нескольких доменов?

Да. Добавьте каждое имя отдельной опцией -d. Wildcard покрывает только один уровень: *.example.com подходит для shop.example.com, но не для a.shop.example.com и не для самого example.com; основной домен добавьте отдельно.

Если проблема не решена, создайте тикет — техническая поддержка IMIDC работает 24/7. Укажите IP сервера, версию ОС, ваш домен, выполненную команду и полный текст ошибки, чтобы мы быстрее нашли причину.

Помог ли вам данный ответ?

Похожие руководства