Skydda MOF-filen

Gäller för: Windows PowerShell 4.0, Windows PowerShell 5.0

DSC hanterar konfigurationen av servernoder genom att tillämpa information som lagras i en MOF-fil, där LCM (Local Configuration Manager) implementerar önskat sluttillstånd. Eftersom den här filen innehåller information om konfigurationen är det viktigt att skydda den. Den här artikeln beskriver hur du ser till att målnoden har krypterat filen.

Från och med PowerShell version 5.0 krypteras hela MOF-filen som standard när den tillämpas på noden med hjälp av cmdleten Start-DSCConfiguration . Processen som beskrivs i den här artikeln krävs endast när du implementerar en lösning med hjälp av pull-tjänstprotokollet om certifikat inte hanteras, för att säkerställa att konfigurationer som laddas ned av målnoden kan dekrypteras och läsas av systemet innan de tillämpas (till exempel pull-tjänsten som är tillgänglig i Windows Server). Noder som är registrerade i Azure Automation DSC kommer automatiskt att ha certifikat installerade och hanterade av tjänsten utan administrativa kostnader.

Anteckning

I det här avsnittet beskrivs certifikat som används för kryptering. För kryptering räcker det med ett självsignerat certifikat eftersom den privata nyckeln alltid hålls hemlig och kryptering inte innebär förtroende för dokumentet. Självsignerade certifikat bör inte användas i autentiseringssyfte. Du bör använda ett certifikat från en betrodd certifikatutfärdare (CA) för alla autentiseringsändamål.

Förutsättningar

Om du vill kryptera autentiseringsuppgifterna som används för att skydda en DSC-konfiguration kontrollerar du att du har följande:

  • Några sätt att utfärda och distribuera certifikat. Det här avsnittet och dess exempel förutsätter att du använder Active Directory-certifikatutfärdare. Mer bakgrundsinformation om Active Directory Certificate Services finns i Översikt över Active Directory Certificate Services.
  • Administrativ åtkomst till målnoden eller noderna.
  • Varje målnod har ett krypteringskompatibelt certifikat som sparats i det personliga arkivet. I Windows PowerShell är sökvägen till arkivet Cert:\LocalMachine\My. Exemplen i det här avsnittet använder mallen "autentisering av arbetsstation", som du hittar (tillsammans med andra certifikatmallar) i Standardcertifikatmallar.
  • Om du ska köra den här konfigurationen på en annan dator än målnoden exporterar du certifikatets offentliga nyckel och importerar den sedan till datorn som du kör konfigurationen från. Kontrollera att du bara exporterar den offentliga nyckeln. skydda den privata nyckeln.

Anteckning

Skriptresurser har begränsningar när det gäller kryptering. Mer information finns i Skriptresurs

Övergripande process

  1. Konfigurera certifikat, nycklar och tumavtryck och se till att varje målnod har kopior av certifikatet och att konfigurationsdatorn har den offentliga nyckeln och tumavtrycket.
  2. Skapa ett konfigurationsdatablock som innehåller sökvägen och tumavtrycket för den offentliga nyckeln.
  3. Skapa ett konfigurationsskript som definierar önskad konfiguration för målnoden och konfigurerar dekryptering på målnoderna genom att be den lokala konfigurationshanteraren att dekryptera konfigurationsdata med hjälp av certifikatet och dess tumavtryck.
  4. Kör konfigurationen, som anger inställningarna för lokala Configuration Manager och startar DSC-konfigurationen.

Processflöde för kryptering av autentiseringsuppgifter

Certifikatkrav

För att kunna utföra kryptering av autentiseringsuppgifter måste ett offentligt nyckelcertifikat vara tillgängligt på målnoden som är betrodd av den dator som används för att skapa DSC-konfigurationen. Det här offentliga nyckelcertifikatet har specifika krav för att det ska användas för kryptering av DSC-autentiseringsuppgifter:

  1. Nyckelanvändning:
    • Måste innehålla: "KeyEncipherment" och "DataEncipherment".
    • Får inte innehålla: "Digital signatur".
  2. Förbättrad nyckelanvändning:
    • Måste innehålla: Dokumentkryptering (1.3.6.1.4.1.311.80.1).
    • Får inte innehålla: Klientautentisering (1.3.6.1.5.5.7.3.2) och Serverautentisering (1.3.6.1.5.5.7.3.1).
  3. Den privata nyckeln för certifikatet är tillgänglig på *Target Node_.
  4. Providern för certifikatet måste vara "Microsoft RSA SChannel Cryptographic Provider".

Viktigt

Även om du kan använda ett certifikat som innehåller en nyckelanvändning av "digital signatur" eller en av EKU:erna för autentisering, gör detta att krypteringsnyckeln blir enklare att missbruka och sårbar för angrepp. Det är därför bästa praxis att använda ett certifikat som skapats specifikt för att skydda DSC-autentiseringsuppgifter som utelämnar dessa nyckelanvändnings- och EKU:er.

Alla befintliga certifikat på målnoden som uppfyller dessa villkor kan användas för att skydda DSC-autentiseringsuppgifter.

Skapa certifikat

Det finns två metoder som du kan använda för att skapa och använda det krypteringscertifikat som krävs (offentligt-privat nyckelpar).

  1. Skapa den på målnoden och exportera bara den offentliga nyckeln till redigeringsnoden
  2. Skapa den på redigeringsnoden och exportera hela nyckelparet till målnoden

Metod 1 rekommenderas eftersom den privata nyckel som används för att dekryptera autentiseringsuppgifter i MOF alltid finns kvar på målnoden.

Skapa certifikatet på målnoden

