为本地集群安装证书
Install a certificate for a local cluster
我有一些代码可以通过 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();
}
一旦我尝试在有状态服务应用程序中使用此代码,它就无法再找到证书。
如何安装证书以便它可用于我的本地集群?
NETWORK SERVICE 帐户下的 Service Fabric 应用程序 运行,因此您需要确保该帐户具有 access/permissions 证书。
编辑:
对于本地机器上的集群 运行,您可以使用 certmgr.msc 或相关的 mmc 管理单元查找证书,然后右键单击 > 所有任务 > 管理私钥然后授予 NETWORK SERVICE 读取权限。
对于 Azure 中的远程集群,您可以在规模集的 VM 上使用 custom script extension 来做到这一点,这将 运行 一个设置所需权限的 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
这不能按原样工作的原因是因为 Service Fabric 在 NETWORK SERVICE 帐户下运行,该帐户在没有配置的情况下无权访问证书。
至少对我们来说,这种情况在使用 Microsoft.Azure.KeyVault 提供的 KeyVaultClient
使用证书连接到 Key Vault 时导致 "Keyset does not exist" 异常。
一个解决方案是将证书包含在您的 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>
... 其中 NetworkServiceAccount
和 KeyVaultCert
都是 <SecurityAccessPolicy />
元素用来引用用户和证书的任意名称。
我有一些代码可以通过 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();
}
一旦我尝试在有状态服务应用程序中使用此代码,它就无法再找到证书。
如何安装证书以便它可用于我的本地集群?
NETWORK SERVICE 帐户下的 Service Fabric 应用程序 运行,因此您需要确保该帐户具有 access/permissions 证书。
编辑:
对于本地机器上的集群 运行,您可以使用 certmgr.msc 或相关的 mmc 管理单元查找证书,然后右键单击 > 所有任务 > 管理私钥然后授予 NETWORK SERVICE 读取权限。
对于 Azure 中的远程集群,您可以在规模集的 VM 上使用 custom script extension 来做到这一点,这将 运行 一个设置所需权限的 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
这不能按原样工作的原因是因为 Service Fabric 在 NETWORK SERVICE 帐户下运行,该帐户在没有配置的情况下无权访问证书。
至少对我们来说,这种情况在使用 Microsoft.Azure.KeyVault 提供的 KeyVaultClient
使用证书连接到 Key Vault 时导致 "Keyset does not exist" 异常。
一个解决方案是将证书包含在您的 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>
... 其中 NetworkServiceAccount
和 KeyVaultCert
都是 <SecurityAccessPolicy />
元素用来引用用户和证书的任意名称。