Udostępnij przez


Zabezpieczanie pliku MOF

Dotyczy: Windows PowerShell 4.0, Windows PowerShell 5.0

DSC zarządza konfiguracją węzłów serwera, stosując informacje przechowywane w pliku MOF, w którym lokalny menedżer konfiguracji (LCM) implementuje żądany stan końcowy. Ponieważ ten plik zawiera szczegóły konfiguracji, ważne jest, aby był bezpieczny. W tym artykule opisano, jak upewnić się, że węzeł docelowy zaszyfrował plik.

Począwszy od programu PowerShell w wersji 5.0, cały plik MOF jest domyślnie szyfrowany, gdy jest stosowany do węzła przy użyciu Start-DSCConfiguration polecenia cmdlet. Proces opisany w tym artykule jest wymagany tylko w przypadku implementowania rozwiązania przy użyciu protokołu usługi ściągania, jeśli certyfikaty nie są zarządzane, aby zapewnić, że konfiguracje pobrane przez węzeł docelowy mogą być odszyfrowywane i odczytywane przez system przed ich zastosowaniem (na przykład usługa ściągania dostępna w systemie Windows Server). Węzły zarejestrowane w usłudze Azure Automation DSC będą automatycznie miały zainstalowane certyfikaty i będą zarządzane przez usługę bez konieczności wykonywania czynności administracyjnych.

Uwaga / Notatka

W tym temacie omówiono certyfikaty używane do szyfrowania. Do szyfrowania wystarczy certyfikat z podpisem własnym, ponieważ klucz prywatny jest zawsze utrzymywany w tajemnicy, a szyfrowanie nie oznacza zaufania do dokumentu. Certyfikaty z podpisem własnym nie powinny być używane do celów uwierzytelniania. Do wszelkich celów uwierzytelniania należy używać certyfikatu z zaufanego urzędu certyfikacji (CA).

Wymagania wstępne

Aby pomyślnie zaszyfrować poświadczenia używane do zabezpieczania konfiguracji DSC, upewnij się, że masz następujące elementy:

  • Niektóre sposoby wydawania i dystrybucji certyfikatów. W tym temacie i jego przykładach założono, że używany jest urząd certyfikacji usługi Active Directory. Aby uzyskać więcej informacji o usługach certyfikatów w usłudze Active Directory, zobacz Omówienie usług certyfikatów w usłudze Active Directory.
  • Dostęp administracyjny do węzła lub węzłów docelowych.
  • Każdy węzeł docelowy ma certyfikat z obsługą szyfrowania, który jest zapisany w magazynie osobistym. W programie Windows PowerShell ścieżka do sklepu to Cert:\LocalMachine\My. W przykładach w tym temacie użyto szablonu "uwierzytelnianie stacji roboczej", który można znaleźć (wraz z innymi szablonami certyfikatów) w temacie Domyślne szablony certyfikatów.
  • Jeśli ta konfiguracja będzie uruchamiana na komputerze innym niż węzeł docelowy, wyeksportuj klucz publiczny certyfikatu, a następnie zaimportuj go do komputera, z którego uruchomisz konfigurację. Upewnij się, że eksportujesz tylko klucz publiczny ; Zadbaj o bezpieczeństwo klucza prywatnego.

Uwaga / Notatka

Zasoby skryptów mają ograniczenia, jeśli chodzi o szyfrowanie. Aby uzyskać więcej informacji, zobacz Zasób skryptu

Ogólny proces

  1. Skonfiguruj certyfikaty, klucze i odciski palców, upewniając się, że każdy węzeł docelowy ma kopie certyfikatu, a komputer konfiguracji ma klucz publiczny i odcisk palca.
  2. Utwórz blok danych konfiguracyjnych, który zawiera ścieżkę i odcisk palca klucza publicznego.
  3. Utwórz skrypt konfiguracji, który definiuje żądaną konfigurację węzła docelowego i konfiguruje odszyfrowywanie w węzłach docelowych, wydając Lokalnemu menedżerowi konfiguracji polecenie odszyfrowania danych konfiguracji przy użyciu certyfikatu i jego odcisku palca.
  4. Uruchom konfigurację, która spowoduje skonfigurowanie lokalnego Configuration Manager i uruchomienie konfiguracji DSC.

Przebieg procesu szyfrowania poświadczeń

