I ran into an interesting problem to solve. I have multiple VMs using KVM that do not require inbound IPv4 but do require at least IPv6 inbound (for CloudFlare) and it would be nice to have outbound IPv4.
I already have a bridge setup for IPv4 + IPv6 named
br0 but need a separate bridge just for NAT routing for special VMs that do not require public IPv4 addresses.
A second NIC needs to be added. This one will use the
- 123456789101112<interface type='bridge'><mac address='11:11:11:11:11:11'/><source bridge='br0'/><model type='virtio'/><address type='pci' domain='0x0000' bus='0x00' slot='0x03' function='0x0'/></interface><interface type='network'><mac address='22:22:22:22:22:22'/><source network='default'/><model type='virtio'/><address type='pci' domain='0x0000' bus='0x00' slot='0x07' function='0x0'/></interface>
Stop all VMs you modified and restart libvirtd.
systemctl restart libvirtd.service
Set the default network to auto start.
- 12virsh net-autostart defaultvirsh net-start default
By default the bridge IP is 192.168.122.1. This is the subnet we’ll use in the VMs.
- 123413: virbr0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group defaultlink/ether fe:54:00:9d:ef:df brd ff:ff:ff:ff:ff:ffinet 192.168.122.1/24 brd 192.168.122.255 scope global virbr0valid_lft forever preferred_lft forever
Forwarding must be allowed in iptables and sysctl. Remember that
br0is the original bridge I set up for public IPv4 + IPv6. The bridge that gets created by libvirt (
virbr0) is for the internal IPv4 network.
- 123iptables -t nat -A POSTROUTING -s 192.168.122.0/24 -o br0 -j MASQUERADEsysctl -w net.ipv4.ip_forward=1sysctl -w net.ipv6.conf.all.forwarding=1
Start the VMs back up.
Make sure you now have a new interface named
eth1. Edit the interfaces file in the VM:
- 12345auto eth1iface eth1 inet staticaddress 192.168.122.10netmask 255.255.255.0gateway 192.168.122.1
Reboot the VM and you should be good to go.