Reputation: 1197
Host: Ubuntu 22.04, kernel 5.19.0, physical interface name enp5s0
QEMU: 6.2.0
Manually implement a NAT network for VMs spawned by QEMU.
Subnet for VMs is 10.8.20.0/24
, VMs can ping host via 10.8.20.2
, host can ping each VM. VM can access internet. All VMs interfaces are in a bridge nat-bridge
in namespace nat-ns
.
# Create namespace which is used by all VMs
ip netns add nat-ns
# Create bridge which is used by all VMs
ip netns exec nat-ns ip link add nat-bridge type bridge
ip netns exec nat-ns ip link set dev nat-bridge up
# This veth pair is used for control internet connection.
# `wwwa` side for internet, `wwwb` side for inner subnet
ip link add nat-wwwa type veth peer nat-wwwb
ip addr add 10.8.20.1/24 dev nat-wwwa
ip link set dev nat-wwwa up
ip link set nat-wwwb netns nat-ns
ip netns exec nat-ns ip link set dev nat-wwwb up
ip netns exec nat-ns ip link set nat-wwwb master nat-bridge
# This veth pair is used for host-guest communications
# `hosta` side for communicate, `hostb` side is plugged into bridge
ip netns exec nat-ns ip link add nat-hosta type veth peer nat-hostb
ip netns exec nat-ns ip link set nat-hostb master nat-bridge
ip netns exec nat-ns ip addr add 10.8.20.2/24 broadcast 10.8.20.255 dev nat-hosta
ip netns exec nat-ns ip link set dev nat-hosta up
ip netns exec nat-ns ip link set dev nat-hostb up
# Add default route to go through nat-wwwa
ip netns exec nat-ns ip route add default via 10.8.20.1
# Setup NAT for subnet 10.8.20.0/24
iptables -t nat -A POSTROUTING -s 10.8.20.0/24 -o enp5s0 -j MASQUERADE
iptables -A FORWARD -i enp5s0 -o nat-wwwa -j ACCEPT
iptables -A FORWARD -o enp5s0 -i nat-wwwa -j ACCEPT
# Create TAP interface for VM to use
ip netns exec nat-ns ip tun tap add nat-vm-tap mode tap
ip netns exec nat-ns ip link set nat-vm-tap master nat-bridge
ip netns exec nat-ns ip link set dev nat-vm-tap up
When using QEMU, I passed the following options to use tap:
-netdev tap,id=tap0,ifname=nat-vm-tap,script=no,downscript=no -device virtio-net,netdev=tap0
Inside guest, I claim the interface's ip with 10.8.20.5
After above settings, now I have:
nat-ns
, which all VM interfaces are in itnat-bridge
, which all VM interfaces are in it10.8.20.2
10.8.20.5
10.8.20.1
Host can ping guest, guest can ping host, host can ping internet with nat-hosta
interface, guest cannot ping internet. This is the problem.
First, I don't want to change any settings for my physical network interface, i.e. enp5s0
, so I don't make it belong to my newly created bridge.
I don't use Libvirt for some other reasons, so I just manually implement such things for basic QEMU/KVM.
I want to control whether my VM can access Internet or not, by just attaching/detaching the veth pair nat-wwwa
/nat-wwwb
to nat-bridge
.
Upvotes: 0
Views: 868
Reputation: 1
My recommendation would be to check the DNS settings /etc/resolv.conf
on the guest VM to make sure it has a valid DNS server IP address.
Another way would be to temporarily disable firewall rules blocking outgoing internet traffic from the guest VM or allow outgoing connections
Upvotes: 0