次の方法で共有


MOF ファイルのセキュリティ保護

適用対象: Windows PowerShell 4.0、Windows PowerShell 5.0

DSC は、MOF ファイルに格納されている情報を適用してサーバー ノードの構成を管理し、ローカル構成マネージャー (LCM) が目的の終了状態を実装します。 このファイルには構成の詳細が含まれているため、安全に保つことが重要です。 この記事では、ターゲットノードがファイルを暗号化していることを確認する方法について説明します。

PowerShell バージョン 5.0 以降では、 Start-DSCConfiguration コマンドレットを使用してノードに適用すると、MOF ファイル全体が既定で暗号化されます。 この記事で説明するプロセスは、証明書が管理されていない場合にプル サービス プロトコルを使用してソリューションを実装する場合にのみ必要であり、ターゲット ノードによってダウンロードされた構成を、適用前にシステムによって復号化して読み取ることができるようにします (たとえば、Windows Server で使用できるプル サービス)。 Azure Automation DSC に登録されているノードには、管理オーバーヘッドは必要なく、サービスによって証明書が自動的にインストールおよび管理されます。

このトピックでは、暗号化に使用される証明書について説明します。 暗号化の場合、秘密鍵は常に秘密に保たれ、暗号化は文書の信頼を意味するものではないため、自己署名証明書で十分です。 自己署名証明書は、認証目的で使用 しないでください 。 認証の目的では、信頼できる証明機関 (CA) からの証明書を使用する必要があります。

[前提条件]

DSC 構成のセキュリティ保護に使用される資格情報を正常に暗号化するには、次のものがあることを確認してください。

  • 証明書を発行および配布するいくつかの手段。 このトピックとその例は、Active Directory 証明機関を使用していることを前提としています。 Active Directory 証明書サービスの詳細については、「 Active Directory 証明書サービスの概要」を参照してください。
  • ターゲット・ノードへの管理アクセス
  • 各ターゲット・ノードには、個人用ストアが保存された暗号化対応証明書があります。 Windows PowerShell では、ストアへのパスは Cert:\LocalMachine\My です。 このトピックの例では、「 デフォルトの証明書テンプレート」で (他の証明書テンプレートとともに) 見つけることができる「ワークステーション認証」テンプレートを使用します。
  • ターゲットノード以外のコンピュータでこの設定を実行する場合は、 証明書の公開キーをエクスポートし、設定を実行するコンピュータにインポートします。 公開鍵のみをエクスポートしてください。秘密鍵を安全に保管します。

スクリプトリソースには、暗号化に関して制限があります。 詳細については、「スクリプト リソース」を参照してください。

プロセス全体

  1. 証明書、キー、拇印を設定し、各ターゲット ノードに証明書のコピーがあり、構成コンピューターに公開キーと拇印があることを確認します。
  2. 公開キーのパスと拇印を含む構成データ ブロックを作成します。
  3. ターゲット ノードに必要な構成を定義する構成スクリプトを作成し、証明書とその拇印を使用して構成データを復号化するようにローカル構成マネージャーに命令することで、ターゲット ノードで復号化を設定します。
  4. 構成を実行すると、ローカル構成マネージャーの設定が設定され、DSC 構成が開始されます。

資格情報暗号化のプロセスフロー

証明書の要件

資格情報の暗号化を有効にするには、DSC 構成の作成に使用されているコンピューターによって信頼されているターゲット ノードで公開キー証明書を使用できる必要があります。 この公開キー証明書には、DSC 資格情報の暗号化に使用するための特定の要件があります。

  1. 主な使用法:
    • 「KeyEncipherment」と「DataEncipherment」を含める必要があります。
    • 「デジタル署名」を含め ないでください
  2. 強化されたキーの使用法:
    • 次のものを含める必要があります: ドキュメント暗号化 (1.3.6.1.4.1.311.80.1)。
    • クライアント認証 (1.3.6.1.5.5.7.3.2) とサーバー認証 (1.3.6.1.5.5.7.3.1) を含め ないでください
  3. 証明書の秘密鍵は、*ターゲットNode_で入手できます。
  4. 証明書の プロバイダー は、"Microsoft RSA SChannel Cryptographic Provider" である必要があります。

Important

「デジタル署名」のキー使用法または認証 EKU の 1 つを含む証明書を使用できますが、これにより、暗号化キーが悪用されやすくなり、攻撃に対して脆弱になります。 そのため、これらのキー使用法と EKU を省略する DSC 資格情報をセキュリティで保護する目的で特別に作成された証明書を使用することをお勧めします。

