Загрузка...
Загрузка...
Полная настройка SSL/TLS в Nginx: установка Certbot, server block, HSTS, OCSP stapling, cipher suites, редирект HTTP на HTTPS.
Пошаговое руководство по установке бесплатных SSL-сертификатов Let's Encrypt на Apache и Nginx. Certbot, автообновление, wildcard. Практический гайд для веб-мастеров.
МониторингПрактическое руководство по мониторингу SSL-сертификатов. Автоматические уведомления, настройка проверок, интеграция с CI/CD. Как избежать простоя сайта из-за просроченного сертификата.
БезопасностьВсё о SSL/TLS сертификатах: типы, получение, настройка, обновление. Let's Encrypt, Wildcard, EV-сертификаты. Практическое руководство для веб-разработчиков.
БезопасностьПошаговая настройка HSTS для принудительного HTTPS. max-age, includeSubDomains, preload. Nginx, Apache, Cloudflare. Проверка и отладка.
Поделитесь с коллегами или изучите другие материалы блога
HTTPS — обязательный стандарт для современных сайтов. Nginx в связке с Let's Encrypt позволяет настроить бесплатный SSL за несколько минут. В этой статье — пошаговая настройка: установка Certbot, конфигурация server block, HSTS, OCSP stapling, выбор шифров и редирект HTTP на HTTPS. Проверить корректность SSL можно через SSL Checker на reChecker. Готовые конфиги генерируются в Nginx Generator.
Certbot — официальный клиент EFF для получения сертификатов Let's Encrypt. Поддерживает автоматическую настройку Nginx.
sudo apt update
sudo apt install certbot python3-certbot-nginx
Плагин python3-certbot-nginx позволяет Certbot автоматически изменять конфигурацию Nginx.
sudo dnf install certbot python3-certbot-nginx
Или через EPEL для CentOS 7:
sudo yum install epel-release
sudo yum install certbot python3-certbot-nginx
Актуальная версия через snap:
sudo snap install --classic certbot
sudo ln -s /snap/bin/certbot /usr/bin/certbot
Для Nginx без плагина используйте standalone или webroot-режим.
Certbot читает конфигурацию Nginx и добавляет SSL-блок:
sudo certbot --nginx -d example.com -d www.example.com
Флаги:
-d — домены для сертификата (можно несколько)--nginx — автоматическая настройка Nginx--email your@email.com — email для уведомлений об истечении срокаCertbot создаст или изменит server block, получит сертификат и настроит редирект HTTP → HTTPS.
Если Nginx уже обслуживает сайт и его нельзя останавливать:
sudo certbot certonly --webroot -w /var/www/example.com -d example.com -d www.example.com
Certbot разместит файл в /.well-known/acme-challenge/ для проверки домена. Убедитесь, что Nginx отдаёт эту директорию:
location /.well-known/acme-challenge/ {
root /var/www/example.com;
allow all;
}
Certbot поднимает временный веб-сервер на порту 80. Nginx должен быть остановлен:
sudo systemctl stop nginx
sudo certbot certonly --standalone -d example.com
sudo systemctl start nginx
Let's Encrypt хранит сертификаты в /etc/letsencrypt/live/<domain>/:
| Файл | Назначение |
|---|---|
fullchain.pem | Сертификат + цепочка CA (для Nginx) |
privkey.pem | Приватный ключ |
cert.pem | Только сертификат домена |
chain.pem | Цепочка промежуточных сертификатов |
В конфигурации Nginx используются fullchain.pem и privkey.pem.
Минимальная конфигурация:
server {
listen 443 ssl http2;
listen [::]:443 ssl http2;
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;
root /var/www/example.com;
index index.html;
location / {
try_files $uri $uri/ =404;
}
}
Директива http2 включает HTTP/2 (в Nginx 1.25.1+ используется listen 443 ssl; с отдельным http2 on; в зависимости от версии).
Отдельный server block для порта 80:
server {
listen 80;
listen [::]:80;
server_name example.com www.example.com;
return 301 https://$host$request_uri;
}
Или с сохранением /.well-known для обновления сертификата:
server {
listen 80;
listen [::]:80;
server_name example.com www.example.com;
location /.well-known/acme-challenge/ {
root /var/www/example.com;
allow all;
}
location / {
return 301 https://$host$request_uri;
}
}
HSTS предписывает браузеру всегда использовать HTTPS для домена. Заголовок передаётся только по HTTPS:
add_header Strict-Transport-Security "max-age=31536000; includeSubDomains; preload" always;
Параметры:
max-age=31536000 — 1 годincludeSubDomains — распространить на поддоменыpreload — возможность добавить домен в список preload браузеровВключайте HSTS только после проверки, что весь сайт работает по HTTPS. Ошибка приведёт к тому, что браузер будет отклонять HTTP на указанный срок.
OCSP Stapling позволяет серверу самому получать статус отзыва сертификата и передавать его клиенту. Снижает задержки и нагрузку на CA.
ssl_stapling on;
ssl_stapling_verify on;
ssl_trusted_certificate /etc/letsencrypt/live/example.com/chain.pem;
resolver 8.8.8.8 8.8.4.4 valid=300s;
resolver_timeout 5s;
resolver — DNS-серверы для запросов OCSP. Для Let's Encrypt chain.pem подходит как trusted certificate.
Рекомендуемая конфигурация для TLS 1.2 и 1.3:
ssl_protocols TLSv1.2 TLSv1.3;
ssl_prefer_server_ciphers off;
# TLS 1.3 выбирает шифры сам, для 1.2 — явный список
ssl_ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384;
ssl_prefer_server_ciphers off — в TLS 1.3 порядок шифров задаёт клиент, отключаем устаревшее поведение.
Современный минимальный набор (Mozilla Intermediate):
ssl_ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384;
Сокращение полных TLS-рукопожатий за счёт кэша сессий:
ssl_session_cache shared:SSL:10m;
ssl_session_timeout 1d;
shared:SSL:10m — кэш на 10 МБ, общий для всех worker-процессов. 1d — время жизни сессии 1 день.
Сводный пример:
# HTTP → HTTPS
server {
listen 80;
listen [::]:80;
server_name example.com www.example.com;
location /.well-known/acme-challenge/ {
root /var/www/example.com;
allow all;
}
location / {
return 301 https://$host$request_uri;
}
}
# HTTPS
server {
listen 443 ssl http2;
listen [::]:443 ssl http2;
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;
ssl_trusted_certificate /etc/letsencrypt/live/example.com/chain.pem;
ssl_protocols TLSv1.2 TLSv1.3;
ssl_prefer_server_ciphers off;
ssl_ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384;
ssl_session_cache shared:SSL:10m;
ssl_session_timeout 1d;
ssl_stapling on;
ssl_stapling_verify on;
resolver 8.8.8.8 8.8.4.4 valid=300s;
resolver_timeout 5s;
add_header Strict-Transport-Security "max-age=31536000; includeSubDomains; preload" always;
root /var/www/example.com;
index index.html;
location / {
try_files $uri $uri/ =404;
}
}
Сертификаты Let's Encrypt действуют 90 дней. Certbot настраивает cron или systemd timer для автообновления.
Проверка обновления вручную:
sudo certbot renew --dry-run
Реальное обновление:
sudo certbot renew
Типичный cron (дважды в день):
0 0,12 * * * certbot renew --quiet --post-hook "systemctl reload nginx"
--post-hook перезагружает Nginx после обновления сертификатов.
Let's Encrypt выдаёт wildcard только через DNS- challenge:
sudo certbot certonly --manual --preferred-challenges dns -d example.com -d "*.example.com"
Certbot выведет TXT-запись для _acme-challenge.example.com. Добавьте её в DNS, дождитесь распространения и нажмите Enter. Автоматизация возможна через плагины (cloudflare, route53 и др.).
Один сертификат для нескольких доменов:
sudo certbot --nginx -d example.com -d www.example.com -d blog.example.com -d api.example.com
Все домены будут в одном сертификате (Subject Alternative Names).
Проверка конфигурации Nginx:
sudo nginx -t
Проверка сертификата через OpenSSL:
openssl s_client -connect example.com:443 -servername example.com
Онлайн-проверка: SSL Checker reChecker — срок действия, цепочка, поддерживаемые протоколы.
Пути в ssl_certificate должны вести на реальные файлы. Симлинки в /etc/letsencrypt/live/ указывают на актуальные версии в archive/.
Проверьте resolver и доступность OCSP-сервера. Для Let's Encrypt chain.pem должен быть указан в ssl_trusted_certificate.
После перехода на HTTPS убедитесь, что все ресурсы (скрипты, стили, изображения) загружаются по HTTPS. Иначе браузер блокирует смешанный контент.
Убедитесь, что Nginx собран с --with-http_v2_module. В новых версиях HTTP/2 включается через listen 443 ssl http2;.
Nginx использует ssl_trusted_certificate для OCSP stapling и проверки цепочки. Файл должен содержать корневые и промежуточные сертификаты. Для Let's Encrypt chain.pem подходит. Для кастомных CA может потребоваться объединение:
cat /path/to/your-cert.pem /path/to/intermediate.pem /path/to/root.pem > fullchain.pem
HTTP/2 требует TLS (кроме h2c, который редко поддерживается). В Nginx 1.25.1+ синтаксис:
listen 443 ssl http2;
В более старых версиях:
listen 443 ssl;
http2 on;
Помимо Certbot существуют acme.sh, dehydrated, lego. acme.sh — скрипт на bash, не требует Python:
curl https://get.acme.sh | sh
~/.acme.sh/acme.sh --issue -d example.com -w /var/www/example.com
Конфигурация Nginx задаётся вручную. Certbot с плагином Nginx остаётся самым простым вариантом для автоматической настройки.
Подробнее о конфигурации Nginx — в руководстве по Nginx. О типах сертификатов и выборе CA — в руководстве по SSL-сертификатам.