带有 kestrel 和反向代理的 Service Fabric https 端点
Service Fabric https endpoint with kestrel and reverse proxy
我一直在尝试按照 Microsoft 文档和我能找到的各种 post/blogs 上的说明在无状态 API 端点上设置 Https。它在本地运行良好,但在我的开发服务器上部署它后,我正在努力使其工作 getting
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());
});
})
服务清单
<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"
}
]
}
],
不确定还有什么相关的,如果你有任何ideas/suggestions,非常欢迎
编辑: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;
});
深入研究您的代码后,我意识到除了一件事之外没有任何问题。我的意思是,当您使用 Kestrel 时,您不需要在 AppManifest 中设置任何额外的东西,因为这些东西是用于 Http.Sys 实现的。您甚至不需要在 ServiceManifest 中有端点(尽管推荐),因为所有这些都是关于 URL 服务帐户和 SSL 绑定配置的预留,而 Kestrel 不需要这两者。
您需要做的是在配置 SSL 时使用 IPAddress.IPv6Any。除了事实证明它是允许您接受 IPv4 和 IPV6 连接的推荐方式之外,它还在 SF 中进行 'correct' 端点注册。看,当您使用 IPAddress.Any 时,您将让 SF 设置一个像 https://0.0.0.0:44338 这样的端点,这就是反向代理将如何尝试访问显然无法正常工作的服务。 0.0.0.0 不对应任何特定的 ip,它只是 'any IPv4 address at all' 的表达方式。当您使用 IPAddress.IPv6Any 时,您将获得映射到可以从 vnet 内解析的 vm ip 地址的正确端点。如果您转到服务实例边栏选项卡中的端点部分,您可以自己在 SF Explorer 中看到这些内容。
我一直在尝试按照 Microsoft 文档和我能找到的各种 post/blogs 上的说明在无状态 API 端点上设置 Https。它在本地运行良好,但在我的开发服务器上部署它后,我正在努力使其工作 getting
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());
});
})
服务清单
<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"
}
]
}
],
不确定还有什么相关的,如果你有任何ideas/suggestions,非常欢迎
编辑: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;
});
深入研究您的代码后,我意识到除了一件事之外没有任何问题。我的意思是,当您使用 Kestrel 时,您不需要在 AppManifest 中设置任何额外的东西,因为这些东西是用于 Http.Sys 实现的。您甚至不需要在 ServiceManifest 中有端点(尽管推荐),因为所有这些都是关于 URL 服务帐户和 SSL 绑定配置的预留,而 Kestrel 不需要这两者。
您需要做的是在配置 SSL 时使用 IPAddress.IPv6Any。除了事实证明它是允许您接受 IPv4 和 IPV6 连接的推荐方式之外,它还在 SF 中进行 'correct' 端点注册。看,当您使用 IPAddress.Any 时,您将让 SF 设置一个像 https://0.0.0.0:44338 这样的端点,这就是反向代理将如何尝试访问显然无法正常工作的服务。 0.0.0.0 不对应任何特定的 ip,它只是 'any IPv4 address at all' 的表达方式。当您使用 IPAddress.IPv6Any 时,您将获得映射到可以从 vnet 内解析的 vm ip 地址的正确端点。如果您转到服务实例边栏选项卡中的端点部分,您可以自己在 SF Explorer 中看到这些内容。