https 与 Service Fabric 本地群集管理器
Posted
技术标签:
【中文标题】https 与 Service Fabric 本地群集管理器【英文标题】:https with Service Fabric Local Cluster Manager 【发布时间】:2021-08-22 11:05:44 【问题描述】:我开发 Service Fabric 应用程序,并且我在本地安装了 Service Fabric SDK,它提供了有用的 Service Fabric 本地集群管理器 (servicefabriclocalclustermanager.exe)(如果是稀疏的)。默认情况下,这似乎只支持http。没有明显的方法可以从 UI 创建 https 集群。我做了一些研究,并设法为自己创建了一个 https 集群,但为了做到这一点,我必须手动修改 ClusterConfig.json 文件并运行 CreateServiceFabricCluster.ps1 powershell 脚本。这不与 Service Fabric 本地集群管理器集成,如果我想操作它,我基本上必须使用 powershell 命令。这是可以管理的,但如果可能的话,使用系统托盘小部件会容易得多。
有没有办法将 Service Fabric 本地集群管理器与为 https 配置的本地集群一起使用?我知道 C:\Program Files\Microsoft SDKs\Service Fabric\ClusterSetup 中有一大堆脚本,这似乎是 Service Fabric 本地集群管理器用来配置与之交互的集群的内容,并且有安全版本那些脚本,但我不知道如何使用它们。
【问题讨论】:
我对此的第一个看法是询问您为什么需要这样做。本地集群管理器旨在用于本地开发目的。在 Azure 上运行的集群管理器默认配置为使用 HTTPS(因为您将必要的证书设置为该配置的一部分)。您打算使用本地 HTTPS 实现什么目标? 我们有一个大型遗留应用程序,我们目前正在将其转变为一组服务结构微服务(慢慢地)。我们最近开始为该应用程序使用 https,这在 prod 中很好,我们的微服务也是 https。然而,我们的开发环境现在是 https 应用程序和 http 微服务的尴尬组合。一些微服务具有我们通过 iframe 嵌入到主应用程序中的 UI。这不再有效,因为 iframe 内容是不安全的,而主机是安全的。我无法更改大应用程序,只能更改我的 SF 集群。 我想我仍然不理解对集群管理器的依赖,因为它只是启动用于监控集群的 SF explorer。 HTTPS 实际上应该只关注单个服务,而这只是确保您为每个服务提供可用的端点 + 服务设置的问题。您选择如何监控它(使用 SFX 或其他工具)应该与此无关。 无论如何,它并不涉及开发集群本身,但您可能会在 standalone guidance 中找到一些有用的提示,因为它提到了您将用于在其上创建安全集群的各种安全脚本-前提。但同样,请注意,它还提到此证书保护集群维护操作(例如通过 SFX 或 PowerShell),您自己的应用程序不一定要依赖它。 谢谢。我已经使用独立的文档来达到我现在的位置,并且它有点工作。我想真正的问题是我们在服务结构中使用了反向代理,而这需要使用 https 进行设置。我可以做到,它工作正常,但工作流程不是很好。我会继续加油的。如果由我决定,我会将主应用程序设置回 http 并完全避免这个问题,但是嘿嘿...... :) 【参考方案1】:这是我使用了一段时间的解决方案。
这里的关键是创建自己的自定义 Https 证书定位器 并使用它根据您的 环境。例如,在本地使用默认值是有意义的
localhost
由 Visual Studio 工具创建的 HTTPS 证书。在 您可能需要根据其他环境识别正确的证书 一些标准,例如它的通用名称。
覆盖CreateServiceInstanceListeners
无状态服务中的CreateServiceInstanceListeners
操作以配置https 端口。这也是您提供自定义 HttpsCertificateLocator
实现的地方。
protected override IEnumerable<ServiceInstanceListener> CreateServiceInstanceListeners()
return new ServiceInstanceListener[]
new ServiceInstanceListener(serviceContext =>
new KestrelCommunicationListener(serviceContext, "ServiceEndpoint", (url, listener) =>
return new WebHostBuilder()
.UseKestrel(opt =>
int port = serviceContext.CodePackageActivationContext.GetEndpoint("ServiceEndpoint").Port;
opt.Listen(IPAddress.IPv6Any, port, listenOptions =>
listenOptions.UseHttps(new HttpsCertificateLocator().GetHttpsCertificateFromStore());
);
)
示例 HTTPS 证书定位器
public class HttpsCertificateLocator : BaseHttpsCertificateLocator, IHttpsCertificateLocator
private readonly string[] _cNsToTryInOrderOfPriority;
private readonly bool _isDevelopment;
private const string Development = nameof(Development);
public HttpsCertificateLocator(string environmentName = null, string[] cNsToTryInOrderOfPriority = null)
_cNsToTryInOrderOfPriority = cNsToTryInOrderOfPriority ?? CommonCertificates.Intranet.DefaultCNs;
var environment = string.IsNullOrWhiteSpace(environmentName)
? (System.Environment.GetEnvironmentVariable("ASPNETCORE_ENVIRONMENT") ?? Development)
: environmentName;
_isDevelopment = string.Compare(environment, Development, StringComparison.OrdinalIgnoreCase) == 0;
/// <summary>
/// If environment is Development, finds and returns the ASP .NET Core HTTPS development certificate in development environment.
/// In other developments, returns a HTTPS certificate that is assumed installed on all Service Fabric cluster nodes
/// </summary>
public X509Certificate2 GetHttpsCertificateFromStore(bool httpsMandatory = true)
if (_isDevelopment)
return ReturnDevCertificate(httpsMandatory);
using (X509Store store = new X509Store(StoreName.My, StoreLocation.LocalMachine))
store.Open(OpenFlags.ReadOnly);
var certCollection = store.Certificates;
foreach (var subjectName in _cNsToTryInOrderOfPriority)
var matchingCerts = certCollection.Find(X509FindType.FindBySubjectDistinguishedName, subjectName, true);
if (matchingCerts.Count > 0)
return EnsureMostRecentCertificate(matchingCerts, subjectName, httpsMandatory);
return EnsureMostRecentCertificate(
new X509Certificate2Collection(),
_cNsToTryInOrderOfPriority.LastOrDefault() ?? "<NONE SPECIFIED>",
httpsMandatory);
以上代码继承自BaseHttpsCertificateLocator
。它提供了额外的功能来定位默认的开发localhost
HTTPs 证书。它还具有查找最新证书的代码(开始滚动证书时必须处理的事情)。
public abstract class BaseHttpsCertificateLocator
protected X509Certificate2 ReturnDevCertificate(bool httpsMandatory)
// Note: AspNet Core should auto generate/install this X509 cert on dev PCs
const string aspNetHttpsOid = "1.3.6.1.4.1.311.84.1.1";
const string cnLocalhost = "CN=localhost";
using (X509Store store = new X509Store(StoreName.My, StoreLocation.LocalMachine))
store.Open(OpenFlags.ReadOnly);
var certCollection = store.Certificates;
var currentCerts = certCollection.Find(X509FindType.FindByExtension, aspNetHttpsOid, true);
var matchingCerts = currentCerts.Find(X509FindType.FindByIssuerDistinguishedName, cnLocalhost, true);
return EnsureMostRecentCertificate(matchingCerts, cnLocalhost, httpsMandatory);
protected X509Certificate2 EnsureMostRecentCertificate(
X509Certificate2Collection marchingCerts,
string cnName,
bool httpsMandatory)
if (marchingCerts.Count == 0)
return httpsMandatory
? throw new SecurityException($"Unable to locate HTTPS X509 cert `cnName`")
: default(X509Certificate2);
if (marchingCerts.Count > 1)
return marchingCerts.Cast<X509Certificate2>().OrderByDescending(x => x.NotAfter).First();
return marchingCerts[0];
【讨论】:
这看起来像是为单个应用程序启用了 https,对吗?如果是这样,那是我可以做的,但不幸的是,它并不能解决我的问题。我正在寻找的是一种使用 https 获取整个集群的方法。 Service Fabric Explorer、Service Fabric Cluster Manager、反向代理(对我们来说最重要的是反向代理)一切。在我们的开发环境中,应用程序是通过反向代理访问的,主要是因为它很好地映射到我们设置 API 管理内容的方式,因此是整个集群方法。 正确 - 每个应用程序。如果要提供端到端的 https 加密,则必须在单个应用程序级别进行;您当然可以为所有应用重复使用相同的通配符证书。除此之外,只有其他方式是通过反向代理 - 使用 SF 反向代理或第 3 方。不幸的是,不确定如何破解本地集群管理器以使用 https。以上是关于https 与 Service Fabric 本地群集管理器的主要内容,如果未能解决你的问题,请参考以下文章
Service Fabric小白入门记录 本地Service Fabric集群安装及设置
在本地部署 Service Fabric 项目:“FABRIC_E_IMAGEBUILDER_UNEXPECTED_ERROR”
在 Linux 中创建 Azure Service Fabric 本地集群
您是不是可以在本地调试 Service Fabric 群集?