Update: NAT-Switch für Hyper-V im Windows Server 2016 TP5 | Hyper-V Server Blog

Update: NAT-Switch für Hyper-V im Windows Server 2016 TP5

thVor einiger Zeit hatte ich hier einen Beitrag veröffentlicht über einen neuen NAT Switchtyp im Hyper-V, der es ermöglichte, dass VMs in einem internal Hyper-V Netzwerk mit der Außenwelt bzw. mit dem Internet kommunizieren können. Diese Informationen bezogen sich auf die Technical Preview 4 von Windows Server 2016 bzw. Windows 10 Build 10586 (November 2015 Update 1511).

Nun hat Microsoft vor ein paar Tagen die Technical Preview 5 von Windows Server 2016 und auch eine neue Windows 10 Insider Preview (Build 14332) veröffentlicht, in denen die Implementierung für NAT geändert wurde. Den Switchtyp NAT gibt es nicht mehr und damit ist auch meine seinerzeitige Beschreibung hinfällig. Vielmehr gibt es jetzt eine Anleitung, wie man auf Basis eines internen Hyper-V Switch ein NAT-Subnetz einrichten kann. Diese neue Vorgehensweise soll hier kurz beschrieben werden einschließlich von 2 Powershell Funktionen, die dies etwas vereinfachen.

3 Schritte sind für ein NAT-Subnetz notwendig:

  1. Erzeugen eines internen Switch im Hyper-V.
  2. Festlegen einer IP-Adresse für den internen Switch. Diese IP-Adresse stellt dann das Standard-Gateway für das NAT-Subnetz dar.
  3. Erzeugen eines NetNat Objekts, mit dem das NAT-Subnetz definiert wird und das später die Netzwerk-Adressübersetzung vornimmt.

Will man ein solches NAT-Subnetz wieder entfernen, so muss man die erzeugten Objekte in umgekehrter Reihenfolge wieder entfernen. Dies ist wichtig, damit keine “Leichen” im System zurückbleiben. Ich werde weiter unten darauf zurückkommen.

Und es gibt eine Einschränkung: Mehr als 1 NetNat Objekt wird derzeit nicht unterstützt, d.h. es kann aktuell nur 1 NAT-Subnetz auf einem Hyper-V Host angelegt werden. Die Anzahl “normaler” interner Switches ist davon nicht berührt. Benötigt man weitere NAT-Subnetze, muss auf “klassische” Vorgehensweisen zurückgegriffen werden, also z.B. eine zusätzliche VM mit 2 virtuellen Netzwerkkarten, in der ein Windows Server mit der Rolle Remote Access installiert ist.

Aber es gibt auch eine gute Nachricht: Die hier beschriebene Vorgehensweise funktioniert nicht nur in den neuen Betriebssystemversionen Server 2016 TP5 und Win10 Build 14332, sondern kann auch in den Vorgängerversionen TP4 bzw. Win10 Build 10586 angewendet werden und erzeugt dort auch nicht die beschriebene Unschönheit von “verlorenen” IP-Subnetzen.

Erzeugen eines internen Switch im Hyper-V

Das Erzeugen eines internen Switch im Hyper-V kann entweder über die GUI oder über Powershell geschehen. Ich werde hier gleich mit der Powershell arbeiten, da die weiteren Schritte ebenfalls damit ausgeführt werden müssen.

In einer Powershell Konsole mit Administratorberechtigung geben wir folgenden Befehl ein:

New-VMSwitch -Name <Switch Name> -SwitchType Internal

wobei <Switch Name> den Namen des anzulegenden Switch darstellt, also z.B. NatSwitch80:

image

 

 

Festlegen einer IP-Adresse für den internen Switch

Für den gerade erzeugten internen Switch wurde im Hyper-V Host ein virtueller Netzwerkadapter erzeugt, dem wir jetzt eine IP-Adresse aus dem gewünschten NAT-Subnetz zuweisen müssen. Diese IP-Adresse stellt dann das Standard-Gateway dar für die VMs, die mit dem NAT-Subnetz verbunden werden. Typischerweise verwendet man dafür die erste gültige IP-Adresse aus dem NAT-Subnetzbereich. Soll also das NAT-Subnetz z.B. den IP-Bereich 192.168.80.0 mit Subnetzmaske 255.255.255.0 bekommen (in CIDR Form 192.168.80.0/24), so wird man als Gateway-Adresse 192.168.80.1 wählen. Es kann aber auch jede andere IP-Adresse aus diesem Bereich verwendet werden.

Das Zuweisen einer IP-Adresse zu einem Netzwerkadapter kann mit dem CmdLet New-NetIPAddress erfolgen:

New-NetIPAddress –IPAddress <GatewayIP> –PrefixLength <PrefixLength> –InterfaceIndex <ifindex>

wobei <GatewayIP> die gewünschte IP-Adresse und <PrefixLength> die Länge der Subnetz-Maskedarstellt, für unser Beispiel also 192.168.80.1 und Länge 24.

Schwieriger wird es mit dem Parameter <ifindex>. Jeder Netzwerkadapter hat einen eindeutigen Index im System, den wir uns mit dem CmdLet Get-NetAdapter anzeigen lassen können:

