設定虛擬子網路的加密
虛擬網路加密可讓虛擬網路流量在彼此於標示為「加密已啟用」的子網路內通訊的 VM 之間進行加密。 這項功能也利用虛擬子網路上的資料包傳輸層安全性 (DTLS) 來加密封包。 DTLS 提供保護以防止任何可存取實體網路的人進行竊聽、竄改和偽造。
虛擬網路加密需要:
- 安裝在每個已啟用 SDN 的 Hyper-V 主機上的加密憑證。
- 網路控制站中的認證物件,參考該憑證的指紋。
- 每個虛擬網路上的設定都包含需要加密的子網路。
在子網路上啟用加密之後,除了可能也會進行的任何應用層級加密之外,該子網路內的所有網路流量都會自動加密。 即使標示為加密,子網路之間的流量也會自動傳送未加密。 任何跨越虛擬網路界限的流量也會未經加密傳送。
注意
與同一個子網路上的另一個 VM 通訊時,無論它是目前連接還是稍後連接,流量都會自動加密。
提示
如果您必須限制應用程式只在加密的子網路上通訊,則只能使用存取控制清單 (ACL) 來允許目前子網路內的通訊。 如需詳細資訊,請參閱使用存取控制清單 (ACL) 來管理資料中心網路流量。
步驟 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
將該憑證匯出到一個檔案中。
您需要該憑證的兩份副本,一份具有私鑰,一份沒有。
$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
在每台 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
在 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 }
針對您環境中的每台伺服器重複執行。
針對每台伺服器重複執行之後,您應該在每台 Hyper-V 主機的 Root 和 My 存放區中安裝了憑證。
確認安裝憑證。
藉由檢查 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
記下指紋 (Thumbprint)。
您必須記下指紋,因為您需要它以在網路控制站中建立憑證認證物件。
步驟 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" 的虛擬網路,且它至少包含一個虛擬子網路。 如需建立虛擬網路的詳細資訊,請參閱建立、刪除或更新租用戶虛擬網路。
注意
與同一個子網路上的另一個 VM 通訊時,無論它是目前連接還是稍後連接,流量都會自動加密。
從網路控制站中擷取虛擬網路和認證物件:
$vnet = Get-NetworkControllerVirtualNetwork -ConnectionUri $uri -ResourceId "MyNetwork" $certcred = Get-NetworkControllerCredential -ConnectionUri $uri -ResourceId "EncryptedNetworkCertificate"
新增憑證認證的參考並在各個子網路上啟用加密:
$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
將更新後的虛擬網路物件放入網路控制站中:
New-NetworkControllerVirtualNetwork -ConnectionUri $uri -ResourceId $vnet.ResourceId -Properties $vnet.Properties -force
恭喜!* 完成這些步驟之後,您就完成了。