4

我一直在尝试按照我可以找到的 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;
    });
4

1 回答 1

4

深入研究您的代码,我意识到除了一件事之外没有任何问题。我的意思是,当你使用 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 地址。

于 2018-03-15T08:43:56.587 回答