我一直在尝试按照微软文档和我能找到的各种帖子/博客上的说明在无状态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
我在instancelistener 中的代码中的
.UseKestrel(options =>
{
options.Listen(IPAddress.Any, 44338, listenOptions =>
{
listenOptions.UseHttps(GetCertificate());
});
})
servicemanifest
<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广告和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;
});
答案 0 :(得分:4)
深入研究你的代码我已经意识到除了一件事之外没有任何问题。我的意思是,当您使用Kestrel时,您不需要在AppManifest中设置任何额外内容,因为这些内容适用于Http.Sys实现。您甚至不需要在ServiceManifest中有一个端点(尽管建议使用),因为所有这些都是关于服务帐户和SSL绑定配置的URL保留,这两者都不是Kestrel所必需的。
您需要做的是在配置SSL时使用IPAddress.IPv6Any。除了事实证明它是允许您同时接受IPv4和IPV6连接的推荐方式之外,它还具有“正确”的正确性。 SF中的端点注册。请参阅,当您使用IPAddress.Any时,您将获得SF设置端点,如https://0.0.0.0:44338,以及反向代理将如何尝试到达服务,这显然不会“工作。 0.0.0.0并不对应任何特定的IP,它只是说“任何IPv4地址”的方式。当您使用IPAddress.IPv6Any时,您将获得映射到vm ip地址的正确端点,该端点可以从vnet中解析。如果您转到服务实例刀片中的端点部分,您可以在SF Explorer中自己查看这些内容。