Вопрос или проблема
Проверьте эту конфигурацию nginx. Если отправить запрос, например –
curl -H “Host: test.com” http://127.0.0.1:8200
Почему nginx использует второй серверный блок вместо первого блока (с точным совпадением хоста и протокола) и вызывает ошибку 400, сообщая, что обычный HTTP-запрос был отправлен на порт HTTPS.
server {
listen 8200;
server_name test.com;
location / {
return 200 'Block1';
}
}
server {
listen 8200 ssl default_server;
ssl_certificate /etc/ssl/server.cer;
ssl_certificate_key /etc/ssl/server.key;
location / {
return 200 'Block2';
}
}
.
Ответ или решение
Когда дело доходит до конфигурации серверов Nginx, важно понимать, как обрабатываются запросы и какие параметры влияют на выбор соответствующего серверного блока. Ваша проблема заключается в том, что Nginx, обрабатывая запрос с заголовком Host: test.com, использует второй серверный блок, что приводит к ошибке 400 с сообщением о том, что "обычный HTTP-запрос был отправлен на HTTPS-порт". Давайте детально разберем эту ситуацию.
1. Структура конфигурации
В вашей конфигурации есть два серверных блока, которые прослушивают один и тот же порт 8200. Однако, они различаются по настройкам:
-
Первый серверный блок:
server { listen 8200; server_name test.com; location / { return 200 'Block1'; } }
Этот блок не использует SSL и отвечает на запросы, направленные на
test.com
. -
Второй серверный блок:
server { listen 8200 ssl default_server; ssl_certificate /etc/ssl/server.cer; ssl_certificate_key /etc/ssl/server.key; location / { return 200 'Block2'; } }
Этот блок использует SSL и объявлен как
default_server
, что определяет его как сервер по умолчанию для этого порта.
2. Причины выбора второго серверного блока
a. Параметр default_server
Ключевым аспектом является то, что второй блок объявлен default_server
. Этот параметр в Nginx означает, что если не найдено точного соответствия для входящего запроса, будет использован этот серверный блок. Поскольку оба блока прослушивают один и тот же порт (8200), это создает выигрышную роль для второго блока при множестве условий.
b. SSL и HTTP запросы
Когда вы отправляете запрос с использованием curl -H "Host: test.com" http://127.0.0.1:8200
, Nginx видит, что ваш запрос предназначен для порта 8200. Поскольку второй блок является default_server
, он получает приоритет, даже если у него нет соответствия с Host
заголовком. Следовательно, запрос обрабатывается как HTTP, в то время как второй блок ожидает HTTPS соединение. Это и приводит к ошибке:
400 Bad Request
plain HTTP request sent to HTTPS port
3. Как это исправить
Чтобы исправить это поведение и заставить Nginx правильно обрабатывать запросы к test.com
, у вас есть несколько опций:
-
Используйте разные порты для HTTP и HTTPS:
- Например, перенаправьте HTTP на 80 порт, а HTTPS на 443 или используйте иные порты для разделения этих потоков.
-
Удалите параметр default_server из второго блока:
- Это заставит Nginx искать точное соответствие перед выбором сервера по умолчанию.
-
Настройте редирект:
- Вы можете добавить редирект на уровне первого блока, перенаправляя все HTTP запросы на нужные адреса.
Заключение
Понимание принципа работы серверных блоков Nginx, параметра default_server
и аспектов, связанных с SSL-соединениями, является ключевым для правильной настройки веб-сервера. Правильная архитектура конфигурации поможет избежать ошибок и обеспечит стабильность и безопасность ваших приложений.