Netwerk unter bhyve

bsd4me

Well-Known Member
Hallo,

ich habe gerade eine VM (Ubuntu 16.04) unter bhyve zum Laufen gebracht. Das, was mir zu Zeit noch fehlt ist der Netzwerkanschluss (tap0). Auf dem Host ist da:

host# ifconfig
re0: flags=8943<UP,BROADCAST,RUNNING,PROMISC,SIMPLEX,MULTICAST> metric 0 mtu 1500
options=82099<RXCSUM,VLAN_MTU,VLAN_HWTAGGING,VLAN_HWCSUM,WOL_MAGIC,LINKSTATE>
ether yy:yy:yy:yy:yy:yy
inet xxx.xxx.xxx.xxx netmask 0xffffffc0 broadcast xxx.xxx.xxx.255
nd6 options=29<PERFORMNUD,IFDISABLED,AUTO_LINKLOCAL>
media: Ethernet autoselect (1000baseT <full-duplex>)
status: active
...
bridge0: flags=8843<UP,BROADCAST,RUNNING,SIMPLEX,MULTICAST> metric 0 mtu 1500
ether 02:45:1b:b6:8e:00
nd6 options=9<PERFORMNUD,IFDISABLED>
id 00:00:00:00:00:00 priority 32768 hellotime 2 fwddelay 15
maxage 20 holdcnt 6 proto rstp maxaddr 2000 timeout 1200
root id 00:00:00:00:00:00 priority 32768 ifcost 0 port 0
member: tap0 flags=143<LEARNING,DISCOVER,AUTOEDGE,AUTOPTP>
ifmaxaddr 0 port 5 priority 128 path cost 2000000
member: re0 flags=143<LEARNING,DISCOVER,AUTOEDGE,AUTOPTP>
ifmaxaddr 0 port 1 priority 128 path cost 55
tap0: flags=8943<UP,BROADCAST,RUNNING,PROMISC,SIMPLEX,MULTICAST> metric 0 mtu 1500
options=80000<LINKSTATE>
ether 00:bd:b0:14:00:00
inet 192.168.2.1 netmask 0xffffff00 broadcast 192.168.2.255
nd6 options=29<PERFORMNUD,IFDISABLED,AUTO_LINKLOCAL>
media: Ethernet autoselect
status: active
Opened by PID 6791


in Ubuntu sehe ich:

vm# ifconfig
enp0s2 Link encap:Ethernet HWaddr 00:a0:98:ce:16:5c
inet addr:192.168.2.1 Bcast:192.168.2.255 Mask:255.255.255.0
inet6 addr: fe80::2a0:98ff:fece:165c/64 Scope:Link
UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1
RX packets:956 errors:0 dropped:0 overruns:0 frame:0
TX packets:256 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:1000
RX bytes:129187 (129.1 KB) TX bytes:18201 (18.2 KB)


auf dem Host komme ich nicht zur vm (der sshd läuft!)

host# ssh 192.168.2.1
ssh: connect to host 192.168.2.1 port 22: Connection refused


kann aber folgendes:

host# ping 192.168.2.1
PING 192.168.2.1 (192.168.2.1): 56 data bytes
64 bytes from 192.168.2.1: icmp_seq=0 ttl=64 time=0.038 ms
64 bytes from 192.168.2.1: icmp_seq=1 ttl=64 time=0.038 ms

von Ubuntu komme ich nicht raus:

vm# ping www.freebsd.org
^C


ich habe eine /etc/pf.conf - und das klappt mit port-forewarding und Jails hervorragend. Hat jemand eine Idee, wo ich was einstellen sollte? Das wäre super.

Ach, vielelicht eine kurze Anmerkung: Allein dieser dumme systemd hat mich 1 Tag Arbeit gekostet, befor ich herausgefunden habe, dass das virtio-net device nicht per eth0, sondern per enp0s2 einzubinden ist... Ubuntu wird mir immer sonderbarer... Schon wieder ein Automatismus mehr...

Aber zum eigentlichen: Danke für Tipps! :) Norbert
 
Hallo Norbert,

hast Du ansonsten alle Netzwerk-Schritte nach Handbuch gemacht? https://www.freebsd.org/doc/handbook/virtualization-host-bhyve.html
(ganz unten auf der Seite steht, wie man die Einstellungen persistent machen kann mit Eintragen in /etc/sysctl.conf, /boot/loader.conf und und /etc/rc.conf)

