使用https时基于主机的nginx代理

时间:2013-08-19 17:34:42

标签: ssl https nginx proxy wildcard-subdomain

我需要使用Nginx作为SSL代理,根据子域将流量转发到不同的后端。

我似乎无处不在,我应该定义多个“服务器{”部分,但这对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实现这一目标?任何帮助/替代方案,链接,将不胜感激。

3 个答案:

答案 0 :(得分:27)

我找到的解决方案基本上是在“服务器”块之外定义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在没有server_name的情况下进行SSL卸载。这应该是什么,因为SSL解密不能基于任何主机名,因为在此阶段URL已加密。
  • JAVA和curl现在不会失败。没有server_name - 主机未命中匹配。

答案 1 :(得分:4)

简短的回答是使用Server Name Indication。这应该在普通浏览器和cURL中默认工作。

答案 2 :(得分:1)

根据http://www.informit.com/articles/article.aspx?p=1994795,你确实应该有两个“服务器”部分,它们有两个不同的服务器名称。 在每一个中,你应该包括你的ssl_ *指令。