By the time I moved to the cloud (in my case Hetzner) I wanted to replicate my home lab setup I had before. This would include my own IP-Range because I want to create and delete VMs on my Proxmox installation on a regular basis. Since a hosting provider would only supply one external IP address and I want to host multiple services on it, I want to setup a NAT.
What is NAT?
Typically you get only one IP-Address assigned by your provider even though you have multiple devices which need an IP-Address to browse the internet. Therefor your router implements NAT which stands for network address translation.
To implement NAT the router has to keep track which device requested content. Then the router itself requests the content from the world wide web. When the content arrives at your router it does a lookup where he has to route the data. If PC1 requests google.com, it sends it’s request to the router because google.com translates to an IP-Address outside it’s own network. The Router creates an entry in it’s NAT-Table and also changes the source address to it’s own (public) address. This has to be done because google.com has to know where the request came from. Since the IP-Address of PC1 is not public, google.com would not be able to send the response back. As soon as the response of the requested website arrives at the router, the package gets retransmitted to PC1.
Whats the goal?
This is also what I want to replicate with my proxmox setup in the cloud. I only have one public IP-Address but multiple VM which need unique IP-Addresses. It would be possible to request additional public IP-Addresses but this would not only cost more money, but also is a lot less dynamic. Every time I create a new VM I would have to request a new one from the provider. Inside my own sub network I can host a DHCP Server which would assign IP-Addresses automatically.
Setup
All the configuration is done inside /etc/network/interfaces
. Here is an example configuration. (I had to upload it with the file ending “.txt”. If you opt to use this as a basis please remove the ending)
Let’s talk about each block separately.
source /etc/network/interfaces.d/* | This is kind of an include statement for other interface configuration files. This folder however is in my case empty. |
auto lo | These lines of code define an internal loopback interface which is used for inter-process networking. We define one for IPv4 and one for IPv6. |
auto enp0s31f6 address <public_ip> <gateway>
| This is the actual definition of your hardware network interface. enp0s31f6 is my network interface name. Yours is very likely different. If you are wondering what yours is called, check your own interfaces file.Also this entry is used to specify the external IP Address and additional network configurations. The gateway is typically pretty much the same as your public ip address. The netmask typically contains a lot of 255. |
auto vmbr0 up ip link set vmbr0 txqueuelen 10000 post-up echo 1 > /proc/sys/net/ipv4/conf/vmbr0/proxy_arp post-up iptables -t nat -A POSTROUTING -o enp0s31f6 -j MASQUERADE --source '10.55.0.0/16' | vmbr0 is the interface we want to configure for our VMs. Therefor we need to add some rules how the traffic should be managed and which IP-Addresses are valid. Line three is where it gets interesting. The configured address tells the interface which IP-Address it is assigned. This is typically an IP-Address ending with “.1” because it’s the gateway for the hole 10.55.0.0 network (you can also change this to your liking). post-up and post-down is used to execute commands at interface startup or shutdown. As soon as the interface starts we want to enable ip forwarding and proxy arp requests. This is done by writing a 1 into the corresponding file. Also we want to use IP-Tables to configure the forwarding. This happens in the last four lines. If you changed the naming of your upstream interface you also need to change it here. If you decide to use a different network this also has to be changed here. |
post-up iptables -t nat -A PREROUTING -i vmbr0 -p tcp --dport 80 -j DNAT --destination <public_ip> --to-destination 10.55.0.66:80 post-up iptables -t nat -A PREROUTING -i enp0s31f6 -p tcp --dport 80 -j DNAT --to-destination 10.55.0.66:80 | Last but not least I want to mention how port forwarding works with this setup. If you want to expose a port of a virtual machine you will have to create those four entries. The first two create a port forwarding of port 80 to the host with the IP-Address 10.55.0.66. The second two are pretty much the same but enables a vm behind the NAT to reach the public IP Address. |
As soon as your configuration file is done you should do a restart. There are other possibilities like the ifup
command but I encountered some problems with my VMs. Every time you add a new VM please make sure you only use the vmbr0
interface. Also because there is no DHCP-Server included with this configuration you have to assign IP-Addresses manually. During the configuration you will also be asked to input the gateway and DNS-Server. The gateway is in case of the example 10.55.0.1. If you don’t host your own DNS-Server inside this network, you can use the common DNS-Servers like 1.1.1.1 or 4.4.4.4 or 8.8.8.8.
If you are interested in a setup with IPv6 please check out this article.
I hope you could follow the steps to adjust the example to your needs. Signing off.