Ansonsten poste doch einmal wie Deine pf.conf aussieht.

Bei mir hat es geholfen, tap0 und bridge0 von den PF-Filterregeln auszunehmen - Forwarding und ähnliches brauchst Du in diesem Fall gar nicht:
Code:
set skip on lo0
set skip on bridge0
 
Danke für die Antwort - wie gesagt, mit Jails funktioniert es super...

Aber ich sende trotzdem mal meine Konfigutaionsdateien:


# more /boot/loader.conf
opensolaris_load="YES"
vfs.root.mountfrom="zfs:zroot"
zfs_load="YES"
vfs.zfs.arc_max="2G"
sem_load="YES"
linux_load="YES"
nvidia_load="YES"
accf_http_load="YES"
# bhyve
if_bridge_load="YES"
if_tap_load="YES"
nmdm_load="YES"
vmm_load="YES"



# more /etc/rc.conf
ifconfig_re0="DHCP"
zfs_enable="YES"
keymap="german.cp850.kbd"
sshd_enable="YES"
ntpd_enable="YES"
sendmail_enable="NONE"
linux_enable="YES"
rpcbind_enable="YES"
devfs_system_ruleset="devfsrules_common"
hald_enable="YES"
dbus_enable="YES"
# Jails
ifconfig_tap0="inet 192.168.2.1/24"
ifconfig_bridge0="addm re0 addm tap0"
cloned_interfaces="lo1 bridge0 tap0"
gateway_enable="YES"
ipv4_addrs_lo1="192.168.1.1-9"
pf_enable="YES"
pf_rules="/etc/pf.conf"
pflog_enable="YES"
# Printing
cupsd_enable="YES"



Für die jails habe ich pf.conf so konfiguriert, dass unterscheidliche jails per port zugreifbar sind

# more /etc/pf.conf

PUB_IF="re0"
PUB_IP="xxx.xxx.xxx.xxx"
JAIL_NET="192.168.1.0/24"

WORK_IP="192.168.1.xxx"
WORK_PORTS="{xxxx}"

...

scrub in all
nat pass on $PUB_IF from $JAIL_NET to any -> $PUB_IP
rdr pass on $PUB_IF proto tcp from any to $PUB_IP port $WORK_PORTS -> $WORK_IP
...



Hilft Dir das?

VG Norbert
 
Ach, vielelicht eine kurze Anmerkung: Allein dieser dumme systemd hat mich 1 Tag Arbeit gekostet, befor ich herausgefunden habe, dass das virtio-net device nicht per eth0, sondern per enp0s2 einzubinden ist... Ubuntu wird mir immer sonderbarer... Schon wieder ein Automatismus mehr...
Wow, der Change ist doch bereits uralt - und imo auch sehr wichtig. Richtige Unix-Systeme, unter anderem doch auch FreeBSD machen das doch schon ewig so oder so ähnlich. Das Problem dabei ist, dass es nicht vorhersehbar ist, in welcher Reihenfolge die Hardware von Treibern initialisiert wird, dadurch kann es hier durchaus dazu kommen, dass ein Interface Assignment sich über Reboots ändert. Das kann verheerende Folgen haben. Der Workaround war hier immer über udev den Namen an die MAC-Adresse zu pinnen. Die Lösung, die systemd hier eingeführt hat entspricht dem Schema, das ein Solaris z.B. seit Urzeiten fährt. Es entspricht der Platzierung auf dem Bus und ist immer Vorhersehbar. Von daher sehe ich das eigentlich als große Verbesserung.
 
Danke für die Kommentare :) und auch an @MuffiXXL... Solaris 11 ist mir noch gut bekannt - und auch der Umstand, dass "generisch" Zuweisungen zu devices erfolgen...

So, zum eigentlichen Problem: ich habe PF komplett herausgenommen - ich bekomme es aber trotzdem nach einem Neutart nicht hin, von der VM nach draussen zu kommen. Leider stecke ich in der Netzwerkgeschichte nicht soooo tief drin. Was habe ich konfiguriert:

#host> more /etc/rc.conf
...
ifconfig_bridge0="inet 192.168.2.254/24 addm re0 addm tap0"
cloned_interfaces="lo1 bridge0 tap0"
gateway_enable="YES"
...


