Configurar a criptografia para uma sub-rede virtual

A criptografia de rede virtual permite a criptografia do tráfego de rede virtual entre VMs que se comunicam entre si em sub-redes marcadas como 'Criptografia habilitada.' Ela também utiliza o DTLS (Datagrama do protocolo TLS) na sub-rede virtual para criptografar os pacotes. O DTLS protege contra interceptações, falsificação e adulteração por qualquer pessoa com acesso à rede física.

A criptografia de rede virtual exige:

  • Certificados de criptografia instalados em cada um dos hosts Hyper-V habilitados para SDN.
  • Um objeto de credencial no controlador de rede que faz referência à impressão digital desse certificado.
  • A configuração em cada uma das redes virtuais contém sub-redes que exigem criptografia.

Após habilitar a criptografia em uma sub-rede, todo o tráfego de rede nessa sub-rede será criptografado automaticamente, além de qualquer criptografia no nível de aplicativo que também possa ocorrer. O tráfego que cruza entre as sub-redes, mesmo que marcado como criptografado, é enviado não criptografado automaticamente. Qualquer tráfego que cruze o limite da rede virtual também é enviado não criptografado.

Observação

Ao se comunicar com outra VM na mesma sub-rede, esteja ela conectada no momento ou posteriormente, o tráfego é criptografado automaticamente.

Dica

Se for necessário restringir os aplicativos para estabelecer comunicação somente na sub-rede criptografada, você poderá usar as ACLs (Listas de Controle de Acesso) apenas para permitir a comunicação dentro da sub-rede atual. Para obter mais informações, consulte Usar ACLs (Listas de Controle de Acesso) para gerenciar o fluxo de tráfego da rede do datacenter.

Etapa 1: Criar o certificado de criptografia

