【问题标题】:Install a certificate for a local cluster为本地集群安装证书
【发布时间】:2016-10-03 19:17:57
【问题描述】:

我有一些代码可以通过 Azure Key Vault 进行身份验证,以便检索一些机密。我使用客户端 ID 和证书而不是客户端 ID 和密钥进行身份验证。此代码在普通控制台应用程序中运行良好:

var store = new X509Store(StoreName.My, StoreLocation.CurrentUser);
try
{
    store.Open(OpenFlags.ReadOnly);

    var matchingCertificates = store.Certificates.Find(X509FindType.FindByThumbprint, thumbprint, false);
    if (matchingCertificates.Count != 1)
    {
        return null;
    }

    return matchingCertificates[0];
}
finally
{
    if (store != null) store.Close();
}

一旦我尝试在有状态服务应用程序中使用此代码,它就无法再找到证书。

如何安装证书以供本地集群使用?

【问题讨论】:

    标签: c# azure-service-fabric


    【解决方案1】:

    这不能按原样工作的原因是因为 Service Fabric 在 NETWORK SERVICE 帐户下运行,该帐户在没有配置的情况下无权访问证书。

    至少对我们来说,在使用 Microsoft.Azure.KeyVault 提供的KeyVaultClient 使用证书连接到 Key Vault 时,这种情况会导致“密钥集不存在”异常。

    解决方案是将证书包含在您的 ApplicationManifest.xml 中,这会指示 Service Fabric 授予 NETWORK SERVICE 帐户对证书的访问权限;

    <ApplicationManifest>
       <!-- snip -->
       <Principals>
          <Users>
             <User Name="NetworkServiceAccount" AccountType="NetworkService" />
          </Users>
       </Principals>
       <Policies>
          <SecurityAccessPolicies>
             <SecurityAccessPolicy ResourceRef="KeyVaultCert" PrincipalRef="NetworkServiceAccount" GrantRights="Full" ResourceType="Certificate" />
          </SecurityAccessPolicies>
       </Policies>
       <Certificates>
          <SecretsCertificate X509FindValue="1ABCD86B815F37123459A34C1BA9EDEBABCEDF1" Name="KeyVaultCert" />
       </Certificates>
    </ApplicationManifest>
    

    ... 其中NetworkServiceAccountKeyVaultCert 都是&lt;SecurityAccessPolicy /&gt; 元素用来引用用户和证书的任意名称。

    另见https://azure.microsoft.com/en-us/documentation/articles/service-fabric-application-runas-security/#a-complete-application-manifest-example

    【讨论】:

    • 这是更好的答案,更干净,更容易。完美无瑕!
    • 此解决方案似乎不支持证书翻转。 Azure Service Fabric 不会使用“netsh http ssl remove ..”之类的内容取消注册端口,并且使用新指纹升级应用程序失败...
    • 一个让我很恼火的澄清:确保将您的证书安装到 LOCALMACHINE(不是 CurrentUser)位置。如果您只是在 *.pfx/cer 文件上单击 dbl,那么它将转到 CurrentUser。这将在代码包部署步骤中为您提供 FABRIC_E_CERTIFICATE_NOTFOUND 错误。
    • @SatThiru 如果通过 VM 规模集资源添加证书(有关信息,请参阅 here),证书会自动安装在 LocalMachine 存储中。
    【解决方案2】:

    Service Fabric 应用程序在 NETWORK SERVICE 帐户下运行,因此您需要确保该帐户具有对证书的访问/权限。

    编辑:

    对于在本地机器上运行的集群,您可以通过使用 certmgr.msc 或相关的 mmc 管理单元找到证书,然后右键单击 > 所有任务 > 管理私钥,然后授予网络服务读取权限。

    对于 Azure 中的远程群集,您可以在规模集的 VM 上使用 custom script extension 来执行此操作,该 VM 将运行 PowerShell 脚本来设置所需的权限。例如,它可以执行以下操作:

    $certificate = Get-ChildItem -Path Cert:\LocalMachine\My | Where-Object {$_.Thumbprint -eq $certificateThumbprint}
    
    # Get file path
    $certificateFilePath = "C:\Documents and Settings\All Users\Application Data\Microsoft\Crypto\RSA\MachineKeys\" + $cert.PrivateKey.CspKeyContainerInfo.UniqueKeyContainerName
    
    # Take ownership of the file so that permissions can be set
    takeown /F $certificateFilePath
    
    # Give the NETWORK SERVICE read permissions
    $acl = (Get-Item $certificateFilePath).GetAccessControl('Access')
    $rule = new-object System.Security.AccessControl.FileSystemAccessRule "NETWORK SERVICE","Read","Allow"
    $acl.SetAccessRule($rule)
    Set-Acl -Path $certificateFilePath -AclObject $acl
    

    【讨论】:

    • 所以它仍然会看到安装在我本地机器上的所有证书,只要它可以访问它们?
    • 是的,没错。您可以通过在 ApplicationManifest.xml 中定义用户、组和访问策略,让 Service Fabric 自动授予对特定证书的访问权限,而不是手动授予访问权限。有关设置的更多信息,请参阅此文档:azure.microsoft.com/en-us/documentation/articles/…
    • 您能否提供有关如何授予对 Service Fabric 中证书的访问权限的更多详细信息?该文档讨论了 SSL 端点证书,但这不是我的用例。我正在使用证书私钥对 KeyVault 资源进行身份验证。
    • 我已经在规模集的 VM 定义上使用自定义脚本扩展来完成此操作,该扩展将运行脚本来设置这些权限。但是,@VaclavTurecek 可能能够使用 RunAs 提供更优雅的解决方案。
    • 请注意,在德国,“NETWORK SERVICE”是“Netzwerkdienst”——即使您将 Windows 语言切换为英语。这就是为什么最好使用New-Object System.Security.Principal.SecurityIdentifier("S-1-5-20") 等。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2017-08-05
    • 2022-01-08
    • 2017-10-15
    • 1970-01-01
    • 2017-12-26
    • 2020-08-19
    • 2019-06-16
    相关资源
    最近更新 更多