Skip to content

Hetzner networking

Hetzner needs host-side network configuration before instances can use extra IPs or subnets. Use Bridge when you buy additional single IPs. Use Routed when you buy a subnet and choose your server’s main IP as its gateway.

These apply to every example below. The values come from Hetzner’s official network documentation.

  • Bridge name: br0. Do not name your bridge virbr0; libvirt reserves that name for its default NAT network and the two collide.
  • Bridge MAC must match the physical NIC’s MAC. Hetzner switch ports have strict IP/MAC binding. A bridge with a random MAC is silently filtered by the upstream switch. On Debian, the bridge_hw directive does this and has been required since Debian 11; hwaddress ether <MAC> is an equivalent alternative.
  • IPv4: the additional or main IP is configured with a /32 netmask plus an on-link route to the gateway. Hetzner’s gateway sits outside your /32, so the on-link flag tells Linux the gateway is still directly reachable.
  • IPv6 gateway: fe80::1 (link-local).
  • IPv6 routing: Hetzner routes the whole /64 to a single MAC. Either leave it on the host’s own MAC, or route the subnet to the virtual MAC of one additional IP in Robot; instances then take addresses from that /64 with gateway fe80::1.
  • Hetzner DNS: 185.12.64.1, 185.12.64.2 (IPv4) and 2a01:4ff:ff00::add:1, 2a01:4ff:ff00::add:2 (IPv6).
  • Interface names in the examples (enp0s31f6) are examples. Find your real one with ip route | grep default and substitute it everywhere.
  • Virtual MACs. When you assign an additional single IP to an instance, generate a virtual MAC for that IP in the Robot console and assign it to the instance NIC. Without it Hetzner filters guest traffic.

Replace the addresses, gateway and MAC below with your own. The examples use documentation values (203.0.113.236, gateway 203.0.113.193, 2001:db8:10:1526::2, MAC 02:00:00:12:34:56).

Edit /etc/network/interfaces:

/etc/network/interfaces
### Hetzner Online GmbH installimage
source /etc/network/interfaces.d/*
auto lo
iface lo inet loopback
iface lo inet6 loopback
# Physical interface - no IP, no auto-bring-up of its own
auto enp0s31f6
iface enp0s31f6 inet manual
# Bridge - carries the physical NIC's MAC
auto br0
iface br0 inet static
address 203.0.113.236
netmask 255.255.255.255
gateway 203.0.113.193
pointopoint 203.0.113.193
bridge_hw enp0s31f6
bridge_ports enp0s31f6
bridge_stp off
bridge_fd 1
bridge_hello 2
bridge_maxage 12
dns-nameservers 185.12.64.1 185.12.64.2
iface br0 inet6 static
address 2001:db8:10:1526::2/64
gateway fe80::1

bridge_hw sets the bridge’s MAC to the physical NIC’s MAC; it is the directive Hetzner’s own documentation uses. hwaddress ether <MAC> does the same job and also works. The pointopoint directive does the same job as netplan’s on-link: true: it tells Debian the gateway is directly reachable even though it sits outside the /32.

Reboot the server to confirm the configuration survives a restart.

Instances also need static configuration; they do not use DHCP. The instance NIC must use the virtual MAC generated in Robot for that IP, and its gateway is the gateway of the host’s main IP, not a gateway of its own. The example below uses the documentation value 203.0.113.50 for the additional IP.

network:
version: 2
ethernets:
eth0:
dhcp4: no
addresses:
- 203.0.113.50/32
routes:
- to: default
via: 203.0.113.193
on-link: true
nameservers:
addresses: [185.12.64.1, 185.12.64.2]

VirtConsole applies this automatically through cloud-init when you set up the subnet as Bridge mode: enter the main IP’s gateway as the subnet gateway and 255.255.255.255 as the netmask, then attach the additional IP with its virtual MAC to the instance.

  • Instances with extra IPs have no connectivity. The virtual MAC is missing. Generate one in Robot for the IP and assign it to the instance NIC.
  • The host is unreachable after netplan apply. The bridge MAC does not match the physical NIC, or the gateway route is missing on-link: true.