これらの基準を満たすターゲット ノード 上の既存の証明書を使用して、DSC資格情報を保護できます。

証明書の作成

必要な暗号化証明書 (公開鍵と秘密鍵のペア) を作成して使用するには、2 つの方法があります。

  1. ターゲットノードで作成し、公開鍵のみをオーサリングノードにエクスポートします
  2. オーサリングノードで作成し、キーペア全体をターゲットノードにエクスポートします

MOF の資格情報の復号化に使用される秘密キーは、常にターゲット ノードにとどまるため、方法 1 をお勧めします。

ターゲット・ノードでの証明書の作成

秘密キーは、 ターゲット ノード 上の MOF の暗号化を解除するために使用されるため、秘密にしておく必要があります。これを行う最も簡単な方法は、 ターゲット ノードで秘密キー証明書を作成し、DSC 構成の作成に使用されているコンピューターに公開 キー証明書 を MOF ファイルにコピーすることです。 次のような例です。

  1. ターゲットノードに証明書を作成します。
  2. ターゲット ノードの公開キー証明書をエクスポートします。
  3. 公開キー証明書をオーサリングノードmy 証明書ストアにインポートします。

ターゲットノードで:証明書を作成してエクスポートします。

ターゲットノード: Windows Server 2016 および Windows 10

# note: These steps need to be performed in an Administrator PowerShell session
$cert = New-SelfSignedCertificate -Type DocumentEncryptionCertLegacyCsp -DnsName 'DscEncryptionCert' -HashAlgorithm SHA256
# export the public key certificate
$cert | Export-Certificate -FilePath "$env:temp\DscPublicKey.cer" -Force

エクスポートしたら、 DscPublicKey.cerオーサリングノードにコピーする必要があります。

オーサリングノードで: 証明書の公開鍵をインポートします

# Import to the my store
Import-Certificate -FilePath "$env:temp\DscPublicKey.cer" -CertStoreLocation Cert:\LocalMachine\My

オーサリングノードでの証明書の作成

または、 オーサリング ノードで暗号化証明書を作成し、 秘密キー を使用して PFX ファイルとしてエクスポートしてから、 ターゲット ノードにインポートすることもできます。 これは、 Nano Server に DSC 資格情報暗号化を実装するための現在の方法です。 PFX はパスワードで保護されていますが、転送中は安全に保つ必要があります。 次のような例です。

  1. オー サリングノードに証明書を作成します。
  2. オー サリングノードの秘密鍵を含む証明書をエクスポートします。
  3. オー サリングノードから秘密キーを削除しますが、公開キー証明書は my ストアに保持されます。
  4. 秘密キー証明書を ターゲットノードのMy(Personal)証明書ストアにインポートします。
    • ターゲット・ノードによって信頼されるように、ルート・ストアに追加する必要があります。

オーサリングノードで: 証明書を作成してエクスポートします。

ターゲットノード: Windows Server 2016 および Windows 10

# note: These steps need to be performed in an Administrator PowerShell session
$cert = New-SelfSignedCertificate -Type DocumentEncryptionCertLegacyCsp -DnsName 'DscEncryptionCert' -HashAlgorithm SHA256
# export the private key certificate
$mypwd = ConvertTo-SecureString -String "YOUR_PFX_PASSWD" -Force -AsPlainText
$cert | Export-PfxCertificate -FilePath "$env:temp\DscPrivateKey.pfx" -Password $mypwd -Force
# remove the private key certificate from the node but keep the public key certificate
$cert | Export-Certificate -FilePath "$env:temp\DscPublicKey.cer" -Force
$cert | Remove-Item -Force
Import-Certificate -FilePath "$env:temp\DscPublicKey.cer" -CertStoreLocation Cert:\LocalMachine\My

エクスポートしたら、 DscPrivateKey.pfxターゲットノードにコピーする必要があります。

ターゲット・ノードで: 証明書の秘密鍵を信頼できるルートとしてインポートします。

# Import to the root store so that it is trusted
$mypwd = ConvertTo-SecureString -String "YOUR_PFX_PASSWD" -Force -AsPlainText
Import-PfxCertificate -FilePath "$env:temp\DscPrivateKey.pfx" -CertStoreLocation Cert:\LocalMachine\My -Password $mypwd > $null

構成データ

