NAT-Netzwerk

Ein NAT-Netzwerk kann genutzt werden, um Anfragen aus einem privaten VM-Netzwerk (z. B. einem Host-Only-Netzwerk) an ein externes Netzwerk zu schicken.

NAT-Netzwerk 1:
VM-Instanz mit einer NAT-Netzwerkkonfiguration.

Unter TwinCAT/BSD muss dafür das Weiterleiten von IP-Pakten zwischen Netzwerkschnittstellen aktiviert werden:

doas sysctl net.inet.ip.forwarding=1

Um diese Einstellung persistent zu speichern kann net.inet.ip.forwarding=1 der Datei /etc/sysctl.conf hinzugefügt werden. Außerdem werden für die Übersetzung der privaten Netzwerkadressen in ein externes Netzwerk entsprechende NAT-Regeln (Network-Address-Translation-Regeln) im pf(8) benötigt.

Im folgenden Beispiel wird die vmnet0 Konfiguration aus dem Kapitel Host-Only-Netzwerk für das private Netzwerk zwischen virtueller Maschine und TwinCAT/BSD Host verwendet.

ifconfig vmnet0
vmnet0: flags=8843<UP,BROADCAST,RUNNING,SIMPLEX,MULTICAST> metric 0 mtu 1500
        options=80000<LINKSTATE>
        ether 58:9c:fc:10:56:5b
        inet 192.168.1.1 netmask 0xffffff00 broadcast 192.168.1.255
        groups: vmnet
        media: Ethernet autoselect
        status: no carrier
        nd6 options=29<PERFORMNUD,IFDISABLED,AUTO_LINKLOCAL>

Über das physische Netzwerkinterface igb0 ist der IPC mit einem externen Netzwerk verbunden:

ifconfig igb0
igb0: flags=8863<UP,BROADCAST,RUNNING,SIMPLEX,MULTICAST> metric 0 mtu 1500
        options=4a004a9<RXCSUM,VLAN_MTU,JUMBO_MTU,VLAN_HWCSUM,LRO,RXCSUM_IPV6,NOMAP>
        ether 00:01:05:62:3b:b0
        inet 172.17.98.154 netmask 0xffffff00 broadcast 172.17.98.255
        media: Ethernet autoselect (1000baseT <full-duplex>)
        status: active
        nd6 options=29<PERFORMNUD,IFDISABLED,AUTO_LINKLOCAL>

Für die Übersetzung der privaten Adressen in das externe Netzwerk kann folgende pf-Regel zunächst in einer Textdatei (samplevm.nat.conf) gespeichert werden und anschließend über pfctl(8) geladen werden:

nat on igb0 from vmnet0:network to any -> (igb0)
doas pfctl -a "bhf-nat/samplevm-nat" -f samplevm.nat.conf

Zusätzlich soll eingehender Netzwerkverkehr in das private Netzwerk erlaubt werden:

pass from vmnet0:network to any keep state

Der Regelsatz kann wiederum in einer Textdatei gespeichert und über pfctl(8) geladen werden:

doas pfctl -a "bhf/bhyve/samplevm " -f samplevm.filters.conf

Sind beide Regelsätze geladen, kann die virtuelle Maschine mit vmnet0 als Backend für den virtio-net basierten Netzwerkcontroller gestartet werden:

doas bhyve \
-c sockets=1,cores=1,threads=1 \
-m 2G \
-l bootrom,/usr/local/share/uefi-firmware/BHYVE_BHF_UEFI.fd,fwcfg=qemu \
-s 0,hostbridge \
-s 20,virtio-net,vmnet0 \
-s 31,lpc \
-A -H -P \
samplevm

Innerhalb des Gastbetriebssystems kann die Kommunikation in das externe Netzwerk mit ping-Anfragen überprüft werden:

ping beckhoff.com
PING beckhoff.com (18.195.44.45) from 192.168.1.2 : 56(84) bytes of data.
64 bytes from ec2-18-195-44-45.eu-central-1.compute.amazonaws.com (18.195.44.45): icmp_seq=1 ttl=245 time=7.44 ms
64 bytes from ec2-18-195-44-45.eu-central-1.compute.amazonaws.com (18.195.44.45): icmp_seq=2 ttl=245 time=7.27 ms
64 bytes from ec2-18-195-44-45.eu-central-1.compute.amazonaws.com (18.195.44.45): icmp_seq=3 ttl=245 time=7.36 ms
^C

Dabei ist zu beachten, dass der virtuellen Netzwerkschnittstelle im Gastbetriebssystem eine Netzwerkadresse im Bereich des vmnet0 Netzwerks (192.168.1.0/24 siehe oben) zugewiesen wird. Außerdem muss die vmnet0 Adresse (192.168.1.1) als Default-Gateway eingetragen werden, sowie Adressen von Name-Servern hinterlegt werden, um öffentliche Domainnamen wie beckhoff.com aufzulösen.