Wymagania dotyczące certyfikatu

Aby można było zastosować szyfrowanie poświadczeń, w węźle docelowym musi być dostępny certyfikat klucza publicznego, który jest zaufany przez komputer używany do tworzenia konfiguracji DSC. Ten certyfikat klucza publicznego ma określone wymagania, które mają być używane do szyfrowania poświadczeń DSC:

  1. Kluczowe użycie:
    • Musi zawierać: "KeyEncipherment" i "DataEncipherment".
    • Nie powinien zawierać: "Podpis cyfrowy".
  2. Ulepszone użycie klucza:
    • Musi zawierać: Szyfrowanie dokumentów (1.3.6.1.4.1.311.80.1).
    • Nie powinien zawierać: Uwierzytelnianie klienta (1.3.6.1.5.5.7.3.2) i Uwierzytelnianie serwera (1.3.6.1.5.5.7.3.1).
  3. Klucz prywatny certyfikatu jest dostępny na Node_ *Target.
  4. Dostawcą certyfikatu musi być "Microsoft RSA SChannel Cryptographic Provider".

Ważne

Chociaż można użyć certyfikatu zawierającego użycie klucza "podpisu cyfrowego" lub jednego z eku uwierzytelniania, umożliwi to łatwiejsze niewłaściwe użycie klucza szyfrowania i podatność na ataki. Dlatego najlepszym rozwiązaniem jest użycie certyfikatu utworzonego specjalnie w celu zabezpieczania poświadczeń DSC, który pomija te użycie klucza i EKU.

Każdy istniejący certyfikat w węźle docelowym , który spełnia te kryteria, może służyć do zabezpieczania poświadczeń DSC.

Tworzenie certyfikatu

Istnieją dwa podejścia, które można zastosować, aby utworzyć i użyć wymaganego certyfikatu szyfrowania (para kluczy publiczny-prywatny).

  1. Utwórz go w węźle docelowym i wyeksportuj tylko klucz publiczny do węzła tworzenia
  2. Utwórz go w węźle tworzenia i wyeksportuj całą parę kluczy do węzła docelowego

Metoda 1 jest zalecana, ponieważ klucz prywatny używany do odszyfrowywania poświadczeń w MOF pozostaje w węźle docelowym przez cały czas.

Tworzenie certyfikatu w węźle docelowym

Klucz prywatny musi być utrzymywany w tajemnicy, ponieważ służy do odszyfrowywania pliku MOF w węźle docelowym Najprostszym sposobem jest utworzenie certyfikatu klucza prywatnego w węźle docelowym i skopiowanie certyfikatu klucza publicznego na komputer używany do tworzenia konfiguracji DSC do pliku MOF. Poniższy przykład:

  1. tworzy certyfikat w węźle docelowym
  2. eksportuje certyfikat klucza publicznego w węźle docelowym.
  3. importuje certyfikat klucza publicznego do magazynu certyfikatów my w węźle Tworzenie.

W węźle docelowym: utwórz i wyeksportuj certyfikat

Węzeł docelowy: Windows Server 2016 i 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

Po wyeksportowaniu należy go DscPublicKey.cer skopiować do węzła tworzenia.

W węźle tworzenia: zaimportuj klucz publiczny certyfikatu

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

Tworzenie certyfikatu w węźle tworzenia

Alternatywnie certyfikat szyfrowania można utworzyć w węźle tworzenia, wyeksportować z kluczem prywatnym jako plik PFX, a następnie zaimportować do węzła docelowego. Jest to bieżąca metoda implementowania szyfrowania poświadczeń DSC na serwerze Nano Server. Mimo że PFX jest zabezpieczony hasłem, powinien być bezpieczny podczas przesyłania. Poniższy przykład:

  1. tworzy certyfikat w węźle Tworzenie.
  2. eksportuje certyfikat wraz z kluczem prywatnym w węźle Tworzenie.
  3. usuwa klucz prywatny z węzła Tworzenie, ale zachowuje certyfikat klucza publicznego w moim magazynie.
  4. importuje certyfikat klucza prywatnego do magazynu certyfikatów My(Personal) w węźle docelowym.
    • musi zostać dodany do magazynu głównego, aby był zaufany przez węzeł docelowy.

W węźle tworzenia: utwórz i wyeksportuj certyfikat