構成データ・ブロックは、操作するターゲット・ノード、資格情報を暗号化するかどうか、暗号化の手段、およびその他の情報を定義します。 構成データブロックの詳細については、「 構成データと環境データの分離」を参照してください。

資格情報の暗号化に関連する各ノードに構成できる要素は次のとおりです。

  • NodeName - 資格情報の暗号化が構成されているターゲットノードの名前。
  • PsDscAllowPlainTextPassword - 暗号化されていない資格情報をこのノードに渡すことができるかどうか。 これは 推奨されません
  • 拇印 - ターゲット ノードの DSC 構成で資格情報を復号化するために使用される証明書の拇印。 この証明書は、ターゲット・ノードのローカル・マシン証明書ストアに存在する必要があります。
  • CertificateFile - ターゲット・ノードの資格証明の暗号化に使用する証明書ファイル(公開鍵のみを含む)。 これは、DER でエンコードされたバイナリ X.509 または Base-64 でエンコードされた X.509 形式の証明書ファイルである必要があります。

この例では、名前付き targetNode で動作するターゲット ノード、公開キー証明書ファイルへのパス (名前付き targetNode.cer)、および公開キーの拇印を指定する構成データ ブロックを示します。

$ConfigData = @{
    AllNodes = @(
        @{
            # The name of the node we are describing
            NodeName        = "targetNode"

            # The path to the .cer file containing the
            # public key of the Encryption Certificate
            # used to encrypt credentials for this node
            CertificateFile = "C:\publicKeys\targetNode.cer"


            # The thumbprint of the Encryption Certificate
            # used to decrypt the credentials on target node
            Thumbprint      = "AC23EA3A9E291A75757A556D0B71CBBF8C4F6FD8"
        }
    )
}

構成スクリプト

構成スクリプト自体で、 PsCredential パラメーターを使用して、資格情報が可能な限り短い時間保存されるようにします。 提供されている例を実行すると、DSC は資格情報の入力を求め、構成データ ブロック内のターゲット ノードに関連付けられている CertificateFile を使用して MOF ファイルを暗号化します。 このコード例では、ユーザーにセキュリティで保護されている共有からファイルをコピーします。

configuration CredentialEncryptionExample
{
    param(
        [Parameter(Mandatory=$true)]
        [ValidateNotNullorEmpty()]
        [PsCredential] $credential
    )

    Node $AllNodes.NodeName
    {
        File exampleFile
        {
            SourcePath = "\\Server\share\path\file.ext"
            DestinationPath = "C:\destinationPath"
            Credential = $credential
        }
    }
}

復号化の設定

Start-DscConfiguration を機能させる前に、証明書の拇印を検証するために CertificateID リソースを使用して、資格情報の復号化に使用する証明書を各ターゲット ノードのローカル構成マネージャーに指示する必要があります。 この関数例は、適切なローカル証明書を検索します (使用する正確な証明書を見つけるようにカスタマイズする必要がある場合があります)。

# Get the certificate that works for encryption
function Get-LocalEncryptionCertificateThumbprint
{
    (dir Cert:\LocalMachine\my) | %{
        # Verify the certificate is for Encryption and valid
        if ($_.PrivateKey.KeyExchangeAlgorithm -and $_.Verify())
        {
            return $_.Thumbprint
        }
    }
}

拇印で識別される証明書を使用して、構成スクリプトを更新して、次の値を使用できます。

configuration CredentialEncryptionExample
{
    param(
        [Parameter(Mandatory=$true)]
        [ValidateNotNullorEmpty()]
        [PsCredential] $credential
    )

    Node $AllNodes.NodeName
    {
        File exampleFile
        {
            SourcePath = "\\Server\share\path\file.ext"
            DestinationPath = "C:\destinationPath"
            Credential = $credential
        }

        LocalConfigurationManager
        {
             CertificateId = $node.Thumbprint
        }
    }
}

構成の実行

この時点で、構成を実行すると、次の 2 つのファイルが出力されます。

  • ローカル コンピューター ストアに格納され、拇印で識別される証明書を使用して資格情報を復号化するようにローカル構成マネージャーを構成する *.meta.mof ファイル。 Set-DscLocalConfigurationManager は*.meta.mof ファイルを適用します。
  • 構成を実際に適用する MOF ファイル。 Start-DscConfiguration 設定が適用されます。

これらのコマンドは、これらの手順を実行します。

Write-Host "Generate DSC Configuration..."
CredentialEncryptionExample -ConfigurationData $ConfigData -OutputPath .\CredentialEncryptionExample

Write-Host "Setting up LCM to decrypt credentials..."
Set-DscLocalConfigurationManager .\CredentialEncryptionExample -Verbose

Write-Host "Starting Configuration..."
Start-DscConfiguration .\CredentialEncryptionExample -wait -Verbose

この例では、DSC 設定をターゲットノードにプッシュします。 DSC 構成は、DSC プル サーバー (使用可能な場合) を使用して適用することもできます。

DSC プル サーバーを使用して DSC 構成を適用する方法の詳細については、「 DSC プル クライアントの設定 」を参照してください。

資格情報暗号化モジュールの例

これらの手順をすべて組み込んだ完全な例と、公開キーをエクスポートしてコピーするヘルパー コマンドレットを次に示します。

# A simple example of using credentials
configuration CredentialEncryptionExample
{
    param(
        [Parameter(Mandatory=$true)]
        [ValidateNotNullorEmpty()]
        [PsCredential] $credential
    )

    Node $AllNodes.NodeName
    {
        File exampleFile
        {
            SourcePath = "\\server\share\file.txt"
            DestinationPath = "C:\Users\user"
            Credential = $credential
        }

        LocalConfigurationManager
        {
            CertificateId = $node.Thumbprint
        }
    }
}

# A Helper to invoke the configuration, with the correct public key
# To encrypt the configuration credentials
function Start-CredentialEncryptionExample
{
    [CmdletBinding()]
    param ($computerName)

    [string] $thumbprint = Get-EncryptionCertificate -computerName $computerName -Verbose
    Write-Verbose "using cert: $thumbprint"

    $certificatePath = join-path -Path "$env:SystemDrive\$script:publicKeyFolder" -childPath "$computername.EncryptionCertificate.cer"

    $ConfigData=    @{
        AllNodes = @(
                        @{
                            # The name of the node we are describing
                            NodeName = "$computerName"

                            # The path to the .cer file containing the
                            # public key of the Encryption Certificate
                            CertificateFile = "$certificatePath"

                            # The thumbprint of the Encryption Certificate
                            # used to decrypt the credentials
                            Thumbprint = $thumbprint
                        };
                    );
    }

    Write-Verbose "Generate DSC Configuration..."
    CredentialEncryptionExample -ConfigurationData $ConfigData -OutputPath .\CredentialEncryptionExample `
        -credential (Get-Credential -UserName "$env:USERDOMAIN\$env:USERNAME" -Message "Enter credentials for configuration")

    Write-Verbose "Setting up LCM to decrypt credentials..."
    Set-DscLocalConfigurationManager .\CredentialEncryptionExample -Verbose

    Write-Verbose "Starting Configuration..."
    Start-DscConfiguration .\CredentialEncryptionExample -wait -Verbose
}

#region HelperFunctions

# The folder name for the exported public keys
$script:publicKeyFolder = "publicKeys"

# Get the certificate that works for encryptions
function Get-EncryptionCertificate
{
    [CmdletBinding()]
    param ($computerName)

    $returnValue= Invoke-Command -ComputerName $computerName -ScriptBlock {
        $certificates = dir Cert:\LocalMachine\my

        $certificates | %{
                    # Verify the certificate is for Encryption and valid
            if ($_.PrivateKey.KeyExchangeAlgorithm -and $_.Verify())
            {
                # Create the folder to hold the exported public key
                $folder= Join-Path -Path $env:SystemDrive\ -ChildPath $using:publicKeyFolder
                if (! (Test-Path $folder))
                {
                    md $folder | Out-Null
                }

                # Export the public key to a well known ___location
                $certPath = Export-Certificate -Cert $_ -FilePath (Join-Path -path $folder -childPath "EncryptionCertificate.cer")

                # Return the thumbprint, and exported certificate path
                return @($_.Thumbprint,$certPath);
            }
        }
    }

    Write-Verbose "Identified and exported cert..."
    # Copy the exported certificate locally
    $destinationPath = join-path -Path "$env:SystemDrive\$script:publicKeyFolder" -childPath "$computername.EncryptionCertificate.cer"
    Copy-Item -Path (join-path -path \\$computername -childPath $returnValue[1].FullName.Replace(":","$"))  $destinationPath | Out-Null

    # Return the thumbprint
    return $returnValue[0]
}

Start-CredentialEncryptionExample