Hosting a Virtual Machine With a Public IP (proxy_arp)

I run this website on a physical server that i rent. Recently I wanted to run on the same server a virtual machine, with a different OS, with a public IP address(I use KVM for that, as there’s nothing to really change on the physical server’s OS and performance-wise it’s more than OK). The way my server provider gives me the second IP is as a “failover IP”, meaning that they just route me an IP thru the one the server already has, just one IP a different class so you have to run it on a /32 mask.

The problem is that my provider’s routers accepts traffic from and to my server only using the physical MAC address that my server already has, so if I want o put the server interface in a bridge and just add the VM’s interface into that bridge and set the IP on the VM it will try to communicate with the provider’s routers with the virtual MAC, so no way this is going to work.

As previously written on the Facebook page the solution is to use proxy_arp, but there are some differences to the link I gave there.

So, for the VM we set a bridge. To do that we need to have bridge-utils package installed (yum install bridge-utils) and set-up the br0 bridge. There’s no need to set an IP address on the bridge as we only need to set a static route on it.

/etc/sysconfig/network-scripts/ifcfg-br0 would look like this:


Then we create the file /etc/sysconfig/network-scripts/route-br0 with the contents:

VM_IP dev br0

VM_IP is the actual ip the provider gave you.

To start the bridge we just need to type in the shell:

ifup br0

To check the static route is well set we type:

ip route show dev br0

Then we edit /etc/sysctl.conf and take care that net.ipv4.ip_forward is set to 1, and add a line:

net.ipv4.conf.br0.proxy_arp = 1

Then we make these settings active by running in shell the command:

 sysctl -p

The next step is to prepare the virtual network for libvirt. We create a file called net-br0.xml with the following contents

<network connections='1'>
  <forward mode='bridge'/>
  <bridge name='br0' />

Then we import this file and make the virtual network active and available on start up by running these shell commands:

virsh net-define net-br0.xml
virsh net-start br0
virsh net-autostart br0

The next step is to install the virtual machine, set it to use br0 virtual network and use the VM_IP with as netmask and your physical server’s IP address as gateway. I use the virt-manager utility to do that.