#host> ifconfig
...
bridge0: flags=8843<UP,BROADCAST,RUNNING,SIMPLEX,MULTICAST> metric 0 mtu 1500
ether 02:45:1b:b6:8e:00
inet 192.168.2.254 netmask 0xffffff00 broadcast 192.168.2.255
nd6 options=9<PERFORMNUD,IFDISABLED>
id 00:00:00:00:00:00 priority 32768 hellotime 2 fwddelay 15
maxage 20 holdcnt 6 proto rstp maxaddr 2000 timeout 1200
root id 00:00:00:00:00:00 priority 32768 ifcost 0 port 0
member: tap0 flags=143<LEARNING,DISCOVER,AUTOEDGE,AUTOPTP>
ifmaxaddr 0 port 5 priority 128 path cost 2000000
member: re0 flags=143<LEARNING,DISCOVER,AUTOEDGE,AUTOPTP>
ifmaxaddr 0 port 1 priority 128 path cost 55
tap0: flags=8943<UP,BROADCAST,RUNNING,PROMISC,SIMPLEX,MULTICAST> metric 0 mtu 1500
options=80000<LINKSTATE>
ether 00:bd:3b:16:00:00
nd6 options=29<PERFORMNUD,IFDISABLED,AUTO_LINKLOCAL>
media: Ethernet autoselect
status: active
Opened by PID 2292


#vm> ifconfig
enp0s2 Link encap:Ethernet HWaddr 00:a0:98:ce:16:5c
inet addr:192.168.2.1 Bcast:192.168.2.255 Mask:255.255.255.0
inet6 addr: fe80::2a0:98ff:fece:165c/64 Scope:Link
UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1
RX packets:4004 errors:0 dropped:1324 overruns:0 frame:0
TX packets:701 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:1000
RX bytes:386541 (386.5 KB) TX bytes:56147 (56.1 KB)


#vm> more /etc/network/interfaces
auto enp0s2
iface enp0s2 inet static
address 192.168.2.1
netmask 255.255.255.0
network 192.168.2.0
broadcast 192.168.2.255
gateway 192.168.2.254
dns-nameservers xxx.xxx.xxx.xxx
dns-search domain.de


trotzdem bleibt:

#vm> ping www.freebsd.org
ping: unknown host www.freebsd.org


allerdings funktioniert

#vm> ping xxx.xxx.32.19
PING xxx.xxx.32.19 (128.176.32.19) 56(84) bytes of data.
64 bytes from xxx.xxx.32.19: icmp_seq=1 ttl=64 time=0.060 ms


wobei xxx.xxx.32.19 die IP des öffentlich Ethernet devices auf dem host ist..

#vm> route
Kernel IP routing table
Destination Gateway Genmask Flags Metric Ref Use Iface
default 192.168.2.254 0.0.0.0 UG 0 0 0 enp0s2
192.168.2.0 * 255.255.255.0 U 0 0 0 enp0s2


Danke für Tipps :) Norbert
 
Also, generell sieht es erst einmal gut aus. Du hast eine Bridge auf dem Host, darin ist das tap-Device. Sowohl die Bridge als auch das tab-Device sind 'up', der Gast hat Netz und erreicht den Host. Er kommt allerdings nicht über den Host hinaus. Lass mich also mal etwas ins Blaue schießen:
  • Deine Host-Netzwerkkarte re0 ist 'up' und hat keine IP, oder? Jede andere Konfiguration muss Ärger machen, da eine IP auf der Bridge liegt.
  • Ich hatte es schon mehrmals, dass die zufällige MAC-Adresse der Bridge gar nicht so zufällig ist und verschiedene Maschinen die gleiche MAC nutzen. Das ist dann eine MAC-Kollision mit genau solchen Symptomen. Ich dübele die MAC-Adressen daher inzwischen statisch auf die Bridges. Ist auch in Sachen IPv6 hilfreich.
  • Auf der Bridge liegt ein Spanning Tree. Der sollte harmlos sein, ich sehe zumindest nun keine Schleife. Trotzdem würde ich auf die Switches schauen, was die so denken.
 
Nein, denn sonst ist deine Maschine mit zwei Beinen im gleichen Netz. Das kann nicht funktionierten, da zwei MAC-Adressen auf jedes ARP-Request antworten. Also entweder die Adresse von re0 oder bridge0 runter. Ich würde die von re0 herunternehmen, weil dabei der IP auf der Bridge der "Verschluckfaktor" bei Änderungen an der Topologie (z.B. Einfügen weiterer Member in die Bridge) kleiner ist.
 