Cada host deve ter um certificado de criptografia instalado. Você pode usar o mesmo certificado para todos os locatários ou gerar um exclusivo para cada locatário.

  1. Gerar o certificado

    $subjectName = "EncryptedVirtualNetworks"
    $cryptographicProviderName = "Microsoft Base Cryptographic Provider v1.0";
    [int] $privateKeyLength = 1024;
    $sslServerOidString = "1.3.6.1.5.5.7.3.1";
    $sslClientOidString = "1.3.6.1.5.5.7.3.2";
    [int] $validityPeriodInYear = 5;
    
    $name = new-object -com "X509Enrollment.CX500DistinguishedName.1"
    $name.Encode("CN=" + $SubjectName, 0)
    
    #Generate Key
    $key = new-object -com "X509Enrollment.CX509PrivateKey.1"
    $key.ProviderName = $cryptographicProviderName
    $key.KeySpec = 1 #X509KeySpec.XCN_AT_KEYEXCHANGE
    $key.Length = $privateKeyLength
    $key.MachineContext = 1
    $key.ExportPolicy = 0x2 #X509PrivateKeyExportFlags.XCN_NCRYPT_ALLOW_EXPORT_FLAG
    $key.Create()
    
    #Configure Eku
    $serverauthoid = new-object -com "X509Enrollment.CObjectId.1"
    $serverauthoid.InitializeFromValue($sslServerOidString)
    $clientauthoid = new-object -com "X509Enrollment.CObjectId.1"
    $clientauthoid.InitializeFromValue($sslClientOidString)
    $ekuoids = new-object -com "X509Enrollment.CObjectIds.1"
    $ekuoids.add($serverauthoid)
    $ekuoids.add($clientauthoid)
    $ekuext = new-object -com "X509Enrollment.CX509ExtensionEnhancedKeyUsage.1"
    $ekuext.InitializeEncode($ekuoids)
    
    # Set the hash algorithm to sha512 instead of the default sha1
    $hashAlgorithmObject = New-Object -ComObject X509Enrollment.CObjectId
    $hashAlgorithmObject.InitializeFromAlgorithmName( $ObjectIdGroupId.XCN_CRYPT_HASH_ALG_OID_GROUP_ID, $ObjectIdPublicKeyFlags.XCN_CRYPT_OID_INFO_PUBKEY_ANY, $AlgorithmFlags.AlgorithmFlagsNone, "SHA512")
    
    
    #Request Certificate
    $cert = new-object -com "X509Enrollment.CX509CertificateRequestCertificate.1"
    
    $cert.InitializeFromPrivateKey(2, $key, "")
    $cert.Subject = $name
    $cert.Issuer = $cert.Subject
    $cert.NotBefore = (get-date).ToUniversalTime()
    $cert.NotAfter = $cert.NotBefore.AddYears($validityPeriodInYear);
    $cert.X509Extensions.Add($ekuext)
    $cert.HashAlgorithm = $hashAlgorithmObject
    $cert.Encode()
    
    $enrollment = new-object -com "X509Enrollment.CX509Enrollment.1"
    $enrollment.InitializeFromRequest($cert)
    $certdata = $enrollment.CreateRequest(0)
    $enrollment.InstallResponse(2, $certdata, 0, "")
    

    Depois de executar o script, um novo certificado será exibido em Meu repositório:

    PS D:\> dir cert:\\localmachine\my
    PSParentPath: Microsoft.PowerShell.Security\Certificate::localmachine\my
    
    Thumbprint                                Subject
    ----------                                -------
    84857CBBE7A1C851A80AE22391EB2C39BF820CE7  CN=MyNetwork
    5EFF2CE51EACA82408572A56AE1A9BCC7E0843C6  CN=EncryptedVirtualNetworks
    
  2. Exporte o certificado para um arquivo.

    Você precisa de duas cópias do certificado, uma com a chave privada e outra sem.

    $subjectName = "EncryptedVirtualNetworks"
    $cert = Get-ChildItem cert:\localmachine\my | ? {$_.Subject -eq "CN=$subjectName"}
    [System.io.file]::WriteAllBytes("c:\$subjectName.pfx", $cert.Export("PFX", "secret"))
    Export-Certificate -Type CERT -FilePath "c:\$subjectName.cer" -cert $cert
    
  3. Instalar os certificados em cada um dos hosts hyper-v

    PS C:\> dir c:\$subjectname.*
    
    Directory: C:\
    
    Mode                LastWriteTime         Length Name
    ----                -------------         ------ ----
    -a----        9/22/2017   4:54 PM            543 EncryptedVirtualNetworks.cer
    -a----        9/22/2017   4:54 PM           1706 EncryptedVirtualNetworks.pfx
    
  4. Instalação em um host Hyper-V

    $server = "Server01"
    
    $subjectname = "EncryptedVirtualNetworks"
    copy c:\$SubjectName.* \\$server\c$
    invoke-command -computername $server -ArgumentList $subjectname,"secret" {
        param (
            [string] $SubjectName,
            [string] $Secret
        )
        $certFullPath = "c:\$SubjectName.cer"
    
        # create a representation of the certificate file
        $certificate = new-object System.Security.Cryptography.X509Certificates.X509Certificate2
        $certificate.import($certFullPath)
    
        # import into the store
        $store = new-object System.Security.Cryptography.X509Certificates.X509Store("Root", "LocalMachine")
        $store.open("MaxAllowed")
        $store.add($certificate)
        $store.close()
    
        $certFullPath = "c:\$SubjectName.pfx"
        $certificate = new-object System.Security.Cryptography.X509Certificates.X509Certificate2
        $certificate.import($certFullPath, $Secret, "MachineKeySet,PersistKeySet")
    
        # import into the store
        $store = new-object System.Security.Cryptography.X509Certificates.X509Store("My", "LocalMachine")
        $store.open("MaxAllowed")
        $store.add($certificate)
        $store.close()
    
        # Important: Remove the certificate files when finished
        remove-item C:\$SubjectName.cer
        remove-item C:\$SubjectName.pfx
    }
    
  5. Repita para cada servidor em seu ambiente.

    Depois de repetir para cada servidor, você deve ter um certificado instalado na raiz e em Meu repositório de cada host Hyper-V.

  6. Verifique a instalação do certificado.

    Verifique os certificados conferindo o conteúdo dos repositórios de certificados Meu repositório e Raiz:

    PS C:\> enter-pssession Server1
    
    [Server1]: PS C:\> get-childitem cert://localmachine/my,cert://localmachine/root | ? {$_.Subject -eq "CN=EncryptedVirtualNetworks"}
    
    PSParentPath: Microsoft.PowerShell.Security\Certificate::localmachine\my
    
    Thumbprint                                Subject
    ----------                                -------
    5EFF2CE51EACA82408572A56AE1A9BCC7E0843C6  CN=EncryptedVirtualNetworks
    
    PSParentPath: Microsoft.PowerShell.Security\Certificate::localmachine\root
    
    Thumbprint                                Subject
    ----------                                -------
    5EFF2CE51EACA82408572A56AE1A9BCC7E0843C6  CN=EncryptedVirtualNetworks
    
  7. Anote a impressão digital.

    Faça uma anotação da impressão digital, pois você precisa dela para criar o objeto de credencial de certificado no controlador de rede.

