Вопрос или проблема
Я недавно создал сервер nginx на Debian 8. Он появился с конфигурацией по умолчанию в /etc/nginx/sites-available/default, которая перенаправляет на страницу приветствия nginx.
server {
listen 80 default_server;
listen [::]:80 default_server;
root /var/www/html;
index index.php index.html index.htm index.nginx-debian.html;
server_name your_server_ip;
location / {
try_files $uri $uri/ =404;
}
location ~ \.php$ {
include snippets/fastcgi-php.conf;
fastcgi_pass unix:/var/run/php/php7.0-fpm.sock;
}
location ~ /\.ht {
deny all;
}
}
Я добавил новую страницу для продакшена, скажем, ‘example.com’ с ssl.
В конфигурации для ../example.com она не установлена как сервер по умолчанию.
server {
listen 80;
listen [::]:80;
server_name example.com www.example.com;
return 301 https://$server_name$request_uri;
}
server {
# Конфигурация SSL
listen 443 ssl;
listen [::]:443 ssl;
include snippets/ssl-example.com.conf;
include snippets/ssl-params.conf;
....
Теперь, когда я проверял безопасность ssl на https://www.ssllabs.com/ssltest/analyze.html?d=example.com, он получил оценку A+. Но он указал ‘Несоответствующая конфигурация сервера’.
И когда я загружаю IP-адрес, скажем, x.x.x.x в браузере как https:// x.x.x.x, он загружает ту же страницу, что и https://example.com, но без ssl (зеленая адресная строка). Если я загружаю http:// x.x.x.x, он загружает страницу приветствия по умолчанию nginx.
Я попытался установить конфигурацию по умолчанию (для IP), чтобы получить сообщение о запрете, я добавил следующий код
location / {
deny all;
}
Теперь, когда я тестирую безопасность ssl для example.com, он говорит “Нет поддерживаемых безопасных протоколов” и тестовые результаты не появляются.
Итак, мои вопросы следующие:
Что следует сделать с конфигурацией по умолчанию, которая приходит с nginx и загружается для IP-адреса?
Какой server_name (файл конфигурации) следует установить как default_server в команде ‘listen’?
Что следует сделать с IP-адресом, который в настоящее время пересылает https-запросы на домен example?
Предполагаемые результаты:
https:// example.com должен использоваться для подключения к серверу, а загрузка IP-адреса может показывать ‘страница не найдена’ или ‘запрещено’, так как example.com будет использоваться для php-скриптов на нем.
Тесты SSL должны давать хотя бы A рейтинг после установленной конфигурации.
IP-адрес не должен принимать никаких подключений напрямую и обрабатывать их.
Вы можете использовать это как свой блок сервера по умолчанию:
server {
listen 80 default_server;
listen 443 ssl default_server;
server_name _;
... SSL ключи для сервера по умолчанию ...
return 403;
}
Это приведет к тому, что любое HTTP-соединение, заголовок Host: которого не совпадает с любым другим виртуальным хостом на сервере, вернет сообщение об ошибке 403 Forbidden клиенту.
Если вы используете действительные SSL ключи для имени хоста, которое не совпадает с любым существующим именем хоста, клиент получит страницу ошибки 403 непосредственно. Если вы используете самоподписанный сертификат, тогда пользователь получит сообщение об ошибке ненадежного сертификата.
Вы можете использовать “ssl_reject_handshake on” для отказа от SSL-соединения. Это как “return 444”, чтобы закрыть соединение.
# HTTP:80 = общий блок сервера, который приведет к ответу 444 для неизвестных доменов.
# HTTPS:443 = общий блок сервера, который приведет к отказу в SSL-соединении для неизвестных доменов.
server {
listen 80 default_server;
listen [::]:80 ipv6only=on default_server;
server_name "_";
return 444; # Соединение закрыто без ответа
}
server {
listen 443 default_server;
listen [::]:443 ipv6only=on default_server;
server_name "_";
ssl_reject_handshake on; # Отклонить соединение SSL
}
Наконец, нашел рабочее решение. Quora делает что-то подобное. Чтобы перенаправить по умолчанию на 404.
Источник : Правильно настройка “по умолчанию” сервера nginx для https
Установив конфигурацию по умолчанию на это.
server {
server_name _;
listen 80 default_server;
return 404;
}
server {
listen 443 ssl;
server_name _;
ssl_certificate /etc/nginx/ssl/nginx.crt;
ssl_certificate_key /etc/nginx/ssl/nginx.key;
return 404;
}
Затем создайте директорию для ssl, если она не существует
sudo mkdir -p /etc/nginx/ssl
Затем создайте самоподписанный ssl для того же
sudo openssl req -x509 -nodes -days 365 -newkey rsa:2048 -keyout /etc/nginx/ssl/nginx.key -out /etc/nginx/ssl/nginx.crt
Проверьте на ошибки и перезагрузите nginx, чтобы получить 404
nginx -t
sudo systemctl reload nginx
Упрощая ответ @Сергея для современных версий nginx:
# /etc/nginx/conf.d/default.conf
# Установить default_server для отклонения/отказа подключений как http/https
server {
listen 80 default_server;
listen [::]:80 default_server;
listen 443 default_server;
listen [::]:443 default_server;
ssl_reject_handshake on; # Закрыть соединение https без ответа
return 444; # Закрыть соединение http без ответа
}
Это работает, потому что:
server_name "_"
в то время как популярный во многих решениях, это просто определяет имя, которое не должно совпадать ни с чем. Вы можете просто удалить его.ipv6only=on
и так является значением по умолчанию.ssl_reject_handshake on;
иreturn 444;
не мешают друг другу.
Ответ или решение
Оптимальные практики для работы с параметрами default_server и публичным IP в NGINX
Ваша задача по конфигурации NGINX для обработки запросов на публичный IP-адрес и настройка параллельно работающего домена example.com
требует внимания к следующим аспектам: установка политики для обработки запросов, корректная настройка SSL и адекватная реакция на запросы, не соответствующие указанным доменам.
Проблема с конфигурацией
По умолчанию, если запрос приходит на IP-адрес вашего сервера и NGINX не может сопоставить его с именем хоста в его конфигурации, будет использоваться блок по умолчанию (default server). В вашем случае такой блок настроен без конкретного поведения, что приводит к загрузке страницы приветствия NGINX. Это поведение нежелательно, так как вы хотите, чтобы запросы по IP-адресу возвращали ошибку конфиденциальности или 404.
Настройка default_server
Для решения возникшей проблемы я рекомендую использовать следующие настройки для вашего default server:
server {
listen 80 default_server;
listen [::]:80 default_server;
return 404; # Возвращаем ошибку 404 для HTTP-запросов
}
server {
listen 443 ssl default_server;
listen [::]:443 ssl default_server;
ssl_certificate /etc/nginx/ssl/nginx.crt; # Укажите путь к вашему SSL-сертификату
ssl_certificate_key /etc/nginx/ssl/nginx.key; # Укажите путь к вашему ключу
return 404; # Возвращаем ошибку 404 для HTTPS-запросов
}
Объяснение настроек:
- listen 80 default_server; и listen 443 ssl default_server; – эти директивы заставляют NGINX обрабатывать все входящие запросы по умолчанию.
- return 404; – это гарантирует, что любой запрос, который не соответствует указанным в других блоках, будет завершаться с ошибкой 404. Это предотвратит доступ к вашему серверу по IP-адресу.
Обработка SSL
Если вы хотите, чтобы никакие подключения к IP-адресу не обрабатывались, рекомендую добавить директиву ssl_reject_handshake
:
server {
listen 443 default_server;
listen [::]:443 default_server;
ssl_reject_handshake on; # Закрытие соединения без ответа для неподдерживаемых хостов
}
Этот подход закроет соединения SSL без передачи каких-либо данных, если они не соответствуют вашим доменным настройкам.
Проверка настройки
После всех изменений убедитесь, что вы проверили конфигурацию на наличие ошибок:
sudo nginx -t
Если ошибок не обнаружено, перезагрузите NGINX для применения новых настроек:
sudo systemctl reload nginx
Результаты
С помощью описанных выше настроек:
- Запросы, поступающие на IP-адрес, будут завершаться ошибкой 404.
- Запросы, поступающие на
example.com
, будут корректно обслуживаться через SSL. - Тестирование SSL должно дать результат не ниже "A", при условии, что параметры SSL настроены корректно.
Заключение
Соблюдение описанных рекомендаций позволит безопасно настроить ваш сервер NGINX, гарантируя, что к нему можно будет обращаться только через заранее определённые домены. Это не только улучшает уровень безопасности, но и оптимизирует взаимодействие с пользователями и клиентами.