【问题标题】:Service Fabric https endpoint with kestrel and reverse proxy带有红隼和反向代理的 Service Fabric https 端点
【发布时间】:2018-08-21 23:32:51
【问题描述】:

我一直在尝试按照我可以找到的 microsoft 文档和各种帖子/博客上的说明在无状态 API 端点上设置 Https。它在本地运行良好,但在我的开发服务器上部署后我很难让它工作

Browser : HTTP ERROR 504
Vm event viewer : HandlerAsyncOperation EndProcessReverseProxyRequest failed with FABRIC_E_TIMEOUT
SF event table : Error while processing request: request url = https://mydomain:19081/appname/servicename/api/healthcheck/ping, verb = GET, remote (client) address = xxx, request processing start time = 2018-03-13T14:50:17.1396031Z, forward url = https://0.0.0.0:44338/api/healthcheck/ping, number of successful resolve attempts = 48, error = 2147949567, message = , phase = ResolveServicePartition

在实例监听器中的代码中

    .UseKestrel(options =>
    {
       options.Listen(IPAddress.Any, 44338, listenOptions =>
       {
           listenOptions.UseHttps(GetCertificate());
       });
    })

服务清单

<Endpoint Protocol="https" Name="SslServiceEndpoint" Type="Input" Port="44338" />

启动

        services.AddMvc(options =>
        {
            options.SslPort = 44338;
            options.Filters.Add(new RequireHttpsAttribute());
        });

+

            var options = new RewriteOptions().AddRedirectToHttps(StatusCodes.Status301MovedPermanently, 44338);
        app.UseRewriter(options);

这是我在 azure 中得到的(通过 ARM 模板部署)

Health probes
NAME                    PROTOCOL    PORT    USED BY
AppPortProbe            TCP         44338   AppPortLBRule
FabricGatewayProbe      TCP         19000   LBRule
FabricHttpGatewayProbe  TCP         19080   LBHttpRule
SFReverseProxyProbe     TCP         19081   LBSFReverseProxyRule

Load balancing rules
NAME                    LOAD BALANCING RULE                 BACKEND POOL                    HEALTH PROBE
AppPortLBRule           AppPortLBRule (TCP/44338)           LoadBalancerBEAddressPool       AppPortProbe
LBHttpRule              LBHttpRule (TCP/19080)              LoadBalancerBEAddressPool       FabricHttpGatewayProbe
LBRule                  LBRule (TCP/19000)                  LoadBalancerBEAddressPool       FabricGatewayProbe
LBSFReverseProxyRule    LBSFReverseProxyRule (TCP/19081)    LoadBalancerBEAddressPool       SFReverseProxyProbe

我有一个集群证书、ReverseProxy 证书,并通过 azure ad 和 ARM 对 api 进行身份验证

                "fabricSettings": [
                {
                    "parameters": [
                        {
                            "name": "ClusterProtectionLevel",
                            "value": "[parameters('clusterProtectionLevel')]"
                        }
                    ],
                    "name": "Security"
                },
                {
                    "name": "ApplicationGateway/Http",
                    "parameters": [
                      {
                        "name": "ApplicationCertificateValidationPolicy",
                        "value": "None"
                      }
                    ]
                }
            ],

不确定还有什么相关的,如果您有任何想法/建议,非常欢迎

编辑:GetCertificate() 的代码

    private X509Certificate2 GetCertificate()
    {
        var certificateBundle = Task.Run(async () => await GetKeyVaultClient()
            .GetCertificateAsync(Environment.GetEnvironmentVariable("KeyVaultCertifIdentifier")));
        var certificate = new X509Certificate2();
        certificate.Import(certificateBundle.Result.Cer);
        return certificate;
    }

    private KeyVaultClient GetKeyVaultClient() => new KeyVaultClient(async (authority, resource, scope) =>
    {
        var context = new AuthenticationContext(authority, TokenCache.DefaultShared);
        var clientCred = new ClientCredential(Environment.GetEnvironmentVariable("KeyVaultClientId"),
            Environment.GetEnvironmentVariable("KeyVaultSecret"));
        var authResult = await context.AcquireTokenAsync(resource, clientCred);
        return authResult.AccessToken;
    });

