Hetzner: Routing IPv6 through a firewall such as pfSense

Hetzner offer very well specified physical servers at extremely low prices. I’ve used them for many years and they’ve proved to be extremely reliable. With each server, Hetzner will give you a single IPv4 IP and a /64 IPv6 subnet. You can also run virtualization software such as Proxmox and it’s often desirable to run a firewall such as pfSense on a virtual machine to protect the other virtual machines.

All good in principal, but the /64 IPv6 subnet has caused some confusion. Surely you need some more address space to be able to route the /64 subnet? It turns out, no. Hetzner don’t use NDP or proper IPv6 routing… they seem to just deliver the address space to the server (probably via static NDP entries mapping your /64 to your server’s MAC address). This actually works to our advantage because you do not need to assign the physical server any IPv6 addresses in the issued /64.

Broadly, the setup looks like this:

  • Physical server does not have an IPv6 address assigned to its physical interface
  • Physical server has IPv6 forwarding turned on
  • Proxmox (thus the physical server) has a private IPv6 address assigned to the bridge (vmbr) interface that it shares with pfSense
  • pfSense WAN interface has another private IPv6 address in the same subnet as the vmbr assigned to it
  • pfSense “LAN” interface has an address from your public /64 assigned to it
  • pfSense uses SLACC to assign IPs in your /64 to the VMs behind it
  • Physical server has a route to your assigned /64, via the private IP you assigned to your pfSense WAN interface
  • Physical server has a default IPv6 route to fe80::1

Here’s a picture where the assigned /64 is 2a01:4f8:66b:12d9::/64 and the private IPv6 /64 used between Proxmox and pfSense has been chosen fairly randomly using this:

Hetzner IPv6 Routing

Here’s the relevant parts of the network config on the physical Proxmox server:

  1. auto vmbr0
  2. iface vmbr0 inet static
  3. address
  4. netmask
  5. ovs_type OVSBridge
  6. post-up route -A inet6 add default gw fe80::1 dev enp0s31f6
  7. post-up route -A inet6 add 2a01:4f8:66b:12d9::/64 gw fda2:5d88:d5a3:1d4d::2
  8. post-up echo 1 > /proc/sys/net/ipv4/ip_forward
  9. post-up echo 1 > /proc/sys/net/ipv6/conf/all/forwarding
  11. iface vmbr0 inet6 static
  12. address fda2:5d88:d5a3:1d4d::1
  13. netmask 64

If you have any questions, leave a comment.



Leave a Reply

Your email address will not be published. Required fields are marked *