Bare Metal Cloud – Part 3 – Several Public IPs – Macvtap vs. Bridging

In the previous post on the topic, I’ve had a look at how several virtual machines on my bare metal cloud server in a data center can share a single public IPv4 address. Public IPv4 addresses are expensive these days, so in many cases, sharing an IPv4 address and using non-standard ports for web servers and other things is hence quite acceptable. This is also how I run my main cloud server behind a DSL line with a single public IPv4 address. Nevertheless, for some applications, the use of standard TCP ports is a must.

As I have a lot of spare capacity on my cloud server, I’m thinking about migrating a number of services such as my BBB server, my Jitsi server, and several containerized web applications in virtual machines to VMs on the bare metal server. For these, I’d prefer to have individual public IPv4 addresses and no NAT in front of them. Turns out, this much easier to set-up than most configuration guides suggest.

A Word About Cost

Yes, public IPv4 addresses are expensive, and prices are likely to keep rising. Today, Hetzner, the data center operator from whom I rent my bare metal server, asks for 2 Euros per month for each additional pubic IPv4 address, plus a 20 Euros initial setup fee. The setup fee really stings. But anyway, for some of my applications that are running on more powerful and thus somewhat more expensive virtual machines in the data center today, it still makes sense to transfer them to virtual machines on the bare metal server.

Getting an Additional Public IPv4 Address

Getting an additional public IPv4 address via Hetzner’s management interface is easy, but setting up a virtual machine to use it seems to be rather complicated. The official documentation of how an additional public IPv4 can be used is rather complicated and left a lot of question marks. Others have written (in German) a somewhat easier to understand account of how to configure a bridged configuration and after some trial and error, I finally got it up and running. However, I wasn’t really happy with the solution, as it’s rather complicated.

Using the Additional Public IPv4 Address – The Hard or the Easy Way

KVM offers different kinds of network adapter emulations and the one I use at home to give each virtual machine an individual MAC address and (local) IP address is ‘macvtap’. I gave this method a try on my bare metal server as well, and the only extra thing I needed was a dedicated MAC address for this IPv4 address, which can be generated in Hetzner’s server configuration dashboard. This MAC address then has to be configured for the virtual machine’s macvtap Ethernet interface. This is very important, as just using any MAC address will not work. Also, Hetzner doesn’t like random MAC addresses very much in their system, and will immediately send an automated abuse eMail. So be a bit careful here. With this setup, no configuration is required at all on the host machine, and its trivial to configure the network in the virtual machine. Here’s an example of the netplan configuration in the virtual machine:

  version: 2
  renderer: networkd
        - on-link: true
      gateway6: fe80::1

The three things that need to be adapted inside the virtual machine is the Ethernet adapter name (e.g. enp1s0), the IP address, and the gateway in the via line. And that’s it! I’m a bit puzzled why Hetzner does not describe this setup, and instead goes for two options that are much more difficult to setup and maintain!?

Going Back and Forth Between Different Configurations

And one final note: Going back and forth between the different solutions is possible, as Hetzner’s management GUI allows to add and also to remove the MAC address for an additional public IPv4 address. I was a bit apprehensive about that, because that’s also not documented. But once a MAC address has been assigned, the same button in the management GUI removes it again.


So far so good, I now have two options to make services available running in virtual machines on my bare metal server: Most of my virtual machines share the primary public IPv4 address via NAT and port forwarding described in the previous post. And for those services that require their own public IPv4 address, I use a macvtap Ethernet interface with a dedicated MAC address attached to the additional public IPv4 address, as it’s the easiest way to set this up. Both NAT and additional public IPv4 VMs run just fine alongside, so I get the best of both worlds!