2017-01-02 6 views
0

Я хочу использовать 2 серверных блока. Первый:Как использовать имя_сервера в Nginx под HTTP/2?

server { 
    listen 443 ssl http2 fastopen=3 reuseport; 
    server_name a.example.xyz; 
    include server_safe.conf; 
    root /home/www/blog/; 
    } 

Второй:

server { 
    listen 443 ssl http2; 
    server_name b.example.xyz; 
    include server_safe.conf; 
} 

Что я хочу: Я хочу server_name быть действительным, то есть, если я использую c.example.xyz посетить мой сайт, как a.example.xyz, b.example.xyz, c.example.xyz - это тот же IP-адрес, сервер должен заблокировать запрос c.example.xyz, поскольку он не находится в server_name.

Однако, если я вхожу https://c.example.xyz, то Nginx все равно будет получать запрос и réponse в a.example.xyz

Я знаю, что HTTP/2 не имеет хозяина в его заголовке, он имеет :authority вместо этого.

Мой вопрос в том, что: Как я могу отклонить любой другой запрос? Я хочу только принять запрос (с) host(:authority) = a(b).example.xyz

ответ

2

Проблема заключается в том, что первый серверный блок используется по умолчанию, если другое имя не совпадает.

Для достижения желаемого вам необходимо создать блок по умолчанию до двух других и заблокировать его или перенаправить или показать страницу с ошибкой.

Недостатков этого являются:

  1. Если у вас есть сертификаты HTTPS, что все доменные имена (или использовать подстановочный сертификат, который покрывает это), то они получат ошибку при переходе к HTTPS версии ваш сайт и используйте эту конфигурацию по умолчанию. Хотя это все равно произойдет в соответствии с вашими нынешними настройками. AFAIK не может отправить сообщение блока до, то есть переговоры HTTPS.

  2. Старые клиенты, которые не поддерживают SNI (в первую очередь Windows XP), перейдут в конфигурацию по умолчанию, тогда как ранее они прошли бы через Server A, поскольку это было по умолчанию (хотя и не для сервера B).

Альтернативой является написать правило переадресации на основе предоставленного имени хоста. Не 100% уверен, как это сделать на nginx, если честно, но если это невозможно по умолчанию, то возможно с ModSecurity. Опять же, это вступит в силу после переговоров HTTPS, так что все еще оставляет вас с потенциальной неправильной проблемой сертификата.

+0

Вы, в соответствии с вашим ответом, создали новый серверный блок с именем 'server_name _' перед другим серверным блоком, так что любому другому запросу может быть присвоено значение 404. Конечно, поскольку он получает ответ 404, он прошел переговоры https. Мой сертификат имеет SAN, у моего nginx есть SNI, поэтому сертификат не является проблемой. Наконец, большое спасибо – user3978288