Węzeł docelowy: Windows Server 2016 i 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

Po wyeksportowaniu należy DscPrivateKey.pfx go skopiować do węzła docelowego.

W węźle docelowym: zaimportuj klucz prywatny certyfikatu jako zaufany katalog główny

# 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

Dane konfiguracyjne

Blok danych konfiguracyjnych określa, na których węzłach docelowych ma być wykonywana operacja, czy mają być szyfrowane poświadczenia, jakie są metody szyfrowania i inne informacje. Aby uzyskać więcej informacji na temat bloku danych konfiguracyjnych, zobacz Rozdzielanie danych konfiguracji i środowiska.

Elementy, które można skonfigurować dla każdego węzła, które są powiązane z szyfrowaniem poświadczeń, to:

  • NodeName — nazwa węzła docelowego, dla którego jest konfigurowane szyfrowanie poświadczeń.
  • PsDscAllowPlainTextPassword — określa, czy niezaszyfrowane poświadczenia będą mogły być przekazywane do tego węzła. Nie jest to zalecane.
  • Odcisk palca — odcisk palca certyfikatu, który będzie używany do odszyfrowywania poświadczeń w konfiguracji DSC w węźle docelowym. Ten certyfikat musi istnieć w magazynie certyfikatów komputera lokalnego w węźle docelowym.
  • CertificateFile — plik certyfikatu (zawierający tylko klucz publiczny), który powinien być używany do szyfrowania poświadczeń węzła docelowego. Musi to być binarny plik certyfikatu X.509 zakodowany w formacie DER lub X.509 zakodowany w formacie Base-64.

W tym przykładzie pokazano blok danych konfiguracyjnych, który określa węzeł docelowy do działania na nazwanym węźle docelowym, ścieżkę do pliku certyfikatu klucza publicznego (o nazwie targetNode.cer) oraz odcisk palca klucza publicznego.

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

Skrypt konfiguracyjny

W samym skrypcie konfiguracyjnym użyj parametru PsCredential , aby upewnić się, że poświadczenia są przechowywane przez jak najkrótszy czas. Po uruchomieniu podanego przykładu DSC wyświetli monit o podanie poświadczeń, a następnie zaszyfruje plik MOF przy użyciu pliku CertificateFile skojarzonego z węzłem docelowym w bloku danych konfiguracji. Ten przykładowy kod kopiuje plik z udziału, który jest zabezpieczony dla użytkownika.

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

Konfigurowanie deszyfrowania

Aby Start-DscConfiguration mógł działać, należy poinformować lokalnego Configuration Managera w każdym węźle docelowym, który certyfikat ma być używany do odszyfrowywania poświadczeń, używając zasobu CertificateID w celu zweryfikowania odcisku palca certyfikatu. Ta przykładowa funkcja znajdzie odpowiedni certyfikat lokalny (może być konieczne dostosowanie go tak, aby znalazł dokładnie ten certyfikat, którego chcesz użyć):

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

Po zidentyfikowaniu certyfikatu za pomocą odcisku palca skrypt konfiguracji można zaktualizować tak, aby używał wartości:

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

Uruchamianie konfiguracji

W tym momencie możesz uruchomić konfigurację, która wyświetli dwa pliki:

  • Plik *.meta.mof , który konfiguruje lokalnego Configuration Managera do odszyfrowywania poświadczeń przy użyciu certyfikatu przechowywanego w magazynie komputera lokalnego i identyfikowanego przez jego odcisk palca. Set-DscLocalConfigurationManager stosuje *.meta.mof plik.
  • Plik MOF, który faktycznie stosuje konfigurację. Start-DscConfiguration zastosuje konfigurację.

Te polecenia wykonają następujące kroki:

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

W tym przykładzie konfiguracja DSC zostanie wypchnięta do węzła docelowego. Konfigurację DSC można również zastosować przy użyciu serwera ściągania DSC, jeśli jest dostępny.

Aby uzyskać więcej informacji na temat stosowania konfiguracji DSC przy użyciu serwera ściągania DSC, zobacz Konfigurowanie klienta ściągania DSC .

Przykład modułu szyfrowania poświadczeń

Oto pełny przykład, który obejmuje wszystkie te kroki, a także polecenie cmdlet pomocnika, które eksportuje i kopiuje klucze publiczne:

# 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