Nginx代理通过证书增补到MS IIS

Agr*_*ris 2 authentication iis ssl reverse-proxy nginx

Nginx 1.9.5(Linux Centos7)-> MS IIS 8.5因此,我尝试将nginx用作IIS的客户端反向代理,其中需要在IIS级别进行客户端证书身份验证。nginx:443->> IIS:443+客户端证书身份验证。

示例位置代理通过也这里是我尝试的注释命令。

location ^~ /test/ {
#proxy_buffering off;
#proxy_http_version 1.0;
#proxy_request_buffering off;
#proxy_set_header Connection "Keep-Alive";
#proxy_set_header X-SSL-CERT $ssl_client_cert;
# proxy_ssl_name domain.lv;
#proxy_ssl_trusted_certificate /etc/nginx/ssl/root/CA.pem;
#proxy_ssl_verify_depth 2;

proxy_set_header HOST domain.com;
proxy_ssl_certificate /etc/nginx/ssl/test.pem;
proxy_ssl_certificate_key /etc/nginx/ssl/test_key.pem;
proxy_ssl_verify off;
proxy_pass https://10.2.4.101/;

 }
Run Code Online (Sandbox Code Playgroud)

在IIS上很简单。

  1. 创建新的网站。
  2. 在受信任的根目录中导入CA证书。
  3. 设置必需的ssl证书。

测试我得到什么:

  1. 直接浏览器需要IIS客户端证书-工作正常。
  2. Nginx到其他nginx客户端证书的要求-工作。
  3. Nginx到IIS客户端证书忽略-工作
  4. Nginx到IIS客户端证书是必需的或不能接受-不起作用

错误:Nginx端:* 4622上游超时(110:连接超时),同时从上游IIS端读取响应标头:500 0 64 119971

所以我希望有人能知道为什么?

编辑1.还尝试从其他服务器使用Nginx 1.8,没有帮助。

proxy_ssl_verify off;
proxy_ssl_certificate /etc/nginx/ssl/test/test.pem;
proxy_ssl_certificate_key /etc/nginx/ssl/test/test_key.pem;
proxy_pass https://domain.com;
Run Code Online (Sandbox Code Playgroud)

2.尝试与Apache 2.4相同

SSLProxyEngine On
SSLProxyVerify none
SSLProxyCheckPeerCN off
SSLProxyCheckPeerName off
SSLProxyCheckPeerExpire off
SSLProxyMachineCertificateFile /etc/httpd/ssl/test.pem
ProxyPass "/test" "https://domain.com"
Run Code Online (Sandbox Code Playgroud)

也许在Nginx中与SSL重新协商有关???

小智 5

您对TLS重新协商的预感是正确的。自0.8.23版以来,Nginx不允许TLS重新协商(请参阅http://nginx.org/en/CHANGES)。但是,默认情况下,IIS在请求客户端证书时将使用TLS重新协商。(我无法找到原因,如果有人能启发我,我将不胜感激!)

您可以使用诸如wireshark的数据包嗅探器来查看此操作:

  1. IIS和Nginx首先仅使用服务器证书执行TLS握手。
  2. Nginx请求资源。
  3. 该资源需要客户端身份验证,因此IIS向Nginx发送“ Hello Request”消息以启动TLS重新协商。
  4. Nginx不响应Hello请求,因为TLS重新协商已被禁用。
  5. IIS然后关闭连接,因为它没有响应。(请参阅https://technet.microsoft.com/zh-cn/library/cc783349(v=ws.10).aspx上有关重新协商的部分)

若要解决此问题,必须强制IIS在初始TLS握手时请求客户端证书。您可以通过powershell或命令行使用netsh实用程序来执行此操作:

  1. 打开具有管理员权限的Powershell提示。
  2. 输入 netsh
  3. 输入 http
  4. 输入show sslcert。您应该在计算机上看到所有当前SSL绑定的列表:

netsh http show sslcert输出

  1. 记下要为其启用客户端证书协商的证书的IP:端口和证书哈希。现在,我们将删除此绑定,并在“协商客户端证书”属性设置为启用的情况下重新添加它。在此的示例IP:端口是0.0.0.0:44300和证书哈希是71472159d7233d56bc90cea6d0c26f7a29db1112。
  2. 输入 delete sslcert ipport=[IP:port from above]
  3. 输入 add sslcert ipport=[IP:port from above] certhash=[certificate hash from above] appid={[any random GUID (can be the same one from the show sslcert output)]} certstorename=MY verifyclientcertrevocation=enable verifyrevocationwithcachedclientcertonly=disable clientcertnegotiation=enable
  4. 现在,您可以通过show sslcert再次运行来确认它是否起作用。您应该看到几乎相同的输出,但是“协商客户端证书”设置为“已启用”:

在此处输入图片说明

请注意,此方法仅适用于单个证书-如果您需要更改或更新证书,则必须再次运行这些步骤。当然,您应该将它们包装在批处理脚本或MSI安装程序自定义操作中,以简化部署和维护。