Den privata nyckeln måste hållas hemlig eftersom används för att dekryptera MOF på målnoden Det enklaste sättet att göra det är att skapa det privata nyckelcertifikatet på målnoden och kopiera det offentliga nyckelcertifikatet till den dator som används för att redigera DSC-konfigurationen till en MOF-fil. Följande exempel:

  1. skapar ett certifikat på målnoden
  2. exporterar certifikatet för offentlig nyckel på målnoden.
  3. importerar certifikatet för offentlig nyckel till mitt certifikatarkiv på noden Redigering.

På målnoden: skapa och exportera certifikatet

Målnod: Windows Server 2016 och 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

När den har exporterats måste den DscPublicKey.cer kopieras till redigeringsnoden.

På redigeringsnoden: importera certifikatets offentliga nyckel

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

Skapa certifikatet på redigeringsnoden

Alternativt kan krypteringscertifikatet skapas på redigeringsnoden, exporteras med den privata nyckeln som en PFX-fil och sedan importeras på målnoden. Det här är den aktuella metoden för att implementera kryptering av DSC-autentiseringsuppgifter på Nano Server. Även om PFX skyddas med ett lösenord bör det hållas säkert under överföringen. Följande exempel:

  1. skapar ett certifikat på noden Redigering.
  2. exporterar certifikatet inklusive den privata nyckeln på noden Redigering.
  3. tar bort den privata nyckeln från noden Redigering, men behåller certifikatet för den offentliga nyckeln i mitt arkiv.
  4. importerar certifikatet för privat nyckel till certifikatarkivet My(Personal) på målnoden.
    • Den måste läggas till i rotarkivet så att den blir betrodd av målnoden.

På redigeringsnoden: skapa och exportera certifikatet

Målnod: Windows Server 2016 och 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

När den har exporterats måste den DscPrivateKey.pfx kopieras till målnoden.

På målnoden: importera certifikatets privata nyckel som en betrodd rot

# 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

Konfigurationsdata

Konfigurationsdatablocket definierar vilka målnoder som ska användas, oavsett om de ska kryptera autentiseringsuppgifterna, krypteringsmedlet och annan information. Mer information om konfigurationsdatablocket finns i Separera konfigurations- och miljödata.

De element som kan konfigureras för varje nod som är relaterade till kryptering av autentiseringsuppgifter är:

  • NodeName – namnet på målnoden som kryptering av autentiseringsuppgifter konfigureras för.
  • PsDscAllowPlainTextPassword – om okrypterade autentiseringsuppgifter kommer att tillåtas skickas till den här noden. Detta rekommenderas inte.
  • Tumavtryck – tumavtrycket för certifikatet som ska användas för att dekryptera autentiseringsuppgifterna i DSC-konfigurationen på målnoden. Det här certifikatet måste finnas i certifikatarkivet för den lokala datorn på målnoden.
  • CertificateFile – certifikatfilen (som endast innehåller den offentliga nyckeln) som ska användas för att kryptera autentiseringsuppgifterna för målnoden. Detta måste antingen vara en DER-kodad binär X.509- eller Base-64-kodad X.509-formatcertifikatfil.

Det här exemplet visar ett konfigurationsdatablock som anger en målnod som ska agera på namngivna targetNode, sökvägen till certifikatfilen för den offentliga nyckeln (med namnet targetNode.cer) och tumavtrycket för den offentliga nyckeln.

$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"
        }
    )
}

Konfigurationsskript

I själva konfigurationsskriptet använder du parametern PsCredential för att säkerställa att autentiseringsuppgifterna lagras under kortast möjliga tid. När du kör det angivna exemplet frågar DSC efter autentiseringsuppgifter och krypterar sedan MOF-filen med hjälp av CertificateFile som är associerad med målnoden i konfigurationsdatablocket. Det här kodexemplet kopierar en fil från en resurs som är skyddad för en användare.

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
        }
    }
}

Konfigurera dekryptering

Innan Start-DscConfiguration kan fungera måste du tala om för den lokala Configuration Manager på varje målnod vilket certifikat som ska användas för att dekryptera autentiseringsuppgifterna med hjälp av CertificateID-resursen för att verifiera certifikatets tumavtryck. Den här exempelfunktionen hittar lämpligt lokalt certifikat (du kanske måste anpassa det så att det hittar exakt det certifikat som du vill använda):

# 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
        }
    }
}

Med det certifikat som identifieras med tumavtrycket kan konfigurationsskriptet uppdateras för att använda värdet:

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
        }
    }
}

Köra konfigurationen

Nu kan du köra konfigurationen, som matar ut två filer:

  • En *.meta.mof fil som konfigurerar den lokala Configuration Manager att dekryptera autentiseringsuppgifterna med hjälp av certifikatet som lagras i det lokala datorarkivet och identifieras med dess tumavtryck. Set-DscLocalConfigurationManager tillämpar *.meta.mof filen.
  • En MOF-fil som faktiskt tillämpar konfigurationen. Start-DscConfiguration tillämpar konfigurationen.

Dessa kommandon utför följande steg:

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

Det här exemplet skulle push-överföra DSC-konfigurationen till målnoden. DSC-konfigurationen kan också tillämpas med hjälp av en DSC-hämtningsserver om en är tillgänglig.

Mer information om hur du tillämpar DSC-konfigurationer med en DSC-hämtningsserver finns i Konfigurera en DSC-hämtningsklient .

Exempel på autentiseringskrypteringsmodul

Här är ett fullständigt exempel som innehåller alla dessa steg, plus en hjälp-cmdlet som exporterar och kopierar de offentliga nycklarna:

# 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