IIS 10和HTTP/2-需要客户端证书

5

目前我正在使用HTTP 1.1和HTTP/2测试基于IIS 10的Web应用程序。

我的测试应用程序有一个端点(/api/test),返回值为“true”。

我有3个证书:

  • 根CA(自签名)
  • 由根CA签名的服务器证书
  • 由根CA签名的客户端证书

根CA和服务器证书安装在Windows Server 2016上,IIS网站配置为监听https://example.net:8081/,使用服务器证书。同时,我还配置了网站要求客户端证书(这对我的测试很重要,需要进行服务器/客户端证书验证)。

我通过curl测试我的应用程序,在HTTP 1.1下一切正常。

命令:

curl.exe --http1.1 --get --url https://example.net:8081/api/test --cacert E:\ca.pem --cert E:\client.pem --key E:\client.key --cert-type PEM --verbose

输出:

* TCP_NODELAY set
* Connected to example.net port 8081 (#0)
* ALPN, offering http/1.1
* successfully set certificate verify locations:
*   CAfile: E:\ca.pem
  CApath: none
* TLSv1.3 (OUT), TLS handshake, Client hello (1):
* TLSv1.3 (IN), TLS handshake, Server hello (2):
* TLSv1.2 (IN), TLS handshake, Certificate (11):
* TLSv1.2 (IN), TLS handshake, Server key exchange (12):
* TLSv1.2 (IN), TLS handshake, Server finished (14):
* TLSv1.2 (OUT), TLS handshake, Client key exchange (16):
* TLSv1.2 (OUT), TLS change cipher, Change cipher spec (1):
* TLSv1.2 (OUT), TLS handshake, Finished (20):
* TLSv1.2 (IN), TLS handshake, Finished (20):
* SSL connection using TLSv1.2 / ECDHE-ECDSA-AES256-GCM-SHA384
* ALPN, server accepted to use http/1.1
* Server certificate: XXX
*  SSL certificate verify ok.
> GET /api/test HTTP/1.1
> Host: example.net:8081
> User-Agent: curl/7.61.1
> Accept: */*
>
* TLSv1.2 (IN), TLS handshake, Hello request (0):
* TLSv1.2 (OUT), TLS handshake, Client hello (1):
* TLSv1.2 (IN), TLS handshake, Server hello (2):
* TLSv1.2 (IN), TLS handshake, Certificate (11):
* TLSv1.2 (IN), TLS handshake, Server key exchange (12):
* TLSv1.2 (IN), TLS handshake, Request CERT (13):
* TLSv1.2 (IN), TLS handshake, Server finished (14):
* TLSv1.2 (OUT), TLS handshake, Certificate (11):
* TLSv1.2 (OUT), TLS handshake, Client key exchange (16):
* TLSv1.2 (OUT), TLS handshake, CERT verify (15):
* TLSv1.2 (OUT), TLS change cipher, Change cipher spec (1):
* TLSv1.2 (OUT), TLS handshake, Finished (20):
* TLSv1.2 (IN), TLS handshake, Finished (20):
< HTTP/1.1 200 OK
< Transfer-Encoding: chunked
< Content-Type: application/json; charset=utf-8
< Server: Kestrel
< Date: Tue, 18 Sep 2018 13:45:35 GMT
<
true* Connection #0 to host abrakadabra.cranecs.net left intact

但是,如果我尝试使用http/2发送请求,在服务器证书验证后就会失败。

命令:

curl.exe --http2 --get --url https://example.net:8081/api/test --cacert E:\ca.pem --cert E:\client.pem --key E:\client.key --cert-type PEM --verbose

输出:

* TCP_NODELAY set
* Connected to example.net port 8081 (#0)
* ALPN, offering h2
* ALPN, offering http/1.1
* successfully set certificate verify locations:
*   CAfile: E:\ca.pem
  CApath: none
* TLSv1.3 (OUT), TLS handshake, Client hello (1):
* TLSv1.3 (IN), TLS handshake, Server hello (2):
* TLSv1.2 (IN), TLS handshake, Certificate (11):
* TLSv1.2 (IN), TLS handshake, Server key exchange (12):
* TLSv1.2 (IN), TLS handshake, Server finished (14):
* TLSv1.2 (OUT), TLS handshake, Client key exchange (16):
* TLSv1.2 (OUT), TLS change cipher, Change cipher spec (1):
* TLSv1.2 (OUT), TLS handshake, Finished (20):
* TLSv1.2 (IN), TLS handshake, Finished (20):
* SSL connection using TLSv1.2 / ECDHE-ECDSA-AES256-GCM-SHA384
* ALPN, server accepted to use h2
* Server certificate: XXX
*  SSL certificate verify ok.
* Using HTTP2, server supports multi-use
* Connection state changed (HTTP/2 confirmed)
* Copying HTTP/2 data in stream buffer to connection buffer after upgrade: len=0
* Using Stream ID: 1 (easy handle 0x1f635299100)
> GET /api/test HTTP/2
> Host: example.net:8081
> User-Agent: curl/7.61.1
> Accept: */*
>
* Connection state changed (MAX_CONCURRENT_STREAMS == 100)!
* HTTP/2 stream 0 was not closed cleanly: HTTP_1_1_REQUIRED (err 13)
* stopped the pause stream!
* Connection #0 to host example.net left intact
curl: (92) HTTP/2 stream 0 was not closed cleanly: HTTP_1_1_REQUIRED (err 13)

在 IIS 日志中,我看到了以下记录:

2018-09-18 13:46:00 172.32.0.193 GET /api/test - 8081 - 134.17.25.89 HTTP/1.1 curl/7.61.1 - 200 0 0 421
2018-09-18 13:55:01 172.32.0.193 GET /api/test - 8081 - 134.17.25.89 HTTP/2.0 curl/7.61.1 - 403 7 64 0

对于http/2,似乎客户端证书缺失(403.7状态码)。

最后,如果我只是将IIS站点设置中的“要求客户端证书”更改为“忽略客户端证书”,则http1.1和http/2都可以工作。

如何在IIS上使用HTTP/2与客户端证书?


这可能涉及在握手期间协商HTTP/1.1,或向客户端发送错误代码,指示其通过HTTP/1.1连接重试。 - Ali NajafZadeh
3个回答

7
几个小时的研究后,我发现IIS 10目前不支持客户端证书验证的HTTP/2。
可以查看https://learn.microsoft.com/en-us/iis/get-started/whats-new-in-iis-10/http2-on-iis#when-is-http2-not-supported了解更多信息。在一些情况下,HTTP/2不能与其他功能组合使用。在这些情况下,Windows将回退到HTTP/1.1并继续处理事务。这可能涉及在握手期间协商HTTP/1.1,或向客户端发送错误代码,指示其在HTTP/1.1连接上重试。
我重新配置了我的服务器,使用nginx代替IIS作为应用程序的代理,一切正常。

0

我也遇到了这个问题,在阅读了this的信息后,我发现你需要在绑定级别上启用“协商客户端证书”。


-1

我在Server 2022上使用IIS 10设置了一个DotNet Framework 4.8网站,并开启了客户端证书要求。IE可以正常工作,但启用TLS1.3的浏览器(如Edge和Chrome)无法正常工作。通过Wireshark抓包发现,在握手期间连接被重置。经过编辑网站绑定的尝试,我发现只有在启用TLS 1.3或HTTP/2时才能使其正常工作,但不能同时启用,当需要客户端证书并使用启用了TLS1.3的客户端时。

希望微软有一天会为我们修复这个问题。


这可能涉及在握手过程中协商HTTP/1.1,或向客户端发送错误代码,指示其通过HTTP/1.1连接重试。 - Ali NajafZadeh
这可能不是关于Microsoft的内容:RFC 9113(HTTP/2):https://datatracker.ietf.org/doc/html/rfc9113#section-9.2.3 RFC 9001(使用TLS保护QUIC):https://datatracker.ietf.org/doc/html/rfc9001#section-4.2 RFC 9001(使用TLS保护QUIC):https://datatracker.ietf.org/doc/html/rfc9001#section-4.4 RFC 8446(TLS 1.3):https://datatracker.ietf.org/doc/html/rfc8446#section-4.2.6 Firefox(至少目前)是唯一实现post_handshake_auth的浏览器:https://bugzilla.mozilla.org/show_bug.cgi?id=1511989 - yibup

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接