Handshake steht. wg show zeigt den Peer. Transfer: 3 KiB received, 2 KiB sent. Sieht gut aus.

Ping auf den Server? 100% packet loss.

Du verbringst 20 Minuten mit Key-Debugging, wechselst Pre-shared Keys, generierst neue Schlüsselpaare. Alles umsonst. Der Handshake war nie das Problem.


Das Setup

pfSense 2.8.1 mit WireGuard-Paket. Bereits ein Site-to-Site-Tunnel (tun_wg0) aktiv. Jetzt soll ein zweiter Tunnel (tun_wg1) für Road-Warrior-Clients dazu — Laptop, Handy, unterwegs ins Homelab.

KomponenteKonfiguration
Tunneltun_wg1, Port 51821
Server-IP192.168.66.1/24
Client-IP192.168.66.2/24
ModusSplit-Tunnel (nur internes Netz durch VPN)
Client-OSLinux mit NetworkManager

Plan: Tunnel anlegen, Peer hinzufügen, Interface zuweisen, Firewall-Regel, fertig. Sollte in 10 Minuten erledigt sein.

War es nicht.


Pitfall 1: Die Interface-IP verschwindet

Das Symptom

Handshake steht. Auf der pfSense siehst du den Client-Peer mit Endpoint und Transfer-Bytes. Aber: Kein einziger Ping kommt durch. 100% packet loss — in beide Richtungen.

Die Ursache

Wenn du einen WireGuard-Tunnel in pfSense anlegst, gibt es ein Feld “Interface Addresses” wo du die Tunnel-IP einträgst. 192.168.66.1/24. Sieht richtig aus.

Dann weist du den Tunnel einem pfSense-Interface zu (Interfaces → Assignments). Das brauchst du für eigene Firewall-Regeln. Alles normal.

Was pfSense dir nicht sagt: Ab dem Moment wo du den Tunnel einem Interface zuweist, wird die Tunnel-IP ignoriert.

Da steht sogar ein Hint auf der WireGuard-Seite:

“These interface addresses are only applicable for unassigned WireGuard tunnel interfaces.”

Aber wer liest schon Hints.

Das Ergebnis: ifconfig tun_wg1 zeigt keine inet-Zeile. Kein IP. netstat -rn | grep 192.168.66 ist leer. pfSense hat keine Route für dein VPN-Subnetz. WireGuard macht brav den Handshake (der funktioniert auf Crypto-Layer, unabhängig von IPs), aber jedes Datenpaket geht ins Nirwana.

Der Fix

Interfaces → dein WireGuard-Interface → IPv4 Configuration Type: Static IPv4:

IPv4 Address: 192.168.66.1 / 24
IPv4 Upstream Gateway: None

Nicht “None” als Configuration Type — das war der Fehler. “None” heißt “kein IP auf diesem Interface”. Du brauchst Static IPv4 mit der gleichen IP die du im Tunnel konfiguriert hast.

Danach:

ifconfig tun_wg1 | grep inet
# inet 192.168.66.1 netmask 0xffffff00

netstat -rn | grep 192.168.66
# 192.168.66.0/24   link#9   U   tun_wg1

Route existiert. Traffic kann fließen.

Merksatz: WireGuard-Tunnel-IP setzen und Interface-IP setzen. Beide. Sonst fehlt eine.


Pitfall 2: WireGuard-Gruppen-Regeln greifen nicht

Das Symptom

IP ist jetzt da. Route existiert. Trotzdem: Kein Ping, kein Traffic.

Du prüfst die Firewall: Da ist doch eine Regel pass in quick on WireGuard inet all. Die gilt für alle WireGuard-Interfaces. Der Site-to-Site-Tunnel funktioniert damit seit Monaten. Warum nicht der neue?

Die Ursache

pfSense hat Interface-Gruppen. Alle WireGuard-Tunnel landen automatisch in der Gruppe “WireGuard”. Auf dieser Gruppe kannst du Firewall-Regeln setzen — praktisch als Catch-All.

Aber: Sobald du einen Tunnel einem echten pfSense-Interface zuweist, verlässt er die Gruppe für Firewall-Zwecke. Die Gruppen-Regeln gelten nur für unassigned Tunnel.

Das ist logisch wenn man drüber nachdenkt: Das zugewiesene Interface hat eigene Firewall-Regeln. pfSense erwartet, dass du dort explizite Regeln definierst. Die Gruppen-Regeln werden nicht vererbt.

Nur: Wenn dein Site-to-Site-Tunnel (tun_wg0) auch assigned ist und funktioniert, hast du dort wahrscheinlich irgendwann eine Regel auf dem Interface angelegt und es vergessen. Beim neuen Tunnel fehlt sie.

Der Fix

Firewall → Rules → dein WireGuard-Interface → Add:

FeldWert
ActionPass
ProtocolAny
Sourcedein WireGuard-Interface net
DestinationAny

Simpel. Aber wenn du nicht weißt, dass die Gruppen-Regeln nicht greifen, suchst du den Fehler überall — nur nicht bei den Interface-Regeln.


Pitfall 3: NetworkManager bricht dein Internet-DNS

Das Symptom

Tunnel funktioniert endlich! Pings gehen durch. Du erreichst alle internen Server. Aber: google.de lässt sich nicht auflösen. Dein Browser sagt “DNS_PROBE_FINISHED_NXDOMAIN” oder ähnliches. Internes DNS (dc-obiwan.darkside.local) funktioniert.

Die Ursache

Dein VPN-Server nutzt einen internen DNS (z.B. einen Active Directory Domain Controller). Der beantwortet nur die eigene Zone — darkside.local. Für google.de kommt REFUSED.

Das allein wäre kein Problem — dafür hast du ja Split-Tunnel konfiguriert. AllowedIPs enthält nur interne Netze, Internet geht direkt.

Aber NetworkManager hat eine Meinung zu DNS. Wenn du eine WireGuard-Config mit DNS = 192.168.66.1 importierst, setzt NetworkManager diesen DNS-Server als Default für alle Anfragen. In resolvectl status siehst du:

Link 88 (wg-homelab)
    Protocols: +DefaultRoute
    DNS Domain: ~.

~. bedeutet: “Route alle DNS-Anfragen über dieses Interface”. Inklusive google.de. An deinen AD-DNS. Der REFUSED antwortet.

Der Fix

nmcli connection modify wg-homelab ipv4.dns-search "darkside.local"
nmcli connection modify wg-homelab ipv4.dns-priority 100

Danach:

resolvectl status wg-homelab
# Protocols: -DefaultRoute     ← nicht mehr Default!
# DNS Domain: darkside.local   ← nur noch interne Domain

Jetzt geht darkside.local über den VPN-DNS und google.de über dein normales WLAN/Ethernet-DNS.

Verifizierung:

resolvectl query dc-obiwan.darkside.local
# → 192.168.66.10  via wg-homelab  ✓

resolvectl query google.de
# → 142.251.x.x    via wlp0s20f3   ✓

Bonus: Pre-shared Key nicht vergessen

Ein vierter Pitfall, der weniger subtil aber genauso nervig ist: pfSense generiert beim Peer-Anlegen optional einen Pre-shared Key (PSK). Wenn du “Generate” klickst, ist der PSK aktiv — aber du hast ihn noch nicht in deiner Client-Config.

# wg show zeigt auf der pfSense:
peer: abc123...
  preshared key: (hidden)     ← PSK ist aktiv!
  endpoint: 203.0.113.42:34367
  latest handshake: never     ← Handshake scheitert
  transfer: 3 KiB received, 2 KiB sent

transfer zeigt Bytes (das sind die Handshake-Versuche), aber latest handshake: never heißt: kein erfolgreicher Handshake.

Fix: PSK von der pfSense kopieren (VPN → WireGuard → Peers → Edit → “Copy” neben Pre-shared Key) und als PresharedKey = ... in die Client-Config eintragen.


Checkliste: WireGuard Client-VPN auf pfSense

Wenn dein Tunnel nicht funktioniert, geh diese Liste durch:

  • Tunnel enabled? (Häkchen auf der WireGuard-Tunnels-Seite)
  • Interface zugewiesen? (Interfaces → Assignments → tun_wg1)
  • Interface enabled? (Interfaces → dein Interface → Enable)
  • Static IPv4 auf Interface? (ifconfig tun_wg1 | grep inet muss IP zeigen)
  • WAN-Regel für neuen Port? (Firewall → Rules → WAN → UDP 51821)
  • Interface-Firewall-Regel? (Firewall → Rules → dein Interface → Pass all)
  • Pre-shared Key stimmt? (wg showlatest handshake: never = Key-Problem)
  • Split-DNS konfiguriert? (resolvectl status → kein +DefaultRoute auf VPN)

Fazit

Drei Pitfalls, ein gemeinsames Muster: pfSense verhält sich bei assigned WireGuard-Tunneln anders als bei unassigned. Die Tunnel-IP wird ignoriert, die Gruppen-Regeln gelten nicht mehr, und du musst alles explizit auf dem Interface konfigurieren.

Dazu kommt NetworkManager auf der Client-Seite, der DNS-Routing “hilfreich” übernimmt und dabei Internet-DNS killt.

Keiner dieser Fehler produziert eine Fehlermeldung. Der Handshake steht immer. wg show sieht gut aus. Nur: Kein Traffic. Und du sitzt da und fragst dich, ob WireGuard vielleicht doch komplizierter ist als alle behaupten.

Ist es nicht. Man muss nur wissen, wo pfSense einem Steine in den Weg legt.