IIS 10 и HTTP / 2 - требуется сертификат клиента - PullRequest
0 голосов
/ 18 сентября 2018

В настоящее время я тестирую веб-приложение на IIS 10, используя HTTP 1.1 и HTTP / 2.Мое тестовое приложение имеет одну конечную точку (/ api / test), которая возвращает просто «true».У меня есть 3 сертификата:

  • Корневой CA (самоподписанный)
  • Сертификат сервера, подписанный корневым CA
  • Сертификат клиента, подписанный корневым CA

Корневой сертификат CA и сервера установлен на Windows Server 2016, а веб-сайт IIS настроен на прослушивание https://example.net:8081/ с использованием сертификата сервера.Также я настраиваю веб-сайт так, чтобы он требовал сертификат клиента (это важно для моих тестов, мне нужна проверка сертификатов сервера / клиента).

Я тестирую свое приложение с помощью curl, и для http1.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 работают оба.

Как я могу использовать сертификат клиента с HTTP / 2 в IIS?

1 Ответ

0 голосов
/ 20 сентября 2018

После нескольких часов исследований я обнаружил, что IIS 10 в настоящее время не поддерживает HTTP / 2 с проверкой сертификата клиента.

https://docs.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в качестве прокси для приложения, и все отлично работает.

...