Nginx proxy на основе хоста при использовании https

Мне нужно использовать Nginx в качестве прокси SSL, который перенаправляет трафик на разные задние концы в зависимости от субдомена.

Кажется, что везде я должен определить несколько разделов "server {", но это не работает корректно для SSL. При этом я всегда имел бы SSL, обрабатываемый на первом виртуальном хосте, поскольку имя сервера неизвестно до тех пор, пока вы не обработаете трафик https.

Сценарий:

  • Один IP-адрес
  • Подстановочный шаблон для одного шаблона SSL
  • Несколько бэкэндов, к которым необходимо получить доступ, например:

    https://one.mysite.com/ -> http://localhost:8080
    https://two.mysite.com/ -> http://localhost:8090
    

Nginx говорит, что "если" является злом: http://wiki.nginx.org/IfIsEvil, но что еще я могу сделать?

Я пробовал это, но он не работает, я получаю ошибку 500, но ничего в журналах ошибок.

    server {
    listen 443;
    server_name *.mysite.com;

    ssl on;
    ssl_certificate ssl/mysite.com.crt;
    ssl_certificate_key ssl/mysite.com.key;

    location / {
        if ($server_name ~ "one.mysite.com") {
            proxy_pass http://localhost:8080;
        }
        if ($server_name ~ "two.mysite.com") {
            proxy_pass http://localhost:8090;
        }
    }

Кто-нибудь смог это сделать с Nginx? Любая помощь/альтернативы, ссылка, будет высоко оценена.

Ответы

Ответ 1

Я нашел решение, которое в основном определяет параметры SSL и сертификат SSL вне блока "сервер":

ssl_certificate ssl/mysite.com.crt;
ssl_certificate_key ssl/mysite.com.key;
ssl_session_timeout  5m;
ssl_protocols        SSLv3 TLSv1;
ssl_ciphers          ALL:!ADH:!EXPORT56:RC4+RSA:+HIGH:+MEDIUM:+EXP;
ssl_prefer_server_ciphers   on;

server {
    listen 80;
    server_name *.mysite.com;
    rewrite ^ https://$host$request_uri? permanent;
}
server {
    listen 443 ssl;
    server_name one.mysite.com;

    ssl on;

    location / {
        proxy_pass http://localhost:8080;
    }
}
server {
    listen 443 ssl;
    server_name two.mysite.com;

    ssl on;

    location / {
        proxy_pass http://localhost:8090;
    }
}

Ключевые вещи:

  • "ssl on;" это единственное, что должно быть в "серверных" блоках, которые прослушивают https, вы также можете выставить его снаружи, но что сделает блоки "сервера", которые прослушивают порт 80, использовать протокол https, а не ожидаемый http.
  • Поскольку "ssl_certificate", "ssl_ciphers: и другие" ssl_ * "находятся за пределами" серверного "блока, Nginx выполняет разгрузку SSL без имени server_name. Это то, что он должен делать, поскольку дешифрование SSL не может произойти на основе любое имя хоста, поскольку на этом этапе URL-адрес зашифрован.
  • JAVA и curl не могут работать сейчас. Нет имени server_name - совпадения с хостом.

Ответ 2

Короткий ответ заключается в использовании Указания имени сервера. Это должно работать по умолчанию в общих браузерах и cURL.

Ответ 3

согласно http://www.informit.com/articles/article.aspx?p=1994795, у вас должно быть два раздела "сервер" с двумя разными именами серверов. В каждом из них вы должны включить директивы ssl_ *.