Let’s Encrypt придумали, чтобы народ не парился с SSL. Бесплатно, автоматом и без этого цирка с ручным подписыванием ключей у «уважаемых» регистраторов, которые любят трясти с тебя бабло за пару килобайт текста.
Но бесплатное — не значит «магия». Если всё сделать по учебнику, оно, конечно, заведётся, но учебники обычно пишут люди, которые ни разу не ловили обрывы коннекта в момент валидации или не дебажили nginx в проде.
Так что давай по чесноку: как это на самом деле ставится, на что ты наступишь и как из этого вылезти.

1. Что тебе нужно до старта

Без лишнего «подготовьте окружение», просто чеклист:

  • Домен, который смотрит на твой реальный публичный IP (не на 127.0.0.1, не на твой NAT за роутером).
  • Уже работающий nginx (а не «кажется, я его поставил»).
  • Серверный блок (vhost) для домена — не этот дефолтный мусор из /etc/nginx/sites-enabled/default.

Если чего-то нет — ставь и настраивай, иначе дальше будет трата времени.

2. Ставим certbot

Ubuntu 18.04 знает про certbot из коробки, так что без PPA и прочего шаманства:

sudo apt update
sudo apt install certbot

Всё. Никаких «а может snap?» — забудь, snap тут как чемодан без ручки.

3. Ключи Диффи-Хеллмана

Да, эти ключи — не про шифрование файлов «чтобы никто не прочитал любовное письмо». Это про то, чтобы у твоего SSL не было дыр, в которые влезет школьник с Kali Linux. Генерим и забываем:

sudo openssl dhparam -out /etc/ssl/certs/dhparam.pem 2048

На слабых VPS может крутиться пару минут. Терпи.

4. Проверка домена: webroot

Let’s Encrypt надо убедиться, что ты реально владеешь доменом. Для этого certbot создаёт временный файл, а их сервера лезут к тебе по HTTP.
Делаем отдельную папку:

sudo mkdir -p /var/lib/letsencrypt/.well-known
sudo chgrp www-data /var/lib/letsencrypt
sudo chmod g+s /var/lib/letsencrypt

Дальше — фрагмент letsencrypt.conf в nginx, чтобы не копипастить в каждый конфиг:

location ^~ /.well-known/acme-challenge/ {
  allow all;
  root /var/lib/letsencrypt/;
  default_type "text/plain";
  try_files $uri =404;
}

И ssl.conf — чтобы сразу с нормальными шифрами и HSTS, а не «TLSv1.0 из 2006-го».

(Да, сюда можно вставить готовый набор из Mozilla, а не выдумывать свой.)

5. Втыкаем в конфиг nginx

HTTP-блок для валидации:

server {
  listen 80;
  server_name example.com www.example.com;
  include snippets/letsencrypt.conf;
}

Симлинк в sites-enabled и перезапуск nginx:

sudo ln -s /etc/nginx/sites-available/example.com.conf /etc/nginx/sites-enabled/
sudo systemctl restart nginx

6. Берём сертификат

sudo certbot certonly --agree-tos --email admin@example.com \
  --webroot -w /var/lib/letsencrypt/ \
  -d example.com -d www.example.com

Если всё норм — certbot скажет, куда кинул ключи и цепочку. Если нет — читай ошибку. Часто это:

  • DNS ещё не обновился (только что домен привязал? подожди).
  • nginx слушает не тот порт или другой сервер блок его перехватывает.

7. Принудительный HTTPS

HTTP → HTTPS, www → без www (или наоборот, если ты из этих):

server {
    listen 80;
    server_name www.example.com example.com;
    include snippets/letsencrypt.conf;
    return 301 https://$host$request_uri;
}

443-блоки — с ssl_certificate, ssl_certificate_key, ssl_trusted_certificate и включённым ssl.conf.

8. Автопродление

Сертификаты живут 90 дней. Certbot ставит cronjob, который обновляет их заранее. Но nginx перезагружать он сам не будет — добавь --renew-hook "systemctl reload nginx".

Cron-файл:

0 */12 * * * root certbot -q renew --renew-hook "systemctl reload nginx" 

Проверка:

sudo certbot renew --dry-run

Если молчит — значит, всё живо.

9. Финал

Теперь у тебя нормальный HTTPS без «небезопасного соединения». И да, это всё бесплатно. Но не забывай:

  • Обновления ОС и nginx — не реже, чем сертификаты.
  • Let’s Encrypt иногда меняет требования — читай changelog, чтобы потом не чесать репу, почему упало.