【问题讨论】:

  • 您是否在 AplicationManifest 中配置了端点绑定?除此之外,如果你登录到你的开发机器并检查端口,你看到 44338 打开了吗?我建议的另一件事是在您的 ServiceManifest 中启用 ConsoleRedirection 日志记录,以查看是否会弹出任何有意义的内容。当然,您可以在事件查看器中验证 SF 日志。
  • 您好,感谢您的回复,端口是开放的。根据 microsoft doc (docs.microsoft.com/en-us/azure/service-fabric/…),这将是 EndpointCertificate 和 EndpointBindingPolicy?我不确定它指的是哪个证书,是集群还是反向代理?我担心的最后一件事是服务器上的 ACL,我读到它可能是错误的,正在研究如何检查并在必要时进行更改
  • 参考这个例子 - matt.kotsenas.com/posts/https-in-service-fabric-web-api。您将在那里找到如何将 AppManifest 中的服务与证书联系起来。不过,这与反向代理无关,而是告诉 SF 它应该与端点绑定什么证书。还要确保你的证书安装在开发机器上。
  • 由于链接根本不涉及反向代理,我想那就是集群证书。所有使用的证书都在 ARM 模板中定义,因此它“应该”已经在正确的位置。我会尝试所有这些,谢谢您的帮助。
  • 在将缺少的内容添加到 appmanifest 后仍然无法正常工作。尽管我有这种消息“ERROR_WINHTTP_CANNOT_CONNECT”或“Re-resolved service url = 0.0.0.0:44338/api/healthcheck/ping”,但我重新部署了集群以将日志设置为详细。 0.0.0.0:44338 看起来有点奇怪......

标签: https reverse-proxy azure-service-fabric kestrel


【解决方案1】:

深入研究您的代码,我意识到除了一件事之外没有任何问题。我的意思是,当你使用 Kestrel 时,你不需要在 AppManifest 中设置任何额外的东西,因为这些东西是用于 Http.Sys 实现的。您甚至不需要在 ServiceManifest 中有一个端点(尽管推荐),因为所有这些都是关于服务帐户的 URL 保留和 SSL 绑定配置,而 Kestrel 都不需要这些。

您需要做的是在配置 SSL 时使用 IPAddress.IPv6Any。除了事实证明它是允许您接受 IPv4 和 IPV6 连接的推荐方式之外,它还在 SF 中进行“正确”端点注册。看,当您使用 IPAddress.Any 时,您将让 SF 设置像 https://0.0.0.0:44338 这样的端点,这就是反向代理将尝试访问显然无法工作的服务的方式。 0.0.0.0 不对应任何特定的 ip,它只是说“任何 IPv4 地址”的方式。当您使用 IPAddress.IPv6Any 时,您将获得一个正确的端点映射到可以从 vnet 中解析的 vm ip 地址。如果您转到服务实例刀片中的端点部分,您可以自己在 SF Explorer 中看到这些内容。

【讨论】:

  • 端点绑定确实是一个失误,对于第二点,我真的不确定,这个实现的重点是在密钥库而不是本地存储中获取证书,将挖掘有点静止,但我希望有更多与昨天提到的错误(ERROR_WINHTTP_CANNOT_CONNECT)相关的网络,所以我相信我需要更多地了解探针/lb规则的工作原理
  • SF 在启动和运行服务时没有获得密钥库的证书。设置 VM 以在群集中安装证书时使用密钥库。如果本地无法到达端点,则与probes/lb规则无关。
  • 我是否尝试过以正确的方式访问它(ping localhost:44338/appname/servicename/api/healthcheck/ping)?以这种方式在运行时检查证书对 localhost 来说效果很好,我以为在我的开发集群上部署时它会是一样的,好吧会测试这个
  • 尝试在 vm 上使用管理员帐户执行 winhttpcertcfg,得到:错误:未成功获取私钥的访问权限。这只能由安装证书的用户完成。
  • @GrayCat 我有点想通了 :) 我的意思是在我做实验的时候。还没有就此事调查SF的内部情况。但是,即使这不是解释,这里有一个链接,SF 团队准确指出您需要使用 IPv6Any - Configure Kestrel to use HTTPS
猜你喜欢
  • 2021-01-11
  • 2017-09-08
  • 2017-05-31
  • 2018-02-07
  • 2017-10-16
  • 2018-04-23
  • 1970-01-01
  • 2017-10-19
  • 2020-09-17
相关资源
最近更新 更多