Если обратиться к Nginx-серверу по IP-адресу, а не по доменному имени, то обычно откроется либо первый virtual host в конфиге, либо тот, где указан default_server в listen. Чаще всего показывать что-то реальное на таком запросе не хочется, поэтому на IP обычно вешают заглушку.
▪️ Для HTTP это решается просто:
server {
listen 80 default_server;
server_name _;
return 404;
}
С обычным HTTP все понятно.
▪️ С HTTPS начинается самое интересное.. Если клиент приходит на сервер по IP через HTTPS, Nginx все равно должен отдать какой-то сертификат. И если отдельный сертификат для такого случая не задан, будет использован сертификат одного из виртуальных хостов. То есть конфиг вроде такого:
server {
listen 443 ssl default_server;
server_name _;
return 404;
}
не решает проблему полностью.
Что увидит пользователь: сначала предупреждение браузера о том, что сертификат не соответствует адресу, а потом, если продолжить, в сертификате можно будет увидеть домен реального сайта
Получается, что даже заглушка на IP все равно может засветить боевой домен.
▪️ Один из старых и рабочих вариантов - использовать самоподписанный сертификат-пустышку.. Создаем его так:
openssl req -x509 -nodes -days 3650 -newkey rsa:2048 \
-keyout /etc/nginx/certs/nginx.key \
-out /etc/nginx/certs/nginx.crt
И подключаем в default server:
server {
listen 443 ssl default_server;
server_name _;
ssl_certificate /etc/nginx/certs/nginx.crt;
ssl_certificate_key /etc/nginx/certs/nginx.key;
return 404;
}
Такой подход уже лучше: реальные домены не светятся, но браузер все равно покажет предупреждение о недоверенном сертификате.
Для многих этого достаточно. Я и сам долго делал именно так. Но есть более аккуратный вариант:
server {
listen 80 default_server;
listen 443 ssl default_server;
server_name _;
ssl_reject_handshake on;
return 404;
}
Здесь ключевая директива -
ssl_reject_handshake on.Она позволяет сразу отклонять TLS-handshake, не отдавая пользователю чужой сертификат и не доводя дело до стандартного браузерного предупреждения о несовпадении имени.
Что это дает на практике:
запросы по IP на 443 сразу режутся;
сертификаты реальных виртуальных хостов не светятся;
пользователь сразу получает ошибку соединения, без лишних переходов и предупреждений.
В итоге это выглядит чище, чем схема с самоподписанным сертификатом-заглушкой.
ssl_reject_handshake on удобно использовать именно в default server для HTTPS-запросов, которые не должны попадать ни в один нормальный виртуальный хост. Если задача - не просто вернуть 404, а вообще не раскрывать ничего лишнего по IP, это один из самых аккуратных вариантов.#nginx #webserver
🧑💻 NetworkAdmin