Set up TAP networking for QEMU on macOS host
I have been trying to set up internet access for an Ubuntu Server (yes, it has to be an Ubuntu Server, even though I would prefer something lightweight like Alpine) on a macOS host. As far as I understand, I need to use Tap/Tun networking.
What I have done so far:
-
Installed TunTap OSX, so I have a
/dev/tap0
device. -
Set up a
bridge1
network device using ifconfig -
Set the IP of the
bridge1
device to192.168.100.1/24
. -
Assigned IP
192.168.100.0
to tap0. -
Set up a DHCP server and packet forwarding as per this site
-
Made scripts to
addm
anddeletem
tap0
frombridge1
at startup and shutdown of the VM. (I have verified these are working).
Apparent problems
At this point, WireShark shows no traffic through tap0
, but all my loopback traffic seems to pass through bridge1
.
The Ubuntu Server guest still does not have any internet access. I cannot send any data from the host to the guest or vice versa (I've tried ssh
and a netcat listener/client pair).
Running ip link show
in the guest shows only 2 devices: lo0
and ens3
. When the Ubuntu Server boots, the latter is always DOWN until I run ip link set ens3 up
(which doesn't fix anything).
When I used to run this VM on VirtualBox (which seems to be broken on macOS now), networking worked perfectly using a virtual NAT. I converted the .vdi
image to .qcow2
, so everything in the quest OS is identical to how it was before.
Have I done anything wrong here? If so, what can I fix? And if not, what should my next steps be? I appreciate your consideration.
Data Dumps
bridge1
when the VM is running:
$ ifconfig bridge1
bridge1: flags=8863<UP,BROADCAST,SMART,RUNNING,SIMPLEX,MULTICAST> mtu 1500
options=3<RXCSUM,TXCSUM>
ether fa:ff:c2:96:c0:01
inet 192.168.100.1 netmask 0xffffff00 broadcast 192.168.100.255
Configuration:
id 0:0:0:0:0:0 priority 0 hellotime 0 fwddelay 0
maxage 0 holdcnt 0 proto stp maxaddr 100 timeout 1200
root id 0:0:0:0:0:0 priority 0 ifcost 0 port 0
ipfilter disabled flags 0x0
member: tap0 flags=3<LEARNING,DISCOVER>
ifmaxaddr 0 port 15 priority 0 path cost 0
Address cache:
52:54:0:12:34:56 Vlan1 tap0 992 flags=0<>
media: autoselect
status: active
bridge1
when the VM is not running:
$ ifconfig bridge1
bridge1: flags=8863<UP,BROADCAST,SMART,RUNNING,SIMPLEX,MULTICAST> mtu 1500
options=63<RXCSUM,TXCSUM,TSO4,TSO6>
ether fa:ff:c2:96:c0:01
inet 192.168.100.1 netmask 0xffffff00 broadcast 192.168.100.255
Configuration:
id 0:0:0:0:0:0 priority 0 hellotime 0 fwddelay 0
maxage 0 holdcnt 0 proto stp maxaddr 100 timeout 1200
root id 0:0:0:0:0:0 priority 0 ifcost 0 port 0
ipfilter disabled flags 0x0
Address cache:
media: <unknown type>
status: inactive
tap0
when the VM is not running:
$ ifconfig tap0
ifconfig: interface tap0 does not exist
tap0
when the VM is running:
$ ifconfig tap0
tap0: flags=8943<UP,BROADCAST,RUNNING,PROMISC,SIMPLEX,MULTICAST> mtu 1500
ether 7e:9b:23:d0:c2:97
media: autoselect
status: active
open (pid 2415)
My QEMU command:
sudo qemu-system-x86_64 \
-m 1024m \
-smp 1 \
-boot d \
-hda Server.qcow2 \
-net nic,model=virtio \
-net tap,id=mynet0,ifname=tap0,script=qemu-ifup.sh,downscript=qemu-ifdown.sh
If you want NAT-networking configured for your VMs automatically, you can just 1) share your Internet connection to the bridge interface in the System Preferences, and 2) add the tapN-interfaces of your VMs to the bridge. Easy!
See more details here - https://gist.github.com/andriytk/bd3def8c30cbd474490280436c779027.