Partilhar via


Proteger o Ficheiro MOF

Aplica-se a: Windows PowerShell 4.0, Windows PowerShell 5.0

O DSC gere a configuração dos nós de servidor ao aplicar informações armazenadas num ficheiro MOF, onde o local Configuration Manager (LCM) implementa o estado final pretendido. Uma vez que este ficheiro contém os detalhes da configuração, é importante mantê-lo seguro. Este artigo descreve como garantir que o nó de destino encriptou o ficheiro.

A partir da versão 5.0 do PowerShell, todo o ficheiro MOF é encriptado por predefinição quando é aplicado ao nó com o Start-DSCConfiguration cmdlet . O processo descrito neste artigo só é necessário ao implementar uma solução com o protocolo do serviço Pull se os certificados não forem geridos, para garantir que as configurações transferidas pelo nó de destino podem ser desencriptadas e lidas pelo sistema antes de serem aplicadas (por exemplo, o serviço pull disponível no Windows Server). Os nós registados no Automatização do Azure DSC terão automaticamente certificados instalados e geridos pelo serviço sem necessidade de sobrecarga administrativa.

Nota

Este tópico aborda os certificados utilizados para encriptação. Para encriptação, um certificado autoassinado é suficiente, porque a chave privada é sempre mantida em segredo e a encriptação não implica confiança no documento. Os certificados autoassinados não devem ser utilizados para fins de autenticação. Deve utilizar um certificado de uma Autoridade de Certificação (AC) fidedigna para efeitos de autenticação.

Pré-requisitos

Para encriptar com êxito as credenciais utilizadas para proteger uma configuração do DSC, certifique-se de que tem o seguinte:

  • Algumas formas de emitir e distribuir certificados. Este tópico e os respetivos exemplos partem do princípio de que está a utilizar a Autoridade de Certificação do Active Directory. Para obter mais informações sobre os Serviços de Certificados do Active Directory, veja Descrição Geral dos Serviços de Certificados do Active Directory.
  • Acesso administrativo ao nó ou nós de destino.
  • Cada nó de destino tem um certificado compatível com encriptação guardado no respetivo Arquivo Pessoal. No Windows PowerShell, o caminho para o arquivo é Cert:\LocalMachine\My. Os exemplos neste tópico utilizam o modelo "autenticação de estação de trabalho", que pode encontrar (juntamente com outros modelos de certificado) em Modelos de Certificado Predefinidos.
  • Se estiver a executar esta configuração num computador que não seja o nó de destino, exporte a chave pública do certificado e, em seguida, importe-a para o computador a partir do qual executará a configuração. Certifique-se de que exporta apenas a chave pública ; mantenha a chave privada segura.

Nota

Os Recursos de Script têm limitações no que diz respeito à encriptação. Para obter mais informações, veja Recurso de Script

Processo geral

  1. Configure os certificados, chaves e thumbprints, certificando-se de que cada nó de destino tem cópias do certificado e que o computador de configuração tem a chave pública e o thumbprint.
  2. Crie um bloco de dados de configuração que contenha o caminho e o thumbprint da chave pública.
  3. Crie um script de configuração que defina a configuração pretendida para o nó de destino e configure a desencriptação nos nós de destino ao comandar o Gestor de Configuração Local para desencriptar os dados de configuração com o certificado e o respetivo thumbprint.
  4. Execute a configuração, que definirá as definições de Configuration Manager Local e iniciará a configuração do DSC.

Fluxo de processo para encriptação de credenciais

Requisitos de Certificados

Para decretar a encriptação de credenciais, tem de estar disponível um certificado de chave pública no Nó de Destinofidedigno pelo computador que está a ser utilizado para criar a configuração do DSC. Este certificado de chave pública tem requisitos específicos para que seja utilizado para encriptação de credenciais DSC:

  1. Utilização da Chave:
    • Tem de conter: "KeyEncipherment" e "DataEncipherment".
    • Não deve conter: "Assinatura Digital".
  2. Utilização de Chave Avançada:
    • Tem de conter: Encriptação de Documentos (1.3.6.1.4.1.311.80.1).
    • Não deve conter: Autenticação de Cliente (1.3.6.1.5.5.7.3.2) e Autenticação do Servidor (1.3.6.1.5.5.7.3.1).
  3. A Chave Privada do certificado está disponível no *Node_ de destino.
  4. O Fornecedor do certificado tem de ser "Microsoft RSA SChannel Cryptographic Provider".

Importante

Embora possa utilizar um certificado que contenha uma Utilização de Chave de "Assinatura Digital" ou um dos EKU de Autenticação, isto permitirá que a chave de encriptação seja mais facilmente utilizada indevidamente e vulnerável a ataques. Por isso, é melhor prática utilizar um certificado criado especificamente para proteger credenciais do DSC que omite estas EKUs e Utilização de Chaves.

Qualquer certificado existente no Nó de Destino que cumpra estes critérios pode ser utilizado para proteger as credenciais do DSC.

Criação de certificados

Existem duas abordagens que pode adotar para criar e utilizar o Certificado de Encriptação necessário (par de chaves público-privado).

  1. Crie-a no Nó de Destino e exporte apenas a chave pública para o Nó de Criação
  2. Crie-o no Nó de Criação e exporte todo o par de chaves para o Nó de Destino

