[24]Window PowerShell DSC学习系列---- 如何保护MOF文件里面存储的密码?

在上节笔者分享了[23]Window PowerShell DSC学习系列---- MOF文件能存储用户的密码吗?MOF文件里面能直接存储明文密码,这样是非常不安全的。那么有什么方式能够把MOF里面存储的明文密码通过某种方式进行加密,从而存储成密文的形式。答案是“Yes”。PowerShell DSC提供了一种通过SSL证书加密MOF文件里面的密码的功能。 具体的流程,请见下图。

[24]Window PowerShell DSC学习系列---- 如何保护MOF文件里面存储的密码?_第1张图片

本图片引用于https://msdn.microsoft.com/en-us/powershell/dsc/securemof

@第1步 生成密钥对

对MOF文件中的密码信息加密有两种方式,一种方式,生成一个秘钥对,然后把公钥在Pull服务器上对MOF文件的密码进行加密,然后在所有的目标节点上存储同一个私钥用来解密; 另外一种方式是,对于每个目标的客户端节点都生成一个不同的密钥对,然后然后把公钥发给Pull服务器,Pull服务器对于每台客户节点机,用不同的公钥进行加密。为了便于演示,笔者选择了第一种方式。
首先找一台Window 10的机器,然打开PowerShell,输入下面的命令,生成一个公私钥对。

$cert = New-SelfSignedCertificate -Type DocumentEncryptionCertLegacyCsp -DnsName 'DscEncryptionCert' -HashAlgorithm SHA256
$mypwd = ConvertTo-SecureString -String "password" -Force -AsPlainText
$cert | Export-PfxCertificate -FilePath "c:\certs\DscPrivateKey.pfx" -Password $mypwd -Force

$cert | Export-Certificate -FilePath "c:\certs\DscPublicKey.cer" -Force

$cert | Remove-Item -Force

将会生成一组公私钥密钥对。

[24]Window PowerShell DSC学习系列---- 如何保护MOF文件里面存储的密码?_第2张图片

@第2步 公钥导入Pull服务器,私钥导入目标客户端节点

把上面生成的公钥DscPublicKey.cer , 拷贝到Pull服务器的c:\certs目录下,通过下面PowerShell脚本导入到本机的证书管理器里面
Import-Certificate -FilePath"c:\certs\DscPublicKey.cer" -CertStoreLocation Cert:\LocalMachine\My

如果读者的机器上的操作系统没有Import-Certificate这个PowerShell Cmdlet,可以通过下面的方式手工导入。
在操作系统的Run里面输入mmc
[24]Window PowerShell DSC学习系列---- 如何保护MOF文件里面存储的密码?_第3张图片

然后在File-->Add/Remove Snapin.. 把Certificate的Snapin加入到mmc(Microsoft Management Console)中。
[24]Window PowerShell DSC学习系列---- 如何保护MOF文件里面存储的密码?_第4张图片

在打开的控制界面通过下面的方式把证书导入到Personal文件中。和上面的命令行的效果一样。

[24]Window PowerShell DSC学习系列---- 如何保护MOF文件里面存储的密码?_第5张图片

对于证书指纹(ThumbPrint);可以通过下面的命令查看其ThumbPrint
dir Cert:\LocalMachine\My
在笔者的电脑上其值为:737C5BCA86E3096A28BE1B7E0C36A2D83DA80FE2 
另外,也可以直接双击DscPublicKey.cer证书,查看其ThumbPrint。

[24]Window PowerShell DSC学习系列---- 如何保护MOF文件里面存储的密码?_第6张图片

对于私钥导入到目标客户端节点要复杂一些。把DscPrivateKey.pfx拷贝到客户端的目标节点之后,
通过下面的PowerShell命令到目标客户端节点的cert:\LocalMachine\my 节点下(注意,其必须保存在cert:\LocalMachine\my这个目录下,不能在cert:\LocalMachine\root下)

$mypwd = ConvertTo-SecureString -String "password" -Force -AsPlainTextImport-PfxCertificate -FilePath "c:\certs\DscPrivateKey.pfx" -CertStoreLocation Cert:\LocalMachine\my -Password $mypwd > $null

同时还需要更新LCM的设置。把CertificateID的值设置成私钥的指纹(ThumbPrint)
[DSCLocalConfigurationManager()]
configuration PullClientConfigNames
{
    Node localhost
    {
        Settings
        {
            RefreshMode = 'Pull'
            ConfigurationMode = "ApplyAndAutocorrect"
            RebootNodeIfNeeded = $true
            DebugMode='ForceModuleImport'
            CertificateID = '737C5BCA86E3096A28BE1B7E0C36A2D83DA80FE2'
        }
        ConfigurationRepositoryWeb pserver.example.com
        {
            ServerURL = 'http://pserver.example.com:8080/PSDSCPullServer.svc'
            RegistrationKey = '2cfefa66-8a92-4e3d-88cd-9048209fde73'
            ConfigurationNames ='unzipFile'
            AllowUnsecureConnection = $true
        }
        ReportServerWeb pserver.example.com
        {
            ServerURL = 'http://pserver.example.com:8080/PSDSCPullServer.svc'
            RegistrationKey = '2cfefa66-8a92-4e3d-88cd-9048209fde73'
            AllowUnsecureConnection = $true
        }
    }
}
PullClientConfigNames

@第3步 在Pull服务器端,使用公钥加密密码

我们还是以上一篇的例子为例,
$password = "ThisIsAPlaintextPassword" | ConvertTo-SecureString -asPlainText -Force
$username = "User1"
[PSCredential] $credential = New-Object System.Management.Automation.PSCredential($username,$password)