image

In unserem Beispiel sehen wir einen ifindex 10.

Der Interfaceindex kann aber auch direkt mit Powershell ermittelt werden und dann in einer Variablen gespeichert werden:

$ifindex = (Get-NetAdapter | where {$_.Name –match “Natswitch80”}).ifIndex

Nun kann das Zuweisen der IP-Adresse also wie folgt geschehen:

New-NetIPAddress -IPAddress 192.168.80.1 -PrefixLength 24 -InterfaceIndex $ifindex

image

 

 

 

 

 

 

Erzeugen eines NetNat Objekts

Jetzt müssen wir noch ein NetNat Objekt mit dem CmdLet New-NetNat erzeugen:

New-NetNat –Name <NAT-Name> -InternalIPInterfaceAddressPrefix "<NAT-IP-Bereich/PrefixLength>"

Beim Parameter <NAT-Name> können wir einen beliebigen Namen für das NAT-Objekt angeben. Ich empfehle jedoch, hier den gleichen Namen zu verwenden wie für den internen Hyper-V Switch. So ist später leichter ein Zusammenhang sichtbar. Meine weiter unten noch beschriebenen Powershell-Funktionen gehen von dieser Namenskonvention aus.

Für <NAT-IP-Bereich/PrefixLength> geben wir in CIDR Form den IP-Bereich an, für den das NetNat-Objekt gelten soll. Für unser Beispiel also 192.168.80.0/24

New-NetNat –Name “Natswitch80” -InternalIPInterfaceAddressPrefix "192.168.80.0/24"

image

Damit sind wir mit dem Erzeugen eines NAT-Subnetzes über einen internen virtuellen Switch im Hyper-V fertig.

Konfiguration der mit dem NAT-Switch verbundenen VMs

Nachdem wir jetzt einen virtuellen internen Switch einschließlich eines NetNat Objekts erzeugt haben, können wir im Hyper-V VMs anlegen und diese mit diesem Switch verbinden. Dabei stellt sich die Frage, wie diese VMs ihre IP-Adressen erhalten. Unser NAT-Switch enthält nämlich keinen DHCP-Server (wie man dies von anderen Virtualisierungsprogrammen kennt). Wir müssen also die IP-Konfiguration entweder manuell durchführen oder in einer der VMs einen DHCP-Server installieren.

 

IP-Konfiguration per GUI

Die manuelle IP-Konfiguration können wir wie üblich über die GUI in der VM durchführen. Wichtig dabei ist, eine freie IP-Adresse aus dem Subnetz-Bereich des NAT-Switch zu wählen (im Beispiel 192.168.80.201) und als Standardgateway die IP-Adresse des für den NAT-Switch erzeugten virtuellen Netzwerkadapter im Host anzugeben (im Beispiel 192.168.80.1).

image

 

 

 

 

 

 

 

 

 

 

 

IP-Konfiguration per Powershell Direct

Nachdem unser Host ja unter einem aktuellen Windows 10 oder Windows Server 2016 läuft, können wir die IP-Konfiguration unserer VMs auch per PowerShell Direct durchführen, vorausgesetzt dass auch in ihnen eine dieser aktuellen Windows Versionen läuft.

Besonders hilfreich ist dies, wenn in der VM kein GUI verfügbar ist wie z.B. bei einer Core Server oder Nano Server Installation.

Um Powershell Direct nutzen zu können, müssen wir die Powershell auf dem Hyper-V Host, auf dem die zu konfigurierende VM läuft, als Administrator starten. Dann können wir eine interaktive Powershell-Sitzung mit dem folgenden Kommando starten:

Enter-PSSession –VMName <VMName>

wobei <VMName> der Name der zu bearbeitenden VM ist, wie er im Hyper-V Manager angezeigt wird. Wichtig: Der interne Computername der VM kann davon abweichen; er lässt sich allerdings in der Poweershell Direct Sitzung ändern!

Der VM können wir jetzt eine IP-Adresse mi dem folgenden Kommando zuweisen – bleiben wir bei unserem Beispiel:

New-NetIPAddress -InterfaceAlias "Ethernet" -AddressFamily IPv4 -IPAddress 192.168.80.201 -PrefixLength 24 -DefaultGateway 192.168.80.1

Entfernen eines NAT-Subnetzes

Will man ein nach der vorstehenden Beschreibung erzeugtes NAT-Subnetz wieder entfernen, so sollten die verschiedenen Objekte in umgekehrter Reihenfolge wieder entfernt werden. Die folgenden Kommandos müssen in einer Powershell-Sitzung mit administrativen Rechten ausgeführt werden.

1. Entfernen des NetNat-Objekts mit dem CmdLet Remove-NetNat

Für unser obiges Beispiel mit dem NatSwitch80:

Remove-NetNat NatSwitch80 -Confirm:$false

2. Entfernen der IP-Adresse, die dem Switch zugewiesen wurde, mit dem CmdLet Remove-NetIPAddress, wobei wir wieder den InterfacIndex des virtuellen Netzwerkadapters für den Switch benötigen.

InterfaceIndex ermitteln:

$ifindex = (Get-NetAdapter | where {$_.Name –match NatSwitch80}).ifIndex

IP-Adresse entfernen:

Remove-NetIPAddress -InterfaceIndex $ifindex -Confirm:$false

Anmerkung: Wird die IP-Adresse nicht entfernt, bleibt sie als “Leiche” im System “hängen”, was bei einer späteren Wiederverwendung zu einem Fehler “IP Address already exists” führt.

3. Entfernen des Switch für das NAT-Subnetz mit dem CmdLet Remove-VMSwitch:

Remove-VMSwitch -Name NatSwitch80 -Force:$true -Confirm:$false

Powershell Funktionen zum Erzeugen und Entfernen eines virtuellen NAT Switch im Hyper-V

Um die Tipparbeit zum Erzeugen und Entfernen eines virtuellen NAT-Switch im Hyper-V etwas zu erleichtern, habe ich mir 2 Powershell Funktionen geschrieben, so dass mit einem Aufruf ein NAT-Switch erzeugt oder entfernt werden kann, wobei meine Empfehlung für die Benennung des NetNat-Objekts berücksichtigt werden.

Die Funktionen habe ich in einer Powershell Skriptdatei NatSwitch.ps1 zusammengefasst, die folgendermaßen in einer Powershell-Sitzung mit administrativen Rechten gehandhabt werden kann:

Laden der Skriptdatei NatSwitch.ps1 in die aktuelle Sitzung per “Dot Sourcing”:

. .\NatSwitch.ps1

Jetzt können die Funktionen direkt wie CmdLets aufgerufen werden, also z.B.

New-NatSwitch -Name NatSwitch80 -InternalIPInterfaceAddressPrefix 192.168.80.0 -PrefixLength 24 -GatewayIP 192.168.80.1

erzeugt den in den vorstehenden Beispielen verwendeten NAT-Switch NatSwitch80 für das NAT-Subnetz 192.168.80.0/24 mit der Gatewayadresse 192.168.80.1

Hier folgt noch der Sourcecode der Skriptdatei NatSwitch.ps1:

Function New-NatSwitch (
    [Parameter(Mandatory)]
    [ValidateNotNullOrEmpty()]
    [String]$Name,

    [Parameter(Mandatory)]
    [ValidateNotNullOrEmpty()]
    [String]$InternalIPInterfaceAddressPrefix,

    [Int]$PrefixLength,

    [Parameter(Mandatory)]
    [ValidateNotNullOrEmpty()]
    [String]$GatewayIP
    )
{
    New-VMSwitch -Name $Name -SwitchType Internal
    # find InterfaceIndex of the network adapter for the newly created internal switch
    $ifindex = (Get-NetAdapter | where {$_.Name -match $Name}).ifIndex
    New-NetIPAddress -IPAddress $GatewayIP -PrefixLength $PrefixLength -InterfaceIndex $ifindex
    New-NetNat -Name $Name -InternalIPInterfaceAddressPrefix "$InternalIPInterfaceAddressPrefix/$PrefixLength"
}


Function Remove-NatSwitch (
    [Parameter(Mandatory)]
    [ValidateNotNullOrEmpty()]
    [String]$Name
    )
{
    Remove-NetNat $Name -Confirm:$false
    # find InterfaceIndex of the network adapter for the previously created internal switch
    $ifindex = (Get-NetAdapter | where {$_.Name -match $Name}).ifIndex
    Remove-NetIPAddress -InterfaceIndex $ifindex -Confirm:$false
    Remove-VMSwitch -Name $Name -Force:$true -Confirm:$false
}

Ich hoffe, dieses Update zum Thema NAT-Switch im Hyper-V hilft dem ein oder anderen Tester beim Umstieg auf die neueren Preview Versionen von Windows Server 2016 bzw. Windows 10.

Gerhard Glenk
 

Diplom Informatiker Gerhard Glenk ist seit über 30 Jahren in der IT-Branche tätig und arbeitet für die Rachfahl IT-Solutions GmbH & Co. KG als freier Mitarbeiter in den Bereichen Cloud Computing mit Microsoft Technologien wie Hyper-V, System Center und Windows Azure Pack.

  • Michael sagt:

    Hallo,

    das Skript hat noch einen kleinen Fehler bei Anlegen des NetNat Objekts.
    So klappt es:
    New-NetNat -Name $Name -InternalIPInterfaceAddressPrefix $InternalIPInterfaceAddressPrefix’/’$PrefixLength

  • Gerhard Glenk sagt:

    Michael,

    der Einwand ist nur bedingt richtig. Ich habe ja den Parameterwert in Anführungszeichen (“…”) gesetzt, um genau den Effekt zu verhindern, dass die Powershell den Schrägstrich als Divisionszeichen interpretiert. Lässt man die Anführungszeichen weg, dann muss natürlich der Schrägstrich mit Apostrophen umgeben sein, damit er als String / Char interpretiert wird. Mir persönlich ist die Schreibweise mit Anführungszeichen sympathischer; da erkenne ich gleich, dass alles ein String sein soll – wahrscheinlich Geschmackssache.

    Gerhard

  • >