Предусловия
Нужен сервер с Ubuntu/Debian, доменное имя, DNS A-запись которого уже смотрит на IP сервера. Без последнего certbot не получит сертификат — проверка идёт по HTTP на 80-м порту. Если DNS ещё не обновился, подождите — смысла идти дальше нет.
Установка nginx и certbot
apt update && apt install -y nginx certbot python3-certbot-nginx
После установки nginx автоматически запускается. Проверяем:
systemctl status nginx
# Должно быть: active (running)
# Если не запущен:
systemctl start nginx
systemctl enable nginx
Конфиг для статического сайта
Создаём конфиг в /etc/nginx/sites-available/example.com:
server {
listen 80;
server_name example.com www.example.com;
root /var/www/example.com;
index index.html;
# Статические файлы
location / {
try_files $uri $uri/ $uri.html =404;
}
# Кэширование статики
location ~* \.(css|js|png|jpg|jpeg|svg|ico|woff2)$ {
expires 30d;
add_header Cache-Control "public, immutable";
}
# Запрет лишнего
location ~ /\. { deny all; }
# Gzip
gzip on;
gzip_types text/plain text/css application/javascript application/json image/svg+xml;
gzip_min_length 1024;
}
Включаем сайт и проверяем конфиг:
ln -s /etc/nginx/sites-available/example.com /etc/nginx/sites-enabled/
nginx -t
# nginx: configuration file /etc/nginx/nginx.conf test is successful
systemctl reload nginx
Получение SSL-сертификата
certbot --nginx -d example.com -d www.example.com
Certbot сам найдёт конфиг, проверит домен, получит сертификат и пропишет HTTPS-блок. Единственный вопрос — нужно ли перенаправлять HTTP на HTTPS (выбираем «да»). После этого конфиг выглядит примерно так:
server {
listen 80;
server_name example.com www.example.com;
return 301 https://$host$request_uri;
}
server {
listen 443 ssl;
server_name example.com www.example.com;
ssl_certificate /etc/letsencrypt/live/example.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/example.com/privkey.pem;
include /etc/letsencrypt/options-ssl-nginx.conf;
ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem;
root /var/www/example.com;
index index.html;
location / {
try_files $uri $uri/ $uri.html =404;
}
# ... остальные location
}
Конфиг для reverse proxy
Если за nginx стоит приложение (FastAPI, Node, Gunicorn и т.д.) на каком-то порту:
upstream app {
server 127.0.0.1:8000;
# Можно добавить несколько серверов для балансировки
}
server {
listen 443 ssl;
server_name api.example.com;
ssl_certificate /etc/letsencrypt/live/api.example.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/api.example.com/privkey.pem;
include /etc/letsencrypt/options-ssl-nginx.conf;
location / {
proxy_pass http://app;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
# Для WebSocket:
# proxy_http_version 1.1;
# proxy_set_header Upgrade $http_upgrade;
# proxy_set_header Connection "upgrade";
# Таймауты
proxy_connect_timeout 60s;
proxy_read_timeout 60s;
}
}
Автообновление сертификата
Certbot при установке добавляет systemd timer или cron задачу автоматически. Проверяем:
# Проверить таймер systemd
systemctl status certbot.timer
# Или проверить cron
cat /etc/cron.d/certbot
# Тест обновления (без реального обновления)
certbot renew --dry-run
Если dry-run прошёл без ошибок — всё настроено. Сертификаты обновляются автоматически за 30 дней до истечения. Следить не нужно.
Полезные команды
# Список сертификатов
certbot certificates
# Принудительное обновление
certbot renew --force-renewal
# Проверить конфиг nginx
nginx -t
# Перезагрузить nginx без прерывания соединений
nginx -s reload
# или
systemctl reload nginx
# Посмотреть ошибки
tail -n 50 /var/log/nginx/error.log
# Посмотреть access log
tail -f /var/log/nginx/access.log
Быстрый security-минимум
Что стоит добавить в конфиг для базовой безопасности:
server {
# ...
# Скрыть версию nginx
server_tokens off;
# Security headers
add_header X-Content-Type-Options "nosniff" always;
add_header X-Frame-Options "SAMEORIGIN" always;
add_header Referrer-Policy "strict-origin-when-cross-origin" always;
add_header Permissions-Policy "geolocation=(), microphone=()" always;
# Ограничение размера тела запроса
client_max_body_size 10M;
# Rate limiting (определить в http блоке)
# limit_req zone=one burst=10 nodelay;
}
Rate limiting определяется в /etc/nginx/nginx.conf внутри блока http:
http {
limit_req_zone $binary_remote_addr zone=one:10m rate=10r/s;
# ...
}
Итог
Весь процесс с чистого сервера до работающего HTTPS занимает 10–15 минут, если DNS уже настроен. Certbot берёт на себя всё, что связано с сертификатами и их обновлением. Nginx конфиг для большинства задач не нужно усложнять — показанные блоки покрывают 95% случаев.