Configuration ChangeCmdBackGroundColor    
{
    Import-DscResource -ModuleName PSDesiredStateConfiguration


    Node $AllNodes.NodeName
    {
        Registry CmdPath
        {
            Key                  = 'HKEY_CURRENT_USER\SOFTWARE\Microsoft\Command Processor'
            ValueName            = 'DefaultColor'
            ValueData            = '1F'
            ValueType            = 'DWORD'
            Ensure               = 'Present'
            Force                = $true
            Hex                  = $true
            PsDscRunAsCredential = $credential
        }
    }                   
}
$configData = @{
    AllNodes = @(
        @{
            NodeName             = 'dscClient-01';
            PSDscAllowPlainTextPassword = $true
        }
    )
}

ChangeCmdBackGroundColor -ConfigurationData $configData

上面这个会生成一个带明文密码的MOF文件。修改为带密文的配置文件如下:
$password = "ThisIsAPlaintextPassword" | ConvertTo-SecureString -asPlainText -Force
$username = "User1"
[PSCredential] $credential = New-Object System.Management.Automation.PSCredential($username,$password)
Configuration ChangeCmdBackGroundColor    
{
    Import-DscResource -ModuleName PSDesiredStateConfiguration


    Node $AllNodes.NodeName
    {
        Registry CmdPath
        {
            Key                  = 'HKEY_CURRENT_USER\SOFTWARE\Microsoft\Command Processor'
            ValueName            = 'DefaultColor'
            ValueData            = '1F'
            ValueType            = 'DWORD'
            Ensure               = 'Present'
            Force                = $true
            Hex                  = $true
            PsDscRunAsCredential = $credential
        }
    }                   
}
$configData = @{
    AllNodes = @(
        @{
            NodeName             = 'dscClient-01';
            #PSDscAllowPlainTextPassword = $true
           
CertificateFile = "C:\certs\DscPublicKey.cer"  
            Thumbprint = "‎737C5BCA86E3096A28BE1B7E0C36A2D83DA80FE2" 

        }
    )
}

ChangeCmdBackGroundColor -ConfigurationData $configData

从上面可以看出,基本的变化就是,在$configData块里面,添加了两个新的默认的属性:CertificateFile和Thumbprint,同时把PSDscAllowPlainTextPassword 属性注释掉了。其生成的MOF文件如下:
instance of MSFT_Credential as $MSFT_Credential1ref
{
Password = "-----BEGIN CMS-----\nMIIBtAYJKoZIhvcNAQcDoIIBpTCCAaECAQAxggFMMIIBSAIBADAwMBwxGjAYBgNVBAMMEURzY0Vu\nY3J5cHRpb25DZXJ0AhAgQGGLMi/7rE8We7FUILK/MA0GCSqGSIb3DQEBBzAABIIBAE5YFXGEUB3e\n5vleh7+9INfO10yZ/6aCT2VoIm+EKnzPKj5syP1C9Wi9KGToGu+y31LPfKKZqF5esaEHDgZFOj9E\nyA+mTwUEu0HGViGLxpSPignOhsMLBEwXlfaZWTbUJbkjP3XMy0CHmHRPwRVC5JYg9uLZECCqd16p\nOxxHlDr4ZGDmLL5PY3zSENZ34NRowisxtE3PwZP+2sVj/MLrN8F6jBecyzqsAr3cqmZqZJ0HqL7f\nAE3dEQa0zYAmZoQL1zM8ISZ2CGwbTrmvMQweSqIprZyEaaPCD3puvLkh89osTjW1Yx4oDDKm/pW0\n87w+/8AcVx7IfDO9juRoynHSJYwwTAYJKoZIhvcNAQcBMB0GCWCGSAFlAwQBKgQQb8eEXvkc1Pjz\n01fOf5l3WYAgA92DTXKQNPAGqbLvbOiP/bq+jerL+8LiSslvhKcof1o=\n-----END CMS-----";
 UserName = "User1";
};
instance of MSFT_RegistryResource as $MSFT_RegistryResource1ref
{
ResourceID = "[Registry]CmdPath";
 ValueName = "DefaultColor";
 PsDscRunAsCredential = $MSFT_Credential1ref;
 Key = "HKEY_CURRENT_USER\\SOFTWARE\\Microsoft\\Command Processor";
 Ensure = "Present";
 Force = True;
 SourceInfo = "C:\\DSC\\ChangeCmdBackGroundColor.ps1::10::9::Registry";
 ValueType = "Dword";
 ModuleName = "PSDesiredStateConfiguration";
 ValueData = {
    "1F"
};
 Hex = True;
ModuleVersion = "0.0";
 ConfigurationName = "ChangeCmdBackGroundColor";

};
instance of OMI_ConfigurationDocument

                    {
  Version="2.0.0";
                        MinimumCompatibleVersion = "2.0.0";
                        CompatibleVersionAdditionalProperties= {"Omi_BaseResource:ConfigurationName"};
                        Author="Admin";
                        GenerationDate="02/24/2017 07:03:59";
                        GenerationHost="PULL51W2K12NSSL";
                        ContentType="PasswordEncrypted";
                        Name="ChangeCmdBackGroundColor";
                    };

恭喜你!!! 对MOF文件中的密码部分已经成功加密;我们只需要把上面的MOF重新部署到Pull服务器上,客户端能够根据私钥,自动解密其里面的密码。



你可能感兴趣的:(PowerShellDSC,PowerShell,DSC)