Etapa 2: Criar a credencial de certificado

Depois de instalar o certificado em cada um dos hosts Hyper-V conectados ao controlador de rede, você deverá configurar o controlador de rede para usá-lo. Para fazer isso, crie um objeto de credencial que contém a impressão digital do certificado do computador com os módulos do PowerShell do Controlador de Rede instalados.

///Replace with the thumbprint from your certificate
$thumbprint = "5EFF2CE51EACA82408572A56AE1A9BCC7E0843C6"

$uri = "https://nc.contoso.com"

///Replace with your Network Controller URI
Import-module networkcontroller

$credproperties = new-object Microsoft.Windows.NetworkController.CredentialProperties
$credproperties.Type = "X509Certificate"
$credproperties.Value = $thumbprint
New-networkcontrollercredential -connectionuri $uri -resourceid "EncryptedNetworkCertificate" -properties $credproperties -force

Dica

Você pode reutilizar essa credencial para cada rede virtual criptografada ou implantar e usar um certificado exclusivo para cada locatário.

Etapa 3: Configurar uma rede virtual para criptografia

Esta etapa pressupõe que você já tenha criado um nome de rede virtual "Minha Rede" e ele contenha pelo menos uma sub-rede virtual. Para saber mais sobre como criar redes virtuais, confira Criar, excluir ou atualizar redes virtuais de locatário.

Observação

Ao se comunicar com outra VM na mesma sub-rede, esteja ela conectada no momento ou posteriormente, o tráfego é criptografado automaticamente.

  1. Recupere os objetos Rede Virtual e Credencial do controlador de rede:

    $vnet = Get-NetworkControllerVirtualNetwork -ConnectionUri $uri -ResourceId "MyNetwork"
    $certcred = Get-NetworkControllerCredential -ConnectionUri $uri -ResourceId "EncryptedNetworkCertificate"
    
  2. Adicione uma referência à credencial de certificado e habilite a criptografia em sub-redes individuais:

    $vnet.properties.EncryptionCredential = $certcred
    
    # Replace the Subnets index with the value corresponding to the subnet you want encrypted.
    # Repeat for each subnet where encryption is needed
    $vnet.properties.Subnets[0].properties.EncryptionEnabled = $true
    
  3. Coloque o objeto Rede Virtual atualizado no controlador de rede:

    New-NetworkControllerVirtualNetwork -ConnectionUri $uri -ResourceId $vnet.ResourceId -Properties $vnet.Properties -force
    

Parabéns!* Você terminará depois de concluir as etapas.