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

Остальную защиту сервера смотрите в hardening Linux, а ограничение доступа к портам в статье про firewall.
Нужен рабочий HTTPS на nginx: сертификат, ключ, TLS 1.2/1.3 и проверка, что 443 отвечает нужным именем. Рейтинг A+ — побочный эффект, не цель.
Что нужно заранее
- Имя, которое совпадает с сертификатом. Для нескольких имён на одном IP нужен SNI:
nginx -V 2>&1 | grep -i sniдолжно сказать, что SNI включён. - Кто выпускает сертификат: Let’s Encrypt, коммерческий УЦ или свой УЦ. Не StartSSL.
- Консоль или второй вход. Ошибочный reload на единственном 443 без консоли отрежет вас от сайта.
1. Сертификат и ключ
Публичный сайт — обычный путь Let’s Encrypt. На Debian/Ubuntu:
sudo apt update
sudo apt install -y certbot python3-certbot-nginx
sudo certbot --nginx -d www.example.com
Плагин сам правит server-блок. Если хотите файлы вручную:
sudo certbot certonly --webroot -w /var/www/html -d www.example.com
sudo ls -l /etc/letsencrypt/live/www.example.com/
Ожидание: fullchain.pem и privkey.pem. Ключ — не в git и не world-readable. Документация nginx: сертификат публичный, ключ читает только master-процесс.
Если УЦ дал серверный сертификат и bundle отдельно, склейте в правильном порядке — сначала ваш сертификат, потом цепочка:
cat www.example.com.crt bundle.crt > www.example.com.chained.crt
Обратный порядок nginx не поднимет: в логе будет mismatch ключа и сертификата.
2. Минимальный server
server {
listen 443 ssl;
server_name www.example.com;
ssl_certificate /etc/letsencrypt/live/www.example.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/www.example.com/privkey.pem;
ssl_protocols TLSv1.2 TLSv1.3;
ssl_ciphers HIGH:!aNULL:!MD5;
}
С 1.27.3 умолчания модуля — TLSv1.2 TLSv1.3 и HIGH:!aNULL:!MD5, если сборка и OpenSSL это умеют. На старых пакетах умолчания шире и могут включать TLS 1.0/1.1 — протоколы лучше прописать явно. Не копируйте из архивных сниппетов nginx.org строки с RC4 и 3DES: это иллюстрация синтаксиса, не рекомендация 2026 года.
Наборы шифров — в Mozilla SSL Configuration Generator; жёсткий nginx — в CIS Benchmarks. Защита канала в NIST SP 800-53 — SC-8 / SC-13, это не замена вашего конфига.
HTTP/2: в nginx 1.25.1+ это отдельная директива http2 on;, в более старых — параметр listen 443 ssl http2. Смотрите man своей сборки, не смешивайте оба синтаксиса.
Два имени на одном IP (официальный приём — SNI, отдельные server):
server {
listen 443 ssl;
server_name www.example.com;
ssl_certificate /etc/letsencrypt/live/www.example.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/www.example.com/privkey.pem;
}
server {
listen 443 ssl;
server_name www.example.org;
ssl_certificate /etc/letsencrypt/live/www.example.org/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/www.example.org/privkey.pem;
}
Без SNI клиент получит сертификат сайта по умолчанию — первого server в конфиге. Сессии между воркерами, если ядер несколько:
ssl_session_cache shared:SSL:10m;
ssl_session_timeout 10m;
3. Проверить конфиг и перечитать
sudo nginx -t
sudo systemctl reload nginx
Пример удачного nginx -t:
nginx: the configuration file /etc/nginx/nginx.conf syntax is ok
nginx: configuration file /etc/nginx/nginx.conf test is successful
Ключ не читается — обычно SSL_CTX_use_PrivateKey_file и права на privkey.pem. Reload, не restart, если уже есть живой трафик. Не отключайте 80 и 443 одновременно на машине без консоли.
4. Редирект и HSTS
Постоянный 80 → 443 включайте, когда HTTP больше не нужен клиентам и мониторингу.
server {
listen 80;
server_name www.example.com;
return 301 https://$host$request_uri;
}
Снова nginx -t и reload. HSTS (Strict-Transport-Security) — отдельное решение. Пока имя, сертификат или смешанный HTTP не устоялись, длинный max-age не ставьте: у клиентов его сложно «отменить».
Как проверить
ss -lntup | grep -E ':443s'
echo | openssl s_client -connect www.example.com:443 -servername www.example.com 2>/dev/null | openssl x509 -noout -dates -subject
echo | openssl s_client -connect www.example.com:443 -servername www.example.com -tls1_1 2>&1 | head
sudo certbot renew --dry-run
Пример куска openssl x509:
notBefore=Oct 1 00:00:00 2026 GMT
notAfter=Dec 30 00:00:00 2026 GMT
subject=CN = www.example.com
Ожидание: 443 слушает nginx; имя совпадает; срок не истёк. TLS 1.1 при закрытых протоколах обычно заканчивается sslv3 alert handshake failure или no protocols available. renew --dry-run — только если сертификат выпускал certbot. SSL Labs и testssl.sh — дополнительная проверка своих хостов, не приёмка сами по себе.
Откат
Верните предыдущий файл из sites-available, nginx -t, reload. Ключ и сертификат не удаляйте, пока новый вход по HTTPS не подтверждён.
Источники
- nginx, Configuring HTTPS servers. URL: https://nginx.org/en/docs/http/configuring_https_servers.html.
- nginx, Module ngx_http_ssl_module. URL: https://nginx.org/en/docs/http/ngx_http_ssl_module.html.
- Certbot. URL: https://eff-certbot.readthedocs.io/en/stable/.
- Mozilla SSL Configuration Generator. URL: https://wiki.mozilla.org/Security/Server_Side_TLS.
- CIS Benchmarks. URL: https://www.cisecurity.org/cis-benchmarks.


















