仮想サブネット用に暗号化を構成する

適用対象: Windows Server 2022、Windows Server 2019、Windows Server 2016、Azure Stack HCI バージョン 21H2 および 20H2

仮想ネットワークの暗号化を使用すると、"暗号化有効" とマークされているサブネット内で相互に通信する VM 間で、仮想ネットワーク トラフィックの暗号化が有効になります。 また、この機能は、仮想サブネットのデータグラム トランスポート層セキュリティ (DTLS) を利用して、パケットを暗号化します。 DTLS は、物理ネットワークへのアクセスを持つユーザーによる盗聴、改ざん、偽造に対する保護を提供します。

仮想ネットワーク暗号化の要件:

  • SDN 対応の各 Hyper-V ホストにインストールされている暗号化証明書。
  • その証明書の拇印を参照する、ネットワーク コントローラー内の資格情報オブジェクト。
  • 各仮想ネットワークの構成には、暗号化を必要とするサブネットが含まれます。

サブネットで暗号化を有効にした後、そのサブネット内のすべてのネットワーク トラフィックが自動的に暗号化され、さらにアプリケーション レベルの暗号化も実行される可能性があります。 サブネット間を横断するトラフィックは、暗号化済みとしてマークされている場合でも、暗号化されていない状態で自動的に送信されます。 仮想ネットワークの境界を越えるトラフィックも、暗号化されていない状態で送信されます。

注意

同じサブネット上の別の VM と通信する場合、現在接続済みであるか後で接続するかにかかわらず、トラフィックは自動的に暗号化されます。

ヒント

暗号化されたサブネットでのみ通信を行うようにアプリケーションを制限する必要がある場合は、アクセス制御リスト (ACL) を使用して、現在のサブネット内での通信のみを許可できます。 詳細については、「アクセス制御リスト (ACL) を使用してデータセンターのネットワーク トラフィック フローを管理する」を参照してください。

ステップ 1: 暗号化証明書を作成する

各ホストには暗号化証明書がインストールされている必要があります。 すべてのテナントに同じ証明書を使用するか、テナントごとに固有の証明書を生成できます。

  1. 証明書を生成する

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

    スクリプトを実行すると、My ストアに新しい証明書が表示されます。

    PS D:\> dir cert:\\localmachine\my
    PSParentPath: Microsoft.PowerShell.Security\Certificate::localmachine\my
    
    Thumbprint                                Subject
    ----------                                -------
    84857CBBE7A1C851A80AE22391EB2C39BF820CE7  CN=MyNetwork
    5EFF2CE51EACA82408572A56AE1A9BCC7E0843C6  CN=EncryptedVirtualNetworks
    
  2. 証明書をファイルにエクスポートします。

    証明書のコピーが 2 つ必要です。1 つはプライベート キーが入ったもの、もう 1 つは入っていないものです。

    $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. 各 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. 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. 環境内の各サーバーに対して繰り返します。

    サーバーごとに繰り返し実行した後、各 Hyper-V ホストのルートと自分のストアに証明書がインストールされているはずです。

  6. 証明書のインストールを確認します。

    My 証明書ストアと Root 証明書ストアの内容をチェックして、証明書を確認します。

    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. 拇印をメモします。

    拇印は、ネットワーク コントローラーで証明書資格情報オブジェクトを作成するために必要なので、メモする必要があります。

ステップ 2: 証明書資格情報を作成する

ネットワーク コントローラーに接続されている各 Hyper-V ホストに証明書をインストールしたら、次はそれを使用するようにネットワーク コントローラーを構成する必要があります。 これを行うには、ネットワーク コントローラー PowerShell モジュールがインストールされているコンピューターから、証明書の拇印を含む資格情報オブジェクトを作成する必要があります。

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

ヒント

暗号化された各仮想ネットワークでこの資格情報を再利用するか、テナントごとに一意の証明書を展開して使用することができます。

ステップ 3: 暗号化用に仮想ネットワークを構成する

この手順では、仮想ネットワーク名 "My Network" が既に作成され、少なくとも 1 つの仮想サブネットが含まれていると想定しています。 仮想ネットワークの作成の詳細については、「テナントの仮想ネットワークを作成、削除、または更新する」を参照してください。

注意

同じサブネット上の別の VM と通信する場合、現在接続済みであるか後で接続するかにかかわらず、トラフィックは自動的に暗号化されます。

  1. ネットワーク コントローラーから仮想ネットワークおよび資格情報オブジェクトを取得します。

    $vnet = Get-NetworkControllerVirtualNetwork -ConnectionUri $uri -ResourceId "MyNetwork"
    $certcred = Get-NetworkControllerCredential -ConnectionUri $uri -ResourceId "EncryptedNetworkCertificate"
    
  2. 証明書資格情報への参照を追加し、個々のサブネットでの暗号化を有効にします。

    $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. 更新された仮想ネットワーク オブジェクトをネットワーク コントローラーに追加します。

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

"お疲れさまでした。"* これらの手順が終われば完了です。