Udostępnij za pośrednictwem


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, gdzie lokalna Configuration Manager (LCM) implementuje żądany stan końcowy. Ponieważ ten plik zawiera szczegóły konfiguracji, ważne jest, aby zachować bezpieczeństwo. 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 Start-DSCConfiguration przy użyciu polecenia cmdlet . Proces opisany w tym artykule jest wymagany tylko podczas implementowania rozwiązania przy użyciu protokołu usługi ściągania, jeśli certyfikaty nie są zarządzane, aby upewnić się, że konfiguracje pobrane przez węzeł docelowy można odszyfrować i odczytać 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 zarządzane przez usługę bez konieczności wprowadzania kosztów administracyjnych.

Uwaga

W tym temacie omówiono certyfikaty używane do szyfrowania. W przypadku szyfrowania certyfikat z podpisem własnym jest wystarczający, ponieważ klucz prywatny jest zawsze przechowywany wpisów tajnych, a szyfrowanie nie oznacza zaufania do dokumentu. Certyfikaty z podpisem własnym nie powinny być używane do celów uwierzytelniania. Do celów uwierzytelniania należy użyć certyfikatu z zaufanego urzędu certyfikacji.

Wymagania wstępne

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

  • Niektóre sposoby wystawiania i rozpowszechniania certyfikatów. W tym temacie i w jego przykładach założono, że używasz urzędu certyfikacji usługi Active Directory. Aby uzyskać więcej informacji na temat usług certyfikatów Active Directory, zobacz Omówienie usług certyfikatów Active Directory.
  • Dostęp administracyjny do węzła docelowego lub węzłów.
  • Każdy węzeł docelowy ma certyfikat z obsługą szyfrowania zapisany w magazynie osobistym. W Windows PowerShell ścieżka do sklepu to Cert:\LocalMachine\My. Przykłady w tym temacie używają 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 zostanie uruchomiona na komputerze innym niż węzeł docelowy, wyeksportuj klucz publiczny certyfikatu, a następnie zaimportuj ją na komputer, z którego zostanie uruchomiona konfiguracja. Upewnij się, że eksportujesz tylko klucz publiczny ; zachowaj bezpieczeństwo klucza prywatnego.

Uwaga

Zasoby skryptów mają ograniczenia dotyczące szyfrowania. Aby uzyskać więcej informacji, zobacz Zasób skryptu

Ogólny proces

  1. Skonfiguruj certyfikaty, klucze i odciski palca, 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 konfiguracji zawierający ś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 przez polecenie lokalnego menedżera konfiguracji w celu odszyfrowania danych konfiguracji przy użyciu certyfikatu i odcisku palca.
  4. Uruchom konfigurację, która ustawi ustawienia lokalne Configuration Manager i uruchom konfigurację DSC.

Przepływ procesu szyfrowania poświadczeń

Wymagania dotyczące certyfikatów

Aby przeprowadzić szyfrowanie poświadczeń, certyfikat klucza publicznego musi być dostępny w węźle docelowymzaufanym przez komputer używany do tworzenia konfiguracji DSC. Ten certyfikat klucza publicznego ma określone wymagania dotyczące szyfrowania poświadczeń DSC:

  1. Użycie klucza:
    • Musi zawierać: "KeyEncipherment" i "DataEncipherment".
    • Nie powinien zawierać: "Podpis cyfrowy".
  2. Rozszerzone użycie klucza:
    • Musi zawierać: Szyfrowanie dokumentów (1.3.6.1.4.1.311.80.1).
    • Nie należy 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 w *Node_ docelowym.
  4. Dostawca certyfikatu musi być "Dostawca kryptograficzny Microsoft RSA SChannel".

Ważne

Chociaż można użyć certyfikatu zawierającego użycie klucza "Podpis cyfrowy" lub jeden z jednostek EKU uwierzytelniania, umożliwi to łatwiejsze użycie klucza szyfrowania i podatne na ataki. Najlepszym rozwiązaniem jest użycie certyfikatu utworzonego specjalnie na potrzeby zabezpieczania poświadczeń DSC, które pomijają te użycie kluczy 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ą dwie metody tworzenia i używania wymaganego certyfikatu szyfrowania (pary kluczy publicznych i prywatnych).

  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

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

Tworzenie certyfikatu w węźle docelowym

Klucz prywatny musi być przechowywany wpisów tajnych, ponieważ służy do odszyfrowywania moF w węźle docelowym Najprostszym sposobem na utworzenie certyfikatu klucza prywatnego w węźle docelowym i skopiowanie certyfikatu klucza publicznego do komputera używanego 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 mojego magazynu certyfikatów 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 DscPublicKey.cer element musi zostać skopiowany 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 można utworzyć certyfikat szyfrowania w węźle tworzenia, wyeksportowany z kluczem prywatnym jako plik PFX, a następnie zaimportowany w węźle docelowym. Jest to bieżąca metoda implementowania szyfrowania poświadczeń DSC na serwerze Nano Server. Chociaż plik PFX jest zabezpieczony hasłem, należy zachować bezpieczeństwo podczas przesyłania. Poniższy przykład:

  1. tworzy certyfikat w węźle Tworzenie.
  2. eksportuje certyfikat, w tym klucz prywatny w węźle Tworzenie.
  3. usuwa klucz prywatny z węzła Tworzenie, ale przechowuje certyfikat klucza publicznego w moim magazynie.
  4. importuje certyfikat klucza prywatnego do magazynu certyfikatów My(Personal) w węźle Docelowy.
    • Należy go dodać 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 DscPrivateKey.pfx element musi zostać skopiowany do węzła docelowego.

W węźle docelowym: zaimportuj klucz prywatny certyfikatu jako zaufany 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 konfiguracji

Blok danych konfiguracji definiuje węzły docelowe do działania, niezależnie od tego, czy należy szyfrować poświadczenia, środki szyfrowania i inne informacje. Aby uzyskać więcej informacji na temat bloku danych konfiguracji, zobacz Oddzielanie konfiguracji i danych środowiska.

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

  • NodeName — nazwa węzła docelowego, dla którego jest konfigurowane szyfrowanie poświadczeń.
  • PsDscAllowPlainTextPassword — czy niezaszyfrowane poświadczenia będą mogły zostać przekazane 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 służyć do szyfrowania poświadczeń węzła docelowego. Musi to być plik certyfikatu X.509 zakodowany w formacie X.509 lub X.509 zakodowany w formacie Base-64.

W tym przykładzie pokazano blok danych konfiguracji, który określa węzeł docelowy do działania na nazwanym węźle targetNode, ścieżkę do pliku certyfikatu klucza publicznego (o nazwie targetNode.cer) i 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 konfiguracji

W samym skrycie konfiguracji użyj parametru PsCredential , aby upewnić się, że poświadczenia są przechowywane przez najkrótszy możliwy 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ład kodu kopiuje plik z udziału zabezpieczonego użytkownikowi.

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 odszyfrowywania

Przed rozpoczęciem konfiguracji DscConfiguration należy poinformować Configuration Manager lokalne w każdym węźle docelowym, którego certyfikatu używać do odszyfrowywania poświadczeń przy użyciu zasobu CertificateID w celu zweryfikowania odcisku palca certyfikatu. Ta przykładowa funkcja znajdzie odpowiedni certyfikat lokalny (może być konieczne dostosowanie go, aby znaleźć dokładny 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ć, aby użyć 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

Na tym etapie można uruchomić konfigurację, która zwróci dwa pliki:

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

Te polecenia umożliwiają wykonanie tych kroków:

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 obejmujący wszystkie te kroki oraz 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