nginx 流可以使用多个 SSL 证书吗?

nginx 流可以使用多个 SSL 证书吗?

我正在尝试将 nginx 设置为 IIS 7 的前端,以便我可以使用单个 IP 设置多个 SSL 证书,这是 IIS 不支持的(令人震惊)。

在我看来,我根本不需要也不应该干扰 HTTP 层,或者任何未加密的数据(因为 Exchange 的 NTLM 身份验证绑定到 TCP 会话而不是单个请求)。我应该设置 nginx 以仅处理 SSL 层。

幸运的是,它支持这样做!但显然不支持多个证书?

基本上这就是我正在尝试的:

stream {
    upstream http_backend {
        server 192.168.1.1:80;
    }

    upstream https_backend {
        server 192.168.1.1:443;
    }

    server {
        listen 80;
        proxy_pass http_backend;
    }

    server {
        listen 443 ssl;

        ssl_certificate      certs/default.pem;
        ssl_certificate_key  certs/default.key;

        ssl_certificate      certs/domain1.pem;
        ssl_certificate_key  certs/domain1.key;

        ssl_certificate      certs/domain2.pem;
        ssl_certificate_key  certs/domain2.key;

        proxy_pass https_backend;
        proxy_ssl on;
    }
}

根据文档ssl_certificate并且ssl_certificate_key可以多次调用,但目的是指定不同类型的证书,而不是为不同的域指定证书。在这种情况下,最后一对证书将覆盖前一对证书,并成为您在尝试访问服务器时协商的唯一证书,无论使用什么主机名。

在模式下,我无法在同一个端口中stream设置多个条目,只是像在模式下那样进行更改,实际上在上下文中使用时根本不支持,所以不清楚我应该如何解决这个问题。serverserver_namehttpserverserver_namestream

我整天都在谷歌搜索,但找不到解决方案。也许 nginx 不支持我需要的功能?在这种情况下,还有其他选择吗?

任何建议都值得赞赏!

答案1

于是我顿悟并设法解决了这个问题。

事实证明,您不需要在流server条目中设置 SSL 模式或任何证书即可开始ssl_preread工作,这可能带来一种有趣的解决方法。

server我可以在列出的任意端口上设置多个条目localhost,每个条目都有不同的证书,并且server在端口 443 上有一个主端口将传入连接路由到正确的端口。

以下是包含 3 个证书的基本配置:

worker_processes  1;

events {
}

stream {

    // IIS server
    upstream https_backend {
        server 10.0.0.1:443;
    }

    // set up SSL session with the default certificate
    upstream default {
        server 127.0.0.1:4430;
    }
    server {
        listen 127.0.0.1:4430 ssl;

        ssl_certificate certs/default.pem;
        ssl_certificate_key certs/default.key;

        proxy_ssl on;
        proxy_pass https_backend;
    }

    // set up SSL session with certificate for marvel.com, www.marvel.com
    upstream marvel {
        server 127.0.0.1:4431;
    }
    server {
        listen 127.0.0.1:4431 ssl;

        ssl_certificate certs/marvel.pem;
        ssl_certificate_key certs/marvel.key;

        proxy_ssl on;
        proxy_pass https_backend;
    }

    // set up SSL session with certificate for dccomics.com, www.dccomics.com
    upstream dccomics {
        server 127.0.0.1:4432;
    }
    server {
        listen 127.0.0.1:4432 ssl;

        ssl_certificate certs/dccomics.pem;
        ssl_certificate_key certs/dccomics.key;

        proxy_ssl on;
        proxy_pass https_backend;
    }

    // route connection to the tunnel with correct certificate
    map $ssl_preread_server_name $upstream {
        marvel.com marvel;
        www.marvel.com marvel;

        dccomics.com dccomics;
        www.dccomics.com dccomics;

        default default;
    }
    server {
        listen 443;
        ssl_preread on;
        proxy_pass $upstream;
    }
}

因此,就 SSL 和 NTLM 身份验证而言,这非常有效,我唯一缺少的是在 IIS 日志上注册真实用户 IP 的可能性,因为我无法X-Forwarded-For在 HTTP 标头中设置。

相关内容