我创建了一个TCP服务,它创建了一个安全的SSL连接,我试图在Azure Service Fabric集群中托管。虽然有关于如何为网站和API加载和使用SSL证书的文档,但我似乎无法找到有关如何为我的服务加载证书的任何文档。我已将我的证书加载到密钥保险库,但现在需要创建一个X509Certificate2实例来保护我的tcp连接。
答案 0 :(得分:1)
我们遇到了类似的问题(我们希望使用带有HTTPS的Kestrel),并找到了实现此目的的两种方法。
这种方法存在问题,因为AFAIK服务结构在NETWORK_SERVICE下运行,并且没有读取私钥的权限。
这里有更好的解释 - https://azure.microsoft.com/en-gb/documentation/articles/key-vault-use-from-web-application
我很乐意,如果有人可以建议在这种情况下最佳做法 - 我认为第二个选项有问题,创建一个新的X509Certificate2也在磁盘上的临时位置创建证书,但没有清理,但我和#39;我相信还有更多。
答案 1 :(得分:1)
当我最初创建我的群集时,它是一个不安全的群集。只需将其重新创建为安全集群,我现在可以使用我创建的以下帮助程序方法访问用于保护集群的文件库中的证书。
private static X509Certificate GetServerCertificate(string thumbprint)
{
string thumbprint = CertificateThumbprint;
X509Store store = new X509Store(StoreName.My, StoreLocation.LocalMachine);
store.Open(OpenFlags.ReadOnly);
var certificateCollection = store.Certificates.Find(X509FindType.FindByThumbprint, thumbprint, false);
if (certificateCollection.Count == 0)
{
store.Close();
string errorMessage = string.Format("Unable to load certificate with thumbprint {0}", thumbprint);
throw new ApplicationException(errorMessage);
}
else
{
var certificate = new X509Certificate2(certificateCollection[0]);
store.Close();
return certificate;
}
}
有关创建安全群集的说明,请访问:https://azure.microsoft.com/en-us/documentation/articles/service-fabric-cluster-creation-via-arm/
答案 2 :(得分:1)
一种选择是以SYSTEM
运行Service Fabric设置任务(只有SYSTEM
将有权更改证书上的ACL)并授予NETWORK SERVICE
权限以读取您的证书< / p>
下面的完整示例,注意我在所有LocalMachine / My证书上设置ACL,修改PS脚本以仅获取您需要的证书
<强> ServiceManifest.xml 强>
<CodePackage Name="Code" Version="1.0.0">
<SetupEntryPoint>
<ExeHost>
<Program>setup.cmd</Program>
<WorkingFolder>CodePackage</WorkingFolder>
</ExeHost>
</SetupEntryPoint>
<EntryPoint>
<ExeHost>
<Program>XXX.exe</Program>
<WorkingFolder>CodePackage</WorkingFolder>
</ExeHost>
</EntryPoint>
</CodePackage>
<强> setup.cmd 强>
powershell.exe -NoLogo -NonInteractive -WindowStyle Hidden -ExecutionPolicy Bypass -File configure-certs.ps1
<强>配置-certs.ps1 强>
$store = New-Object System.Security.Cryptography.X509Certificates.X509Store @(
[System.Security.Cryptography.X509Certificates.StoreName]::My,
[System.Security.Cryptography.X509Certificates.StoreLocation]::LocalMachine)
try
{
$store.Open([System.Security.Cryptography.X509Certificates.OpenFlags]::ReadOnly)
$certs = $store.Certificates
$rule = New-Object System.Security.AccessControl.FileSystemAccessRule @(
"NETWORK SERVICE",
[System.Security.AccessControl.FileSystemRights]::Read,
[System.Security.AccessControl.AccessControlType]::Allow)
foreach ($cert in $certs)
{
$privateKeyPath = "$($ENV:ProgramData)\Microsoft\Crypto\RSA\MachineKeys\$($cert.PrivateKey.CspKeyContainerInfo.UniqueKeyContainerName)"
$privateKeyInfo = New-Object System.IO.FileInfo @($privateKeyPath)
$privateKeyAccessControl = $privateKeyInfo.GetAccessControl()
$privateKeyAccessControl.AddAccessRule($rule)
$privateKeyInfo.SetAccessControl($privateKeyAccessControl)
}
}
finally
{
$store.Close()
}
<强> ApplicationManifest.xml 强>
将 ConfigOverrides 作为 ServiceManifestImport 的子代后,您需要将设置添加到
...
<Policies>
<RunAsPolicy CodePackageRef="Code" UserRef="LocalSystem" EntryPointType="Setup" />
</Policies>
...
将 DefaultServices 作为 ApplicationManifest 的子项之后
...
<Principals>
<Users>
<User Name="LocalSystem" AccountType="LocalSystem" />
</Users>
</Principals>
...
答案 3 :(得分:1)
实际上有一种更简单的方法可以确保Service Fabric(例如默认的Network_Service)有权访问您的证书。
我运行一个内部部署的Service Fabric集群,过去我必须做类似的事情,因为我使用证书来加密应用程序机密。
基本上,您只需将Application Manifest更新为
即可<Principals>
<SecurityAccessPolicy>
<Certificates>
示例ApplicationManifest.xml
提取:
<Principals>
<Users>
<User Name="DefaultServiceAccount" AccountType="NetworkService" />
</Users>
</Principals>
<Policies>
<SecurityAccessPolicies>
<SecurityAccessPolicy ResourceRef="AppSecretsCert" PrincipalRef="DefaultServiceAccount" ResourceType="Certificate" />
</SecurityAccessPolicies>
</Policies>
<Certificates>
<SecretsCertificate X509FindValue="YOUR CERT THUMPRINT" Name="AppSecretsCert" />
</Certificates>