Configure a NAT server in Hetzner Cloud by enabling Private Networking, assigning private IPs to client VMs, and configuring Ubuntu’s iptables or nftables for masquerading. This setup allows instances without public IPs to route traffic through a designated gateway, ensuring secure and efficient internal communication within your cloud infrastructure.
Prerequisites and Network Architecture
Before deploying the NAT solution, you must understand how Hetzner Cloud handles networking. Unlike traditional on-premise setups where you might plug into a physical switch, Hetzner uses software-defined networking. The critical component here is the Private Net. Without it, your client VMs cannot communicate with each other privately, nor can they use a central node for NAT unless that node has a public IP. You need at least two servers: 1. The NAT Gateway: A server with a public IPv4 address. This will handle the translation of private addresses to its public IP. 2. Client VMs: Servers that do not require direct public internet access. These will rely on the NAT Gateway for outbound connectivity. It is essential to ensure that all participating VMs are located in the same datacenter. Private Networking is only available within specific datacenters and cannot span across regions. If your clients are in different locations, you would need a VPN solution instead, as discussed in Using WireGuard to Establish a Tunnel Between NATted Clients and a Middleman.Step 1: Enable Private Networking in Hetzner Console
The most common mistake users make is attempting to configure routing before enabling the underlying network interface. You cannot assign private IPs if Private Net is disabled. 1. Log in to the Hetzner Robot or Hetzner Console. 2. Navigate to the Networks section. 3. Click Add Network. 4. Select the datacenter where your VMs reside. 5. Choose a subnet (e.g.,10.0.0.0/24). Ensure this subnet does not conflict with any other networks you may have.
6. Attach the newly created network to both your NAT Gateway and your Client VMs.
Once attached, the network appears in the console, but the operating systems inside the VMs do not yet know about it. You must now configure the OS level.
Step 2: Configure Network Interfaces on Ubuntu
Ubuntu 22.04 and later usenetplan for network configuration. You need to modify the YAML configuration files to recognize the new private interface. Typically, the primary public interface is named eth0, while the private interface might be named eth1 or similar, depending on the order of attachment.
Check your current interfaces using ip addr. Look for an interface with a MAC address matching the one shown in the Hetzner Console under the Private Net details.
Edit the netplan configuration file, usually found in /etc/netplan/. Add the following configuration for the private interface. Note that you do not need to define a default gateway for the client VMs; they will receive their routing instructions from the NAT server.
network:
version: 2
ethernets:
eth0:
dhcp4: true
eth1:
dhcp4: false
addresses:
- 10.0.0.10/24
nameservers:
addresses:
- 8.8.8.8
- 1.1.1.1
Apply the changes with sudo netplan apply. Verify connectivity by pinging the NAT Gateway’s private IP from the client VM. For more details on managing these interfaces, refer to How do Ubuntu-server network interfaces work?.
Step 3: Configure IP Forwarding on the NAT Gateway
The NAT Gateway must be configured to forward traffic between its public and private interfaces. First, enable IP forwarding in the kernel. Edit/etc/sysctl.conf and uncomment or add the following line:
net.ipv4.ip_forward = 1
Apply the settings immediately with:
sudo sysctl -p
Verify that forwarding is active by checking the value:
cat /proc/sys/net/ipv4/ip_forward
It should return 1.
Step 4: Set Up Masquerading with iptables
Now you must configure the firewall to perform Network Address Translation. We will useiptables to masquerade traffic coming from the private subnet.
Add the POSTROUTING rule to replace the source IP of packets leaving the public interface:
sudo iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE
Here, eth0 is assumed to be the public interface. Adjust this if your public interface has a different name. To ensure these rules persist after a reboot, install iptables-persistent:
sudo apt install iptables-persistent
sudo netfilter-persistent save
Additionally, you must allow forwarding between the interfaces. By default, Ubuntu’s UFW or iptables policy may drop forwarded packets. Allow this explicitly:
sudo iptables -A FORWARD -i eth1 -o eth0 -j ACCEPT
sudo iptables -A FORWARD -i eth0 -o eth1 -m state --state RELATED,ESTABLISHED -j ACCEPT
Save these forwarding rules as well using netfilter-persistent save.
Step 5: Configure Client Routing
Your client VMs now have private IPs, but they do not know how to reach the internet. They need a default route pointing to the NAT Gateway’s private IP. On each client VM, set the default gateway to the NAT Gateway’s private IP address. If you usednetplan, update the client configuration:
network:
version: 2
ethernets:
eth0:
dhcp4: true
eth1:
dhcp4: false
addresses:
- 10.0.0.11/24
routes:
- to: default
via: 10.0.0.10
nameservers:
addresses:
- 8.8.8.8
In this example, 10.0.0.10 is the private IP of your NAT Gateway. Apply the config with sudo netplan apply.
Test the connection by pinging an external IP like 8.8.8.8. If successful, check if DNS works by running curl http://example.com.
Troubleshooting Common Issues
If connectivity fails, check the following: 1. Firewall Rules: Ensure no local firewall on the NAT Gateway is blocking incoming traffic on the private interface. While we allowed forwarding, explicit input policies might still block packets. 2. Hetzner Firewall Scope: Remember that the Hetzner Cloud Firewall applies to public interfaces. It does not inspect private network traffic. Do not try to manage private traffic security through the Hetzner Console firewall. 3. Routing Loops: Ensure your client VMs are not trying to route traffic back out through their own public interface if one exists. Disable public IPs on client VMs if they are strictly for internal NAT usage. For scenarios involving complex routing between multiple VMs, consider reading How to Configure a Traffic Route from VM1 through Host to VM2.Frequently Asked Questions
Can I use this NAT setup for inbound connections?
No, standard masquerading only supports outbound connections initiated from inside the private network. For inbound traffic, you must set up port forwarding (DNAT) rules in addition to masquerading. This requires modifying thePREROUTING chain in iptables to redirect specific ports to the internal private IP.