KVM Bridge and NAT
Aug 15, 2016

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.

  1. A second NIC needs to be added. This one will use the default network.

    • ```
1. Stop all VMs you modified and restart libvirtd.

   - `systemctl restart libvirtd.service`

1. Set the default network to auto start.

   - ```
virsh net-autostart default
virsh net-start default
  • By default the bridge IP is 192.168.122.1. This is the subnet we’ll use in the VMs.

    • 13: virbr0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default
       link/ether fe:54:00:9d:ef:df brd ff:ff:ff:ff:ff:ff
       inet 192.168.122.1/24 brd 192.168.122.255 scope global virbr0
        valid_lft forever preferred_lft forever
      
  1. Forwarding must be allowed in iptables and sysctl. Remember that br0 is the original bridge I set up for public IPv4 + IPv6. The bridge that gets created by libvirt (virbr0) is for the internal IPv4 network.

    • iptables -t nat -A POSTROUTING -s 192.168.122.0/24 -o br0 -j MASQUERADE
      sysctl -w net.ipv4.ip_forward=1
      sysctl -w net.ipv6.conf.all.forwarding=1
      
  2. Start the VMs back up.

  3. Make sure you now have a new interface named eth1. Edit the interfaces file in the VM:

    • auto eth1
      iface eth1 inet static
       address 192.168.122.10
       netmask 255.255.255.0
       gateway 192.168.122.1
      
  4. Reboot the VM and you should be good to go.

Comments