O método 1 é recomendado porque a chave privada utilizada para desencriptar credenciais no MOF permanece sempre no Nó de Destino.

Criar o Certificado no Nó de Destino

A chave privada tem de ser mantida em segredo, porque é utilizada para desencriptar o MOF no Nó de Destino A forma mais fácil de o fazer é criar o certificado de chave privada no Nó de Destino e copiar o certificado de chave pública para o computador que está a ser utilizado para criar a configuração do DSC num ficheiro MOF. O exemplo seguinte:

  1. cria um certificado no nó Destino
  2. exporta o certificado de chave pública no nó Destino.
  3. importa o certificado de chave pública para o meu arquivo de certificados no nó Criação.

No Nó de Destino: criar e exportar o certificado

Nó de Destino: Windows Server 2016 e 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

Depois de exportado, o DscPublicKey.cer teria de ser copiado para o Nó de Criação.

No Nó de Criação: importar a chave pública do certificado

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

Criar o Certificado no Nó de Criação

Em alternativa, o certificado de encriptação pode ser criado no Nó de Criação, exportado com a chave privada como um ficheiro PFX e, em seguida, importado no Nó de Destino. Este é o método atual para implementar a encriptação de credenciais DSC no Servidor Nano. Embora o PFX esteja protegido com uma palavra-passe, deve ser mantido seguro durante o trânsito. O exemplo seguinte:

  1. cria um certificado no nó Criação.
  2. exporta o certificado, incluindo a chave privada no nó Criação.
  3. remove a chave privada do nó Criação, mas mantém o certificado de chave pública no meu arquivo.
  4. importa o certificado de chave privada para o arquivo de certificados My(Personal) no nó Destino.
    • tem de ser adicionado ao arquivo de raiz para que seja considerado fidedigno pelo nó Destino.

No Nó de Criação: criar e exportar o certificado

Nó de Destino: Windows Server 2016 e 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

Depois de exportado, o DscPrivateKey.pfx teria de ser copiado para o Nó de Destino.

No Nó de Destino: importar a chave privada do certificado como uma raiz fidedigna

# 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

Dados de configuração

O bloco de dados de configuração define em que nós de destino devem operar, quer encripte ou não as credenciais, os meios de encriptação e outras informações. Para obter mais informações sobre o bloco de dados de configuração, veja Separar Dados de Configuração e de Ambiente.

Os elementos que podem ser configurados para cada nó relacionado com a encriptação de credenciais são:

  • NodeName – o nome do nó de destino para o qual a encriptação de credenciais está a ser configurada.
  • PsDscAllowPlainTextPassword – se as credenciais não encriptadas serão autorizadas a ser transmitidas para este nó. Isto não é recomendado.
  • Thumbprint – o thumbprint do certificado que será utilizado para desencriptar as credenciais na Configuração do DSC no Nó de Destino. Este certificado tem de existir no arquivo de certificados do Computador Local no Nó de Destino.
  • CertificateFile – o ficheiro de certificado (que contém apenas a chave pública) que deve ser utilizado para encriptar as credenciais do Nó de Destino. Tem de ser um ficheiro de certificado de formato X.509 codificado por DER ou X.509 codificado com Base-64.

Este exemplo mostra um bloco de dados de configuração que especifica um nó de destino para agir com o nome targetNode, o caminho para o ficheiro de certificado de chave pública (denominado targetNode.cer) e o thumbprint da chave pública.

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

Script de configuração

No próprio script de configuração, utilize o PsCredential parâmetro para garantir que as credenciais são armazenadas durante o menor período de tempo possível. Quando executar o exemplo fornecido, o DSC irá pedir-lhe credenciais e, em seguida, encriptar o ficheiro MOF com o CertificateFile associado ao nó de destino no bloco de dados de configuração. Este exemplo de código copia um ficheiro de uma partilha que está protegida para um utilizador.

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

Configurar a desencriptação

Antes de Start-DscConfiguration poder funcionar, tem de indicar ao Configuration Manager Local em cada nó de destino qual o certificado a utilizar para desencriptar as credenciais, utilizando o recurso CertificateID para verificar o thumbprint do certificado. Esta função de exemplo irá encontrar o certificado local adequado (poderá ter de o personalizar para encontrar o certificado exato que pretende utilizar):

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

Com o certificado identificado pelo thumbprint, o script de configuração pode ser atualizado para utilizar o valor:

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

Executar a configuração

Neste momento, pode executar a configuração, que irá produzir dois ficheiros:

  • Um *.meta.mof ficheiro que configura a Configuration Manager Local para desencriptar as credenciais com o certificado armazenado no arquivo do computador local e identificado pelo thumbprint. Set-DscLocalConfigurationManager aplica o *.meta.mof ficheiro.
  • Um ficheiro MOF que aplica efetivamente a configuração. Start-DscConfiguration aplica a configuração.

Estes comandos irão realizar esses passos:

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

Este exemplo emitiria a configuração do DSC para o nó de destino. A configuração do DSC também pode ser aplicada através de um Servidor de Solicitação DSC, se estiver disponível.

Veja Configurar um cliente de solicitação DSC para obter mais informações sobre como aplicar configurações de DSC com um Servidor de Solicitação DSC.

Exemplo de Módulo de Encriptação de Credenciais

Eis um exemplo completo que incorpora todos estes passos, além de um cmdlet auxiliar que exporta e copia as chaves públicas:

# 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