Skip to main content

Method 1 — Single Extra IP with MAC Reservation

Overview

Hetzner allows you to order a single additional IPv4 and bind it to a virtual MAC address. When a frame with that MAC arrives on the uplink, Hetzner routes the IP to it — regardless of which server or VM holds the NIC. You assign that MAC to the PfSense WAN interface in Proxmox, and Hetzner delivers the extra IP directly to PfSense.

This is the simplest method: no subnet routing, no vSwitch, no changes to the host bridge beyond what is already in place.

Step 1 — Order the Additional IP in Hetzner Robot

  1. Log in to robot.hetzner.com
  2. Go to Servers → your server → IPs
  3. Click Order additional IP → select Single IPv4 → complete the order
  4. Once provisioned, click the IP in the list → open the MAC section
  5. Click Generate MAC — Hetzner issues a virtual MAC in the format 00:50:56:xx:xx:xx
  6. Note both values — you need them in the next step:
    • IP address (e.g. 203.0.113.10)
    • Virtual MAC (e.g. 00:50:56:00:1a:2b)
    • Subnet mask and gateway shown in Robot — copy these exactly

The MAC must match exactly. Hetzner drops frames from any other MAC on that IP at the uplink level.

Step 2 — Upload the PfSense ISO to Proxmox

SSH into the Proxmox host and download the PfSense installer ISO directly:

cd /var/lib/vz/template/iso
wget -O pfSense-CE-latest.iso "https://atxfiles.netgate.com/mirror/downloads/pfSense-CE-2.8.0-RELEASE-amd64.iso.gz"
gunzip pfSense-CE-latest.iso.gz

Or upload via the Proxmox web UI: local storage → ISO Images → Upload.

Step 3 — Create the PfSense VM

Run on the Proxmox host. Adjust the VMID (here 104) and ISO filename as needed:

qm create 104 --name PfSense \
  --memory 2048 --cores 2 --cpu host \
  --bios ovmf --machine q35 \
  --net0 virtio,bridge=public-bridge,macaddr=00:50:56:00:1a:2b \
  --net1 virtio,bridge=private-bridge \
  --scsihw virtio-scsi-single \
  --scsi0 VM-Data:20 \
  --ide2 local:iso/pfSense-CE-latest.iso,media=cdrom \
  --efidisk0 VM-Data:0,efitype=4m,pre-enrolled-keys=0 \
  --boot order=ide2 \
  --serial0 socket --vga serial0 \
  --onboot 1 --protection 1
qm start 104

Key points:

ParameterValueWhy
net0 macaddrThe MAC from RobotMust match exactly — Hetzner filters at the uplink
net0 bridgepublic-bridgeWAN — faces Hetzner uplink
net1 bridgeprivate-bridgeLAN — faces internal VM network

Step 4 — Install PfSense

The installer is straightforward but slow — expect 3–5 minutes on a VM with default specs. The console output goes quiet for stretches during disk write operations. It's not frozen. Let it run.

Open the VM console in Proxmox (qm terminal 104 or web UI → Console):

  1. Boot from ISO — accept the copyright notice
  2. Select Install pfSense
  3. Accept default keymap
  4. Select Auto (ZFS) or Auto (UFS) — UFS is fine for a gateway VM
  5. Confirm disk selection (vtscsi0) and proceed
  6. Reboot when prompted — detach the ISO first:
    qm set 104 --ide2 none,media=cdrom
    qm reset 104

Step 5 — Assign Interfaces via Console

On first boot PfSense asks to assign interfaces. At the console prompt:

  1. When asked to set up VLANs — No
  2. WAN interface: vtnet0 (the NIC connected to public-bridge)
  3. LAN interface: vtnet1 (the NIC connected to private-bridge)
  4. Confirm the assignment

Step 6 — Configure WAN

In most cases, Hetzner runs a DHCP server that assigns the reserved IP automatically when a NIC with the matching MAC comes online. Try DHCP first — manual static configuration is only needed if DHCP does not deliver the correct IP.

Option A — DHCP (recommended)

From the PfSense console menu, select 2) Set interface(s) IP address1) WAN:

  1. Configure IPv4 via DHCP? Yes
  2. Configure IPv6 via DHCP? No — leave blank
  3. Revert to HTTP for webConfigurator? No

PfSense will obtain the reserved IP from Hetzner's DHCP server. Verify the correct IP was assigned from the Proxmox host:

qm guest cmd 104 network-get-interfaces

The WAN interface (vtnet0) should show the extra IP from Robot. If it does, skip Option B and continue to Step 7.

Option B — Static (fallback)

If DHCP does not assign the expected IP, set it manually:

  1. Configure IPv4 via DHCP? No
  2. Enter the WAN IPv4 address: 203.0.113.10 (your extra IP from Robot)
  3. Enter the subnet bit count: 32 (Hetzner routes additional single IPs as /32)
  4. For a /32, PfSense will ask for the upstream gateway — enter the same gateway as your host (e.g. 203.0.113.1)
  5. Configure IPv6 via DHCP? No — leave blank
  6. Revert to HTTP for webConfigurator? No

PfSense may warn that the gateway is not within the /32 subnet. This is expected for Hetzner single IPs — confirm and proceed.

Step 7 — Configure LAN

Select 2) Set interface(s) IP address2) LAN:

  1. Enter the LAN IPv4 address: 10.100.100.1
  2. Subnet bit count: 24
  3. No upstream gateway for LAN
  4. Enable DHCP server on LAN? Optional — skip for now if VMs use static IPs

Step 8 — Access the Web UI and Finish Setup

From any VM on the private bridge, open https://10.100.100.1. Default credentials: admin / pfsense.

Run through the setup wizard:

  • Set hostname and DNS servers
  • Confirm WAN and LAN settings
  • Change the admin password

Default firewall behaviour out of the box:

  • LAN → WAN: allowed (NAT masquerade active)
  • WAN → LAN: blocked (stateful firewall)
  • To expose a VM service: Firewall → NAT → Port Forward

Step 9 — Verify

From a VM on the private bridge:

curl -s ifconfig.me   # should return the PfSense WAN IP
ping 1.1.1.1          # should succeed

From outside, ping the extra IP — it should reach PfSense WAN.

VM Network Configuration

With this method, only one public IP exists — the one assigned to PfSense WAN. There is no subnet available to assign public IPs directly to VMs. All VMs sit on the private bridge and reach the internet through PfSense NAT. Inbound access to specific services is handled via PfSense port forwards.

Private VMs (all VMs)

SettingValue
IP address10.100.100.X/24 — any unused address in the range
Subnet mask255.255.255.0 (/24)
Gateway10.100.100.1 (PfSense LAN)
DNS10.100.100.1 (PfSense) or 1.1.1.1 / 8.8.8.8

For cloud-init VMs provisioned from the Proxmox template, set in the VM config:

ipconfig0: ip=10.100.100.X/24,gw=10.100.100.1

Or via the CLI when cloning:

qm set VMID --ipconfig0 ip=10.100.100.X/24,gw=10.100.100.1

Exposing VM Services Publicly

To make a service on a private VM reachable from the internet, add a port forward in PfSense: Firewall → NAT → Port Forward → redirect traffic arriving on the WAN IP + port to the VM's private IP + port. A matching firewall allow rule is created automatically when the NAT rule is saved.