On-demand Wireguard VPN server on Hetzner

2025/06/13

I need VPN so rarely that any subscription service becomes cost-prohibitive. Instead an on-demand VM instance could be provisioned in a cloud of choice. The cheapest VM on Hetzner costs just 0.007 €/hr. Let’s make it real.

Generate two sets of keys and a PSK

for i in A B; do
    KEY=$(wg genkey)
    PUB=$(echo $KEY | wg pubkey)
    echo -e "$i key: $KEY\n$i pub: $PUB"
done
echo "  psk: $(wg genpsk)"
A key: 8LfzsPSUfKRIF1nJRGsWquwQfYK1t4xtZ/tZd0Iw/nc=
A pub: W3FavAFRpwbwrf+C1swigClVe5HV9deUwqv+V2vGhgc=
B key: 8LXWaEVGhHwPLnXjMjFpZwHNUfj9lfaKWdKB1/gRg3U=
B pub: Tt9VwSHn7v4k7FrdPcgfv6dpIQ+kl/lj1DUvGGnKj18=
  psk: s34FX6nUoDOiPzj6ExWh92kgA03xk6YaQtf7qTRRO2M=

Put these in { placeholders } in files below.

Prepare a cloud-init provision script

wireguard module is only supported on ubuntu.

#cloud-config
wireguard:
  interfaces:
    - name: wg0
      config_path: /etc/wireguard/wg0.conf
      content: |
        [Interface]
        Address = 10.66.66.1/24,fd42:42:42::1/64
        ListenPort = 52817
        PrivateKey = { A key }
        PostUp = iptables -I INPUT -p udp --dport 52817 -j ACCEPT
        PostUp = iptables -I FORWARD -i eth0 -o wg0 -j ACCEPT
        PostUp = iptables -I FORWARD -i wg0 -j ACCEPT
        PostUp = iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE
        PostUp = ip6tables -I FORWARD -i wg0 -j ACCEPT
        PostUp = ip6tables -t nat -A POSTROUTING -o eth0 -j MASQUERADE
        PostDown = iptables -D INPUT -p udp --dport 52817 -j ACCEPT
        PostDown = iptables -D FORWARD -i eth0 -o wg0 -j ACCEPT
        PostDown = iptables -D FORWARD -i wg0 -j ACCEPT
        PostDown = iptables -t nat -D POSTROUTING -o eth0 -j MASQUERADE
        PostDown = ip6tables -D FORWARD -i wg0 -j ACCEPT
        PostDown = ip6tables -t nat -D POSTROUTING -o eth0 -j MASQUERADE

        [Peer]
        PublicKey = { B pub }
        PresharedKey = { psk }
        AllowedIPs = 10.66.66.2/32,fd42:42:42::2/128        

runcmd:
  - sysctl -p /etc/sysctl.d/nat.conf

write_files:
  - content: |
      net.ipv4.ip_forward = 1
      net.ipv6.conf.all.forwarding = 1      
    owner: root:root
    path: /etc/sysctl.d/nat.conf
    permissions: '0644'

Deploy the VM

hcloud server create --name vpn \
    --type cax11 --image ubuntu-24.04 \
    --location hel1 \
    --ssh-key thinkpad \
    --start-after-create
Server 65612345 created
IPv4: 123.123.123.123

Prepare client config

[Interface]
Address = 10.66.66.2/32, fd42:42:42::2/128
PrivateKey = { B key }
ListenPort = 51820

[Peer]
PublicKey = { A pub }
PresharedKey = { psk }
AllowedIPs = 0.0.0.0/0, ::/0
Endpoint = { VM ip }

Start Wireguard

sudo wg-quick up ./wg0.conf

Cleanup after use

sudo wg-quick down ./wg0.conf
hcloud server delete vpn
Server vpn deleted

Further reading