Чому слухати 443 default_server; Правило nginx замінює вже налаштоване правило (правила нормального режиму роботи в режимі http)?


9

У мене є nginx та різні субдомени:

a.mydomain.com
b.mydomain.com
c.mydomain.com

Nginx має 4 правила:

1) переписати правило:

server {
  listen 80
  server_name gl.udesk.org;

  root /nowhere;
  rewrite ^ https://a.mydomain.com$request_uri permanent;
}

2) правило https:

server {

  listen 443;
  server_name a.mydomain.com;

  root /home/a/a/public;

  ssl on;
  ssl_certificate conf.d/ssl/a.crt;
  ssl_certificate_key conf.d/ssl/a.key;
  ssl_protocols ...
  ssl_ciphers ...
  ssl_prefer_server_ciphers on;

  location ...
}

3) правило за замовчуванням http:

server {
  listen 80 default_server;
  return 444;
}

4) правило за замовчуванням https:

server {
  listen 443 default_server;
  return 444;
}

Тож якщо я запускаю nginx і:

  • якщо я заходжу в браузер на http://a.mydomain.com, він перенаправляє на https://a.mydomain.com, а потім повертає помилку 107 (нетто: ERR_SSL_PROTOCOL_ERROR): помилка протоколу SSL.
  • якщо я заходжу у веб-переглядачі на https://b.mydomain.com, я очікую, що він поверне помилку 444 назад. Але замість цього він повертає ту саму помилку 107 (net :: ERR_SSL_PROTOCOL_ERROR): помилка протоколу SSL.
  • і так для всіх зареєстрованих постачальником DNS CNAME (тобто a, b, c)
  • всі http-версії (наприклад, правило 3 -) працюють як слід:

Так чому правила https в nginx настільки складні в налаштуванні і як я повинен їх правильно налаштувати, щоб отримати таку саму поведінку, як і у версії http?

Оновлення:

Створення нового сертифіката та додавання:

ssl on;
ssl_certificate conf.d/ssl/default.crt;
ssl_certificate_key conf.d/ssl/default.key;

працює зараз, але я мав би рішення без необхідності отримати сертифікат SSL. Просто скиньте всі з'єднання для всіх піддоменів https (порт 443), крім https://a.mydomain.com, не надаючи сертифікат.


2
Ви не можете. SSL вимагає сертифікату, перш ніж веб-сервер дізнається, який домен ви хочете . Він повинен мати сертифікат для надсилання, або він не може встановити з'єднання для розмови з клієнтом.
Дарт Android

2
@DarthAndroid: Магія називається SNI - en.wikipedia.org/wiki/Server_Name_Indication .
Ши

@Shi Я знаю SNI - Це дозволяє веб - сервер , щоб вибрати , який сертифікат для відправки, але він все одно повинен вибрати в сертифікат. nginxнедостатньо розумний, щоб зрозуміти, що йому не потрібен сертифікат для того, що користувач хоче робити.
Дарт Android

Відповіді:


3

Не змішуйте порт 443 зі ssl! Nginx є повністю портовим агностиком. Ви також можете запропонувати https через порт 80. Сучасні версії nginx дозволяють

listen 1234 ssl;

і тоді вам не потрібна ssl on;лінія.

Але якщо ви хочете обслуговувати https, вам потрібно вказати сертифікат. Ваш сервер вводить https, коли він переписує http-запит у запит https.

Ви отримуєте помилку PROTOCOL, оскільки рукостискання SSL робиться раніше всього. Так return 444не досягнуто. І будь-якому SSL рукостисканню знадобиться сертифікат і приватний ключ, щоб подати алгоритми шифрування за допомогою пари сертифікатів / приватних ключів.


3

returnДиректива є частиною модуля перезапису. Якщо ви перевірите документацію , ви можете побачити, що вона працює із запитами. У HTTPS запити можуть бути зроблені лише після закінчення рукостискання.

Є запит на функцію: https://trac.nginx.org/nginx/ticket/195, і вирішено вирішення проблеми.

server {
    listen 443 ssl;
    server_name bbb.example.com;
    ssl_ciphers aNULL;
    ssl_certificate /path/to/dummy.crt;
    ssl_certificate_key /path/to/dummy.key;
    return 444;
}

Зверніть увагу , це суперечить не-SNI-здатних клієнтів HTTPS (наприклад Nginx власного proxy_pass, якщо не встановлено proxy_ssl_server_name on;) від досягнення якої - небудь інший server_names(так істотно порушити законні server_nameS , що ви дійсно хочете , щоб через). Докладніше див. Trac.nginx.org/nginx/ticket/195#comment:11 .
nh2
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.