Danke - aber ich lass die IP vom re0 aktiv - einfach aus dem grunde, da das DIE Addresse ist, die per DHCP vergeben wird... Trotzdem bekomme ich keine Verbindung von der vm ins Internet - auch wenn ich bei bridge0 die IP wegnehme...
 
vielleicht sollte ich sagen, dass host udn vm in ganz unterscheidlichen netzen liegen, die ips also 128.xxx.yyy.zzz und 192.168.2.1 sind...
 
Das ist okay so. Du gibst der Bridge einfach eine IP Adresse aus dem VM Bereich und richtest ein NAT mit pf ein.
 
Moment, wenn das unterschiedliche Subnetze sind, stelle ich instinktiv die Frage nach der Rückroute. Also der Host ist z.B. 128.0.0.1 und es gibt eine zweite Maschine A mit 128.0.0.2 Die VM auf 192.168.2.1 kann natürlich den Host pingen, denn er weiß ja wo er 192.168.2.1 findet. Aber weiß Maschine A mit 128.0.0.2 es auch? Weiß er es nicht, landet die Antwort nämlich auf dem Defaultrouter und der wird sie verwerfen, sofern er keine Route auf 192.168.2.1 hat... Ich hoffe, das war halbwegs verständlich.
 
mhhmm... das ist halbwegs verständlich :) Es ist komplizerter als ich dachte, mit jails und pf und Regeln, die Ports weitergereicht haben war das überhaupt kein Problem... Sowas müsste doch auch hier funktionieren.

Sorry für die vielen Fragen, da ich aber nahezu alles (Entwicklung, Server, Web, Datenbanken etc.) hier am Lehrstuhl mache, sind halt einige Bereiche nur rudimentär abgedeckt...

Wär so schön, wenn das mal klappen könnte, dann bräuchte ich VirtualBox nicht nutzen, sondern könnte auf das schlankere bhyve umschalten. Und testen, insbesondere was Performance angeht. Das würde evtl. dem Entwicklerteam von bhyve wieder freuen - hoffe ich :) Das wären dann auch mal dickere Anwendungen aus der Bioinformatik, mit vielen GB RAM, grossen Datenmengen und viel CPU Leistung...
 
Mit NAT geht es. Ich habe dafür sogar ein fertiges Setup. Allerdings auf Basis von IPFW, das sollte sich aber übersetzen lassen:

Als erstes brauchst du eine Bridge, die später die Interfaces der einzelnen VMs aufnimmt. Die Bridge darf nicht mit dem umgebenden Netzwerk verbunden sein, da es sonst Probleme mit dem NAT gibt. Also in der rc.conf etwa so:

Code:
hostname="mein_host"
defaultrouter="192.168.X.Y"
gateway_enable="YES"

ifconfig_re0="inet 192.168.X.Y/24 up"

cloned_interfaces="bridge0"
ifconfig_bridge0="inet 10.5.0.1/24 up"

10.5.0.0/24 wird das Netz, aus dem VMs ihre Adressen bekommen. Da kann man natürlich jedes andere, private Netz nehmen. Dann ein NAT um bridge0 bauen:

Code:
# Das Kommando
cmd="/sbin/ipfw -q"

# Unsere Netzwerkkarte
lan_if="re0"

# Unsere externe IP-Adresse
ipaddr="192.168.X.Y/24"

# Das VM-Netzwerk
vm_net="10.5.0.0/24"

# -------------------------------------------------------- #

# Alles rauswerfen
$cmd flush
$cmd queue flush
$cmd pipe flush

# -------------------------------------------------------- #

# Alles was einen State hat darf durch
$cmd add 10 check-state

# Vom Host auf die VMs
$cmd add 20 allow all from me to $vm_net setup keep-state

# -------------------------------------------------------- #

# NAT
$cmd nat 1 config if $lan_if

$cmd add 50 nat 1 all from $vm_net to not $vm_net
$cmd add 60 nat 1 all from any to $ipaddr

# -------------------------------------------------------- #

# Alles durchlassen
$cmd add 70 allow all from any to any

Und das in der rc.conf verdrahten:

Code:
# IPFW fuer NAT
# -------------
firewall_enable="YES"
firewall_script="/etc/ipfw.conf"
firewall_nat_enable="YES"

Wenn du nun eine VM anlegst, wird das zugehörige tap-Device in die bridge0 eingefügt. Die VM bekommt dann eine Adresse aus dem 10.5.0.0/24 Netz und die auf bridge0 liegende Adresse (10.5.0.1) als Default Router eingetragen. Das war's. Wirklich cool wird es, wenn man noch dnsmasq für DHCP und DNS ggü. den VMs mit ins Spiel bringt. Dann kann sich die VM ihre IP per DHCP ziehen und man kann vom Host ein "ssh $hostname_der_vm" machen, um auf sie zu verbinden. Dazu erstmal 'pkg install dnsmasq' und dann in die '/usr/local/etc/dnsmasq.conf':

Code:
# DNS-Anfragen brauchen eine Domain
domain-needed

# Provate Netzwerke nicht nach außen leaken
bogus-priv

# Spezielle resolv.conf
resolv-file=/etc/dnsmasq-resolv.conf

# Config für den resolvconf Generator
conf-file=/etc/dnsmasq-conf.conf

# Wir lauschen auf bridge0
interface=bridge0

# Der DHCP-Pool
dhcp-range=10.5.0.10,10.5.0.250,12h

# Wenn kein FQDN gegeben, hänge das Postfix an
expand-hosts

# Und das anzuhängende Postfix
domain=bhyve.local

Die Runtime-Config touchen:

Code:
% touch /etc/dnsmasq-resolv.conf
% touch /etc/dnsmasq-conf.conf

Unseren Host in der /etc/hosts auf dem Host angeben, damit die VMs sich mit "ssh host" auf den Host verbinden können:

Code:
10.5.0.1  host

rc.conf Eintrag:

Code:
# DNSMasq fuer VMs
# ----------------
dnsmasq_enable="YES"

Jetzt 'service dnsmasq start' und anschließend in die /etc/resolv.conf des Hosts:

Code:
nameserver 127.0.0.1

Von nun an brauchst du nur noch das tab-Device einer neuen VM in bridge0 einfügen und schon konfiguriert sich die VM per DHCP selbst.
 
so - jetzt geht es - aber doch ein klein wenig anders als Ihr beschrieben habt...

in der /etc/rc.conf habe ich folgendes eingetragen:

ifconfig_bridge0="inet 192.168.2.254/24 up"
cloned_interfaces="lo1 bridge0"
gateway_enable="YES"
pf_enable="YES"
pf_rules="/etc/pf.conf"
pflog_enable="YES"


bei /etc/pf.conf:

PUB_IF="re0"
PUB_IP="xxx.xxx.xxx.xxx"
BHYVE_NET="192.168.2.0/24"
UBUNTU_IP="192.168.2.1"
UBUNTU_PORTS="{xxxx}"
set skip on tap0
rdr pass on $PUB_IF proto tcp from any to $PUB_IP port $UBUNTU_PORTS -> $UBUNTU_IP
nat pass on $PUB_IF from $BHYVE_NET to any -> $PUB_IP


und in der ubuntu vm /etc/networks/interfaces:

auto enp0s2
iface enp0s2 inet static
address 192.168.2.1
netmask 255.255.255.0
network 192.168.2.0
broadcast 192.168.2.255
gateway 192.168.2.254
dns-nameservers yyy.yyy.yyy.yyy
dns-search domain.de


Ach, das tap device musste ich manuell an die bridge hängen...

Ich werde nochmals ein wenig an der Konfiguration experementieren, jetzt aber erstmal schauen, we performant sich bhyve zeigt :)

Norbert
 
Wenn du es dir noch ein bisschen einfacher machen möchtest, kannst du dir mal sysutils/vm-bhyve angucken, damit lässt sich das alles schön automatisieren.
 
danke :) Aber jetzt läuft es auch bei mir... sogar mit remote mounten - also erstmal alles, was ich für einen Server benötige...

Ich habe mal einen Performance Test gemacht... da gibt es für blast (biologisches Tool) einen benchmark. Ich habe einfach die Gesamt-Ausführungs-Zeit als Mass genommen. Habe das ganze (auf einem AMD PC) laufen lassen. Unter FreeBSD und in einer Ubuntu-bhyve-VM (auf dem gleichen Rechenr) lief es ähnlich schnell. Dann habe ich den benchmark auf einer Intel Maschine gemacht. es ging mir um einen Anhaltspunkt bzgl. Performance. Naja, da ist auch Platten-IO dabei. Aber ich bin erstaunt, bhyve performt sehr gut. Soweit ich sehen kann. Mit anderen Worten: es schreit danach, bald in Produktion genommen zu werden :)

VG Norbert
 
Zurück
Oben