When you dot source the DSC configuration file that contains
a resource having a PSCredential object as parameter with the
PSDscAllowPlainTextPassword option set in the configuration data, the resulting
MOF file will have the password saved as plain text in a human readable format.
This results in compromising the credentials from the MOF files. If you want to
secure your credentials in the MOF file, then you need to use the LCM to check
the credentials of the user, encrypt the credentials using the certificate
details mentioned in the configuration data and then later decrypt it using the
settings of the LCM.
To secure your MOF files, you’ll need to first create a
certificate with a private key to decrypt the data in the MOF files and then
use that information to create the MOF files.
You can create the certificate, root certificate and revocation
list using the makecert command from the VS 2013 command prompt as given below
makecert -pe -n "CN=*your subject here" -a sha256 -sky
exchange -eku 1.3.6.1.5.5.7.3.3,1.3.6.1.4.1.311.10.3.13 -ic ..\Root\Myroot.cer -iv
..\Root\Myroot.pvk -sy 24 -sv Myroot.pvk Myroot.cer
pvk2pfx -pvk Myroot.pvk -spc Myroot.cer -pfx Myroot..pfx -po
"your password"
makecert -pe -n "CN=ROOT Authority" -sy 24 -sv
MyCert.pvk MyCert.cer
pvk2pfx -pvk MyCert.pvk -spc MyCert.cer -pfx MyCert.pfx -po
"Your password"
makecert -crl -sv MyCert.pvk MyCert.crl
Once you have the required certificates, you can use this
data in the configuration file to encrypt the credentials and store in the MOF
files.
$ErrorActionPreference
= "Stop"
Import-Module DSCAdministration
Configuration SecuredAccountConfiguration
{
Node $AllNodes.Where{$_.Role -eq "DEV"}.NodeName
{
$credential = Get-Credentials
ProtectedResource Resource1
{
Username = $credential.Username
Credential = $credential
Ensure = "Present"
}
LocalConfigurationManager
{
CertificateId = $Node.Thumbprint
}
}
}
Function Create-Configuration{
param(
[Parameter(Mandatory = $true)]
[string] $Thumbprint,
[bool] $ApplyConfiguration = $false
)
$certificate = (Get-CertDetailsToEncryptMofFile $Thumbprint)
$config = @{
AllNodes = @(
@{
NodeName = $env:COMPUTERNAME
Role = "DEV"
CertificateFile =
$certificate.Certificate
Thumbprint =
$certificate.Thumbprint
}
)
}
SecuredAccountConfiguration -configurationdata $config -OutputPath .\SecuredAccountConfiguration
if($ApplyConfiguration){
Set-DSCLocalConfigurationManager .\SecuredAccountConfiguration
Start-DscConfiguration .\SecuredAccountConfiguration -Verbose -Wait
}
}
Create-Configuration -Thumbprint "546AD85913453805AF1115E135DF9EB126218765"
The Get-CertDetailsToEncryptMofFile function is defined in
the PS module as
Function Get-CertDetailsToEncryptMofFile
{
param(
[Parameter(Mandatory = $true)]
[string] $Thumbprint,
[string] $Path
)
$result = @{Certificate = $null;
Thumbprint = $null}
Get-ChildItem -Path "cert:\LocalMachine\My" |% {
if($_.PrivateKey.KeyExchangeAlgorithm
–and $_.Verify()){
if($_.Thumbprint -eq
$Thumbprint){
if([string]::IsNullOrEmpty($Path)){
$Path
= Join-Path
$env:SystemDrive -ChildPath "MyPublicKeys”
}
if(-not (Test-Path $Path -ErrorAction
SilentlyContinue)){
Write-Verbose "Creating new directory at location $Path to export the public key
to encrypt the credentials in the mof file"
New-Item -Path $Path
-ItemType directory -ErrorAction SilentlyContinue | Out-Null
}
[Byte[]]$CertContent = $_.Export('Cert')
$Path
= Join-Path
$Path MyCert.cer
Set-Content -Path $Path -Value
$CertContent -Encoding Byte
Write-Verbose "Exported the certificate to $Path"
$result.Certificate
= $Path
$result.Thumbprint
= $_.Thumbprint
}
}
}
return $result
}
The Set-DSCLocalConfigurationManager command will make sure
that the LCM on the target machine knows the certificate to decrypt the
credentials in the MOF file.
No comments:
Post a Comment