HTTPS 不适用于在具有自定义域的 Service Fabric 上运行的 Kestrel 3.2.187/ASPNET Core 2.1.5

Posted

技术标签:

【中文标题】HTTPS 不适用于在具有自定义域的 Service Fabric 上运行的 Kestrel 3.2.187/ASPNET Core 2.1.5【英文标题】:HTTPS not working with Kestrel 3.2.187/ASPNET Core 2.1.5 running on the Service Fabric with a custom domain 【发布时间】:2019-03-27 21:24:42 【问题描述】:

我们正在远程开发集群上运行 Service Fabric 应用程序。它由多个有状态和无状态服务组成,并由多个在 Kestrel 上运行的前端 API 构成。

到目前为止,由于没有用于生产,Kestrel 被配置为使用自签名证书,该证书也用于反向代理和集群本身,并且服务直接在 Azure 提供的默认域上运行, <app>.<region>.cloudapp.azure.com.

我们现在正处于开发阶段,自签名证书错误成为问题,第三方回调拒绝连接,因此现在被视为开始使用适当的域和证书的时候了。

到目前为止,我做了以下工作:

devcluster.somexampledomain.com 添加了一条 A 记录 -> 我们的服务公共 IP。 为*.someexampledomain.com 创建了通配符 Azure 应用程序证书。 已将证书导入 Azure Key Vault。 将证书绑定到集群的Vault Secrets,拉取证书到Cert:/LocalMachine/My/ 修改了应用程序配置以在初始化 Kestrel 时使用此证书,并验证在初始化时已找到它。 尝试使用和不使用UseHsts()UseHttpsRedirection() Kestrel 在选项对象上配置了Listen(IPAddress.IPv6Any, endpoint.Port, ...)UseHttps(X509Certificate2)UseUrls(string) 与默认 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 端添加一些日志记录吗?我不认为在运行我的集群的 Azure VM 上安装 Fiddler 是一个可行的解决方案。

【问题讨论】:

【参考方案1】:

深入研究 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()

这使它成为Certificate problem with a new machine - credentials supplied to package not recognized的体现。

我花了一些时间试图弄清楚解决这个问题的最佳方法是什么,Service Fabric documentation 有一个脚本可以修改权限,但这听起来不对。

事实证明,这可以直接在 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,我只添加了SecretsCertificateEndpointCertificate,但名称不同。他们都指的是同一个证书,所以它起作用了。不得不将它们加倍感觉不是特别干净,但这是我目前的解决方案。

【讨论】:

以上是关于HTTPS 不适用于在具有自定义域的 Service Fabric 上运行的 Kestrel 3.2.187/ASPNET Core 2.1.5的主要内容,如果未能解决你的问题,请参考以下文章

自定义样式不适用于 angular 10

缩进不适用于自定义 UITableViewCell

Google协作平台应用脚本不适用于自定义域

setText 不适用于自定义 Edittext

VueJS - 绑定自定义道具不适用于 b-form 组件

在 PhP、Wordpress 和 MySQL 中,查找最近的位置的功能不适用于自定义表