如何告诉 nginx 仅为一个 vhost 管理的域提供 https 服务?

如何告诉 nginx 仅为一个 vhost 管理的域提供 https 服务?

我有一个运行 ubuntu 和 nginx 0.8.4 的 ec2 实例,其中 vhosts 使用 http 为几个不同的域提供服务,但有一个使用 SSL/https。

安全域配置:

server {
    listen 443 ssl;
    server_name "securedomain.tld";

    ssl_certificate     /etc/nginx/certs/securedomain.tld.crt;
    ssl_certificate_key /etc/nginx/certs/securedomain.tld.key;

    if ($host != $server_name) {
        return 444; # this won't work because HTTPS communication has 
                    # been already started, warning message is displayed
    }

    // ...
}

不安全的域配置:

server {
    listen 80; 
    server_name "unsecuredomain.tld";

    // ...
}

目前,使用 https 提供服务的域名正在迎头赶上全部所有托管域的 https 流量……这意味着https://unsecuredomain.tld/将显示警告,但实际上提供的内容来自securedomain.tld:(

问题是,有没有办法阻止 nginx 为所有使用 https 服务的不安全域提供服务?例如,通过指定您只想接受给定请求主机的 https 连接……

提示:一个 ec2 实例不能有多个 IP 受到影响。

答案1

简而言之:不行。就 nginx 而言,您已告知它到端口 443 的所有连接都是该虚拟主机的 SSL 连接,它只是按照您告知的方式执行。当它能够看到Host:请求中的标头时,SSL 协商已完成(缺少 SNI,这实际上只有在您拥有所有域的证书并且被支持 SNI 的浏览器访问时才会有所帮助)。

答案2

正如 womble 所指出的,如果没有第二个 IP 地址或某种代理设置,SSL 不匹配警告是无法避免的。

如果您想阻止 unsecuredomain.tld 内容通过 SSL 提供,您应该在 securedomain.tld SSL vhost 定义中使用类似以下内容,而不是您已有的内容:

if ($host != $server_name) {
    rewrite ^(.*)$ http://unsecuredomain.tld permanent;
}

然后将其弹出,而不是在他们已经收到浏览器警告并选择继续后抛出不同的 HTTP 错误。

相关内容