HTTPS не работает с Kestrel 3.2.187 / ASPNET Core 2.1.5, работающим в Service Fabric с настраиваемым доменом - PullRequest
0 голосов
/ 23 октября 2018

Мы запускаем приложение Service Fabric в нашем удаленном кластере dev.Он состоит из нескольких сервисов с отслеживанием состояния и без сохранения состояния и имеет несколько интерфейсных API, работающих на Kestrel.

До настоящего времени, поскольку он не использовался для производства, Kestrel был настроен на использование самозаверяющего сертификата, которыйтакже использовался для обратного прокси-сервера и самого кластера, а служба работала непосредственно в домене по умолчанию, предоставленном Azure, <app>.<region>.cloudapp.azure.com.

. Теперь мы подошли к моменту разработки, когда самозаверяющий сертификатошибки становятся проблематичными, поскольку обратные вызовы сторонних производителей отклоняют соединение, поэтому было замечено, что пришло время начать использовать надлежащий домен и сертификат для него.

До сих пор я сделал следующее:

  • Добавлена ​​запись A для devcluster.somexampledomain.com -> нашего общедоступного IP-адреса для службы.
  • Создан сертификат приложения подстановочного знака Azure для *.someexampledomain.com.
  • Импортирован сертификат в AzureХранилище ключей.
  • Привязать сертификат к хранилищам секретов кластера, извлекая сертификатв Cert:/LocalMachine/My/
  • Изменил конфигурацию приложения для использования этого сертификата при инициализации Kestrel и проверил, что он найден при инициализации.
    • Пробовал с и без UseHsts() и UseHttpsRedirection()
    • Kestrel настроен с Listen(IPAddress.IPv6Any, endpoint.Port, ...) и UseHttps(X509Certificate2) на объекте параметров.
    • UseUrls(string) isиспользуется с URL-адресом по умолчанию, равным https://+:<port>, но попытался вручную добавить https://*:<port> и даже собственно имя хоста.

Независимо от того, что я пробовал, нет соединения HTTPSможет быть установлен на сервер.При использовании конечных точек других промежуточных серверов, которые все еще используют старый сертификат, он работает как положено.

Используя openssl s_client -connect devcluster.someexampledomain.com:<port> -prexit, я получаю:

---
no peer certificate available
---
No client certificate CA names sent
---

Нет ошибок или исключенийзашли на ETW, вроде бы все в порядке.Я подозреваю, что это может иметь какое-то отношение к CN сертификата, но у меня закончились идеи, чтобы попытаться выяснить, что происходит и как это исправить.

Я пытался разобраться в этом с помощьюFiddler и я мало что получим от этого, сессия просто заканчивается fiddler.network.https> HTTPS handshake to <myhost> (for #191) failed. System.IO.IOException Authentication failed because the remote party has closed the transport stream.

Кто-нибудь знает, как добавить некоторые записи на стороне Kestrel?Я не думаю, что установка Fiddler на виртуальные машины Azure, на которых работает мой кластер, является жизнеспособным решением.

1 Ответ

0 голосов
/ 01 ноября 2018

После изучения источника Kestrel я обнаружил, что он регистрируется под "Microsoft-AspNetCore-Server-Kestrel" и "Microsoft-Extensions-Logging", поэтому добавив передачу тех, кого я обнаружил, что происходит.

Соединения заканчивались со следующим исключением:

System.ComponentModel.Win32Exception (0x8009030D): The credentials supplied to the package were not recognized
   at System.Net.SSPIWrapper.AcquireCredentialsHandle(SSPIInterface secModule, String package, CredentialUse intent, SCHANNEL_CRED scc)
   at System.Net.Security.SslStreamPal.AcquireCredentialsHandle(CredentialUse credUsage, SCHANNEL_CRED secureCredential)
   at System.Net.Security.SslStreamPal.AcquireCredentialsHandle(X509Certificate certificate, SslProtocols protocols, EncryptionPolicy policy, Boolean isServer)
   at System.Net.Security.SecureChannel.AcquireServerCredentials(Byte[]& thumbPrint, Byte[] clientHello)
   at System.Net.Security.SecureChannel.GenerateToken(Byte[] input, Int32 offset, Int32 count, Byte[]& output)
   at System.Net.Security.SecureChannel.NextMessage(Byte[] incoming, Int32 offset, Int32 count)
   at System.Net.Security.SslState.StartSendBlob(Byte[] incoming, Int32 count, AsyncProtocolRequest asyncRequest)
   at System.Net.Security.SslState.ProcessReceivedBlob(Byte[] buffer, Int32 count, AsyncProtocolRequest asyncRequest)
   at System.Net.Security.SslState.PartialFrameCallback(AsyncProtocolRequest asyncRequest)
--- End of stack trace from previous location where exception was thrown ---
   at System.Net.Security.SslState.EndProcessAuthentication(IAsyncResult result)
   at System.Threading.Tasks.TaskFactory`1.FromAsyncCoreLogic(IAsyncResult iar, Func`2 endFunction, Action`1 endAction, Task`1 promise, Boolean requiresSynchronization)
--- End of stack trace from previous location where exception was thrown ---
   at Microsoft.AspNetCore.Server.Kestrel.Https.Internal.HttpsConnectionAdapter.InnerOnConnectionAsync(ConnectionAdapterContext context)
   at Microsoft.AspNetCore.Server.Kestrel.Core.Internal.HttpConnection.ApplyConnectionAdaptersAsync()

Это делает это проявлением проблемы с сертификатом на новом компьютере - учетные данные, предоставленные для пакета, не распознаны .

Я потратил некоторое время, пытаясь выяснить, чтолучший способ разобраться в этом - документация Service Fabric , в которой есть скрипт для изменения разрешений, но он звучит неправильно.

Как оказалось, это можно сделать напрямую.в ApplicationManifest следующим образом:

<Principals>
    <Users>
        <User Name="NETWORK SERVICE" AccountType="NetworkService" />
    </Users>
</Principals>
<Policies>
    <SecurityAccessPolicies>
        <SecurityAccessPolicy ResourceRef="HttpsCert2" PrincipalRef="NETWORK SERVICE" ResourceType="Certificate" />
    </SecurityAccessPolicies>
</Policies>
<Certificates>
    <SecretsCertificate X509FindValue="[HttpsCertThumbprint]" Name="HttpsCert" />
</Certificates>

Чтобы SecurityAccessPolicy найти ResourceRef, он должен был быть SecretsCertificate, а не EndpointCertificate.Поскольку для EndpointBindingPolicy требуется EndpointCertificate, я просто добавил SecretsCertificate и EndpointCertificate с разными именами.Они оба ссылаются на один и тот же сертификат, так что это сработало.Мне не очень приятно их удваивать, но сейчас у меня есть решение.

...