【问题标题】:ServiceFabric Local Cluster SSLServiceFabric 本地集群 SSL
【发布时间】:2018-11-26 12:28:03
【问题描述】:

我对在 localhost 上使用 SSL 在本地集群上运行 SF 有一些误解。 微软创建了greate article about configuring HTTPS on your endpoints 但只有如果你使用他们的证书生成器 CertSetup.ps1 才能正常工作。如果您尝试安装自己的 pfx,它将无法正常工作。

首先我通过 OpenSSL 创建了 localhost 自签名证书:

set OPENSSL_CONF=W:\OpenSSL-Win32\bin\openssl.cfg
openssl genrsa -out W:\CERTS\wepapissl.key -passout pass:1234567890 -aes256 2048
openssl req -x509 -new -key W:\CERTS\wepapissl.key -days 10000 -out W:\CERTS\wepapissl.crt -passin pass:1234567890 -subj /CN="localhost"
openssl pkcs12 -export -inkey W:\CERTS\wepapissl.key -in W:\CERTS\wepapissl.crt -out W:\CERTS\wepapissl.pfx -passout pass:0987654321 -passin pass:1234567890`

第二 我已经创建了默认的 ASP.NET Core Web 应用程序(Core 2.0,API 模板)。并添加了配置 Kestrel 以使用 HTTPS 的代码:

public static IWebHost BuildWebHost(string[] args) =>
        WebHost.CreateDefaultBuilder(args)
            .UseKestrel(opt =>
            {
                opt.Listen(IPAddress.Any, port, listenOptions =>
                {
                    listenOptions.UseHttps(GetCertificateFromStore());
                });
            })
            .UseStartup<Startup>()
            .Build();

private static X509Certificate2 GetCertificateFromStore()
    {
        var store = new X509Store(StoreName.My, StoreLocation.LocalMachine);
        try
        {
            store.Open(OpenFlags.ReadOnly);
            var certCollection = store.Certificates;
            var currentCerts = certCollection.Find(X509FindType.FindBySubjectDistinguishedName, "CN=localhost", false);
            return currentCerts.Count == 0 ? null : currentCerts[0];
        }
        finally
        {
            store.Close();
        }
    }

我得到了预期的结果。带有网站安全证书警告的页面: Result from ValueController with warning

第三我创建了 Service Fabric 应用程序(无状态 ASP.NET Core 模板)。通过编辑Endpoint 部分更改我的ServiceManifest.xml

<Endpoint Protocol="https" Name="ServiceEndpoint" Type="Input" Port="8256" />

并添加了配置 Kestrel 以使用 HTTPS (class Web1 : StatelessService) 的代码:

    protected override IEnumerable<ServiceInstanceListener> CreateServiceInstanceListeners()
    {
        return new ServiceInstanceListener[]
        {
            new ServiceInstanceListener(serviceContext =>
                new KestrelCommunicationListener(serviceContext, "ServiceEndpoint", (url, listener) =>
                {
                    ServiceEventSource.Current.ServiceMessage(serviceContext, $"Starting Kestrel on {url}");

                    return new WebHostBuilder()
                                .UseKestrel(opt =>
                                {
                                    int port = serviceContext.CodePackageActivationContext.GetEndpoint("ServiceEndpoint").Port;
                                    opt.Listen(IPAddress.IPv6Any, port, listenOptions => 
                                    {
                                        listenOptions.UseHttps(this.GetCertificateFromStore());
                                    });
                                })
                                .ConfigureServices(
                                    services => services
                                        .AddSingleton<StatelessServiceContext>(serviceContext))
                                .UseContentRoot(Directory.GetCurrentDirectory())
                                .UseStartup<Startup>()
                                .UseServiceFabricIntegration(listener, ServiceFabricIntegrationOptions.None)
                                .UseUrls(url)
                                .Build();
                }))
        };
    }

    private X509Certificate2 GetCertificateFromStore()
    {
        var store = new X509Store(StoreName.My, StoreLocation.LocalMachine);
        try
        {
            store.Open(OpenFlags.ReadOnly);
            var certCollection = store.Certificates;
            var currentCerts = certCollection.Find(X509FindType.FindBySubjectDistinguishedName, "CN=localhost", false);
            return currentCerts.Count == 0 ? null : currentCerts[0];
        }
        finally
        {
            store.Close();
        }
    }

结果:在本地 SF 集群上成功构建和部署代码。 But my resource can't be reached

附:我再重复一遍,如果您使用 Mircosoft 提供的 PowerShell -CertSetup.ps1 安装新证书,它适用于 SF 应用程序。我试图挖掘 PS 脚本,但我无法理解我错过了什么。

P.P.S 我是创建证书的新手,但这似乎很奇怪。

  1. 我已经通过CertSetup.ps1 安装了pfx。 一切正常(资源可达)。
  2. 然后我使用 私钥所有扩展属性 将证书导出到 pfx
  3. 从 LocalMachine(MY 和 Root)、CurrentUser (MY) 存储中删除
  4. 将导出的 pfx 安装到 LocalMachine(My 和 Root)、CurrentUser (My) 商店
  5. 重建和重新部署代码
  6. 无法到达资源

这是魔法吗?还是我错过了什么?

【问题讨论】:

    标签: ssl openssl localhost kestrel azure-service-fabric


    【解决方案1】:

    无论如何,一些细节对我来说还不够清楚。回答: 如果您尝试使用自己生成的证书(openssl、makecert 等),您应该为 NETWORK SERVICE 设置权限。

    To manually do this on your dev box, open up certlm.msc, expand Personal-&gt;Certificates, and right-click your cert. Select All Tasks-&gt;Manage private keys and then add NETWORK SERVICE.

    更多:https://github.com/Azure/service-fabric-issues/issues/714#issuecomment-381281701

    【讨论】:

      猜你喜欢
      • 2017-10-16
      • 2017-01-31
      • 2017-08-05
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-04-17
      • 1970-01-01
      • 2018-12-27
      相关资源
      最近更新 更多