ServiceFabric本地群集SSL

时间:2018-06-17 11:36:56

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

我对在本地主机上使用SSL在本地群集上运行SF有一些误解。 Microsoft已创建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核心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核心模板)。通过修改ServiceManifest.xml部分更改我的Endpoint

<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

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

P.P.S我是创建证书的新手,但看起来很奇怪。

  1. 我已经CertSetup.ps1安装了pfx。 一切正常(资源可以访问)。
  2. 然后我使用私钥所有扩展属性
  3. 将证书导出到pfx
  4. 从LocalMachine(MY和Root)删除,CurrentUser(MY)存储
  5. 将导出的pfx安装到LocalMachine(我的和根目录),CurrentUser(我的)商店
  6. 重建&amp;重新部署代码
  7. 无法到达Resoucre
  8. 这是魔术吗?或者我错过了什么?

1 个答案:

答案 0 :(得分:0)

对于我来说,情侣的细节并不是很清楚。回答: 如果您尝试使用自己生成的证书(openssl,makecert等),则应为NETWORK SERVICE设置权限。

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

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