OPNsense ohne SNAT oder Masquerade

Hallo Zusammen,
ich bin Glasfaserkunde und somit vom CGNAT betroffen. Da ich ein paar Server zuhause betreibe, die auch aus dem Urlaub/Hotel erreichbar sein müssen, habe ich erfolgreich einen Wireguard Tunnel von meiner OPNsense zu einem VPS (Ionos) eingerichtet. Der Tunnel wird per IPv6 aufgebaut und im Tunnel wird IPv4 gesprochen. (So ähnlich wie Dennis das mal vorgestellt hat.)
An der Verbindung stört mich, daß die Clients die Tunneladresse (10.x.x.x) sehen und nicht die reale IP der Anfrage.
Also habe ich die VPS-Konfiguration wie folgt abgeändert (SNAT auskommentiert).

[Interface]
PrivateKey = <Key>
Address = 10.20.50.1/24
ListenPort = 51820
Table = off

PostUp   = iptables -t nat -A PREROUTING -i ens6 -p tcp -m multiport --dport 80,443    -j DNAT --to-destination 192.168.11.1
PostUp   = iptables -t nat -A PREROUTING -i ens6 -p tcp -m multiport --dport 8080,8443 -j DNAT --to-destination 192.168.11.1
PostUp   = ip route add 192.168.11.1 via 10.20.50.2 dev wg0
#PostUp   = iptables -t nat -A POSTROUTING -o wg0 -p tcp -m multiport --dport 80,443    -d 192.168.11.1 -j SNAT --to-source 10.20.50.1
#PostUp   = iptables -t nat -A POSTROUTING -o wg0 -p tcp -m multiport --dport 8080,8443 -d 192.168.11.1 -j SNAT --to-source 10.20.50.1

PostDown = iptables -t nat -D PREROUTING -i ens6 -p tcp -m multiport --dport 80,443    -j DNAT --to-destination 192.168.11.1
PostDown = iptables -t nat -D PREROUTING -i ens6 -p tcp -m multiport --dport 8080,8443 -j DNAT --to-destination 192.168.11.1
PreDown  = ip route del 192.168.11.1 via 10.20.50.2 dev wg0
#PostDown = iptables -t nat -D POSTROUTING -o wg0 -p tcp -m multiport --dport 80,443    -d 192.168.11.1 -j SNAT --to-source 10.20.50.1
#PostDown = iptables -t nat -D POSTROUTING -o wg0 -p tcp -m multiport --dport 8080,8443 -d 192.168.11.1 -j SNAT --to-source 10.20.50.1

[Peer]
PublicKey = <Key>
AllowedIPs = 0.0.0.0/0

Gleichzeitig habe ich in der OPNsense ein Gateway (10.20.50.1) angelegt und dieses Gateway als reply-to Gateway in der Firewallregel des Tunnels eingetragen. Eigentlich müsste ich auf der OPNsense eine neue Routing-Table für den Wireguardtunnel anlegen, aber das geht wohl nicht.

HTTPS-Zugriffe bleiben immer beim Handshake hängen

$ curl  -v  https://web.winnig.eu
* Host web.winnig.eu:443 was resolved.
* IPv6: (none)
* IPv4: 87.106.212.183
*   Trying 87.106.212.183:443...
* Connected to web.winnig.eu (87.106.212.183) port 443
* ALPN: curl offers h2,http/1.1
* (304) (OUT), TLS handshake, Client hello (1):
*  CAfile: /etc/ssl/cert.pem
*  CApath: none
* (304) (IN), TLS handshake, Server hello (2):
* TLSv1.2 (IN), TLS handshake, Certificate (11):
* TLSv1.2 (IN), TLS handshake, Server key exchange (12):
* TLSv1.2 (IN), TLS handshake, Server finished (14):
* TLSv1.2 (OUT), TLS handshake, Client key exchange (16):
* TLSv1.2 (OUT), TLS change cipher, Change cipher spec (1):
* TLSv1.2 (OUT), TLS handshake, Finished (20):
* LibreSSL SSL_connect: SSL_ERROR_SYSCALL in connection to web.winnig.eu:443
* Closing connection
curl: (35) LibreSSL SSL_connect: SSL_ERROR_SYSCALL in connection to web.winnig.eu:443

Irgendwas wird scheinbar nicht in den Wireguard Tunnel geschoben, sondern vielleicht auf WLAN oder es wird verworfen ich weiß es nicht.
Es wäre schön, wenn mir jemand weiterhelfen könnte an welchen Schrauben der OPNsense ich drehen muss…

Das geht so herum nicht. Die Regel gilt nur für neue Verbindungen, du musst im WG-Interface das GW setzen, dann werden Reply-To-Rules generiert…

Wie ist das gemeint? Nur HTTPS-Zugriffe verursachen Probleme, ping (icmp) oder z.B. ssh funktionieren aber?

Es wird ja nur TCP 80 & 443 weitergeleitet.

Meine Frage zielt auf den Tunnel ab. Ich habe in meiner pfsense auch ein Problem mit Wiregurad-Tunnel und https gehabt der via v6 erstellt wird, aber v4-Trafic hat. https ging nicht, bis ich die mtu nach unten angepasst habe.


Das hat bei mir auch ein Weilchen gedauert, bis ich das verstanden habe…

Es sieht so aus:
HTTP-Zugriff: Seite wird unvollständig übertragen. Hier ein Beispiel:

<a href="#programmieren">                      <div class="feature-icon">
<i class="fa fa-fw fa fa-desktop"></i>
* transfer closed with outstanding read data remaining
* Closing connection
curl: (18) transfer closed with outstanding read data remaining

HTTPS-Zugriff: SSL Error beim 2. Handshake. Beispiel:

* (304) (IN), TLS handshake, Server hello (2):
* TLSv1.2 (IN), TLS handshake, Certificate (11):
* TLSv1.2 (IN), TLS handshake, Server key exchange (12):
* TLSv1.2 (IN), TLS handshake, Server finished (14):
* TLSv1.2 (OUT), TLS handshake, Client key exchange (16):
* TLSv1.2 (OUT), TLS change cipher, Change cipher spec (1):
* TLSv1.2 (OUT), TLS handshake, Finished (20):
* LibreSSL SSL_connect: SSL_ERROR_SYSCALL in connection to web.winnig.eu:443
* Closing connection
curl: (35) LibreSSL SSL_connect: SSL_ERROR_SYSCALL in connection to web.winnig.eu:443

es sollte eigentlich so aussehen:

* (304) (IN), TLS handshake, Server hello (2):
* TLSv1.2 (IN), TLS handshake, Certificate (11):
* TLSv1.2 (IN), TLS handshake, Server key exchange (12):
* TLSv1.2 (IN), TLS handshake, Server finished (14):
* TLSv1.2 (OUT), TLS handshake, Client key exchange (16):
* TLSv1.2 (OUT), TLS change cipher, Change cipher spec (1):
* TLSv1.2 (OUT), TLS handshake, Finished (20):
* TLSv1.2 (IN), TLS change cipher, Change cipher spec (1):
* TLSv1.2 (IN), TLS handshake, Finished (20):
* SSL connection using TLSv1.2 / ECDHE-RSA-AES256-GCM-SHA384 / [blank] / UNDEF
.
.
.

* Connection #0 to host web.mwinnig.de left intact

Ping funktioniert: VPS->OPNsense:

manne@ionos:~$ ping 192.168.11.1
PING 192.168.11.1 (192.168.11.1) 56(84) bytes of data.
64 bytes from 192.168.11.1: icmp_seq=1 ttl=64 time=39.8 ms
64 bytes from 192.168.11.1: icmp_seq=2 ttl=64 time=38.9 ms
--- 192.168.11.1 ping statistics ---
2 packets transmitted, 2 received, 0% packet loss, time 3004ms
rtt min/avg/max/mdev = 37.258/39.045/40.184/1.135 ms

und andersrum OPNsense->VPS:

manne@mwsense:~ % ping 10.20.50.1
PING 10.20.50.1 (10.20.50.1): 56 data bytes
64 bytes from 10.20.50.1: icmp_seq=0 ttl=64 time=39.718 ms
64 bytes from 10.20.50.1: icmp_seq=1 ttl=64 time=36.386 ms
--- 10.20.50.1 ping statistics ---
2 packets transmitted, 2 packets received, 0.0% packet loss
round-trip min/avg/max/stddev = 36.386/37.708/39.718/1.444 ms
m

Das Gateway im Interface zu setzen erschien mir auch schon sinnvoll, aber es gibt keine Möglichkeit das zu setzen…

Doch, du musst nur IPv4 was konfigurieren, aber ich meine da jammert die OPNsense, das wäre nicht zulässig für diesen Interface-Typ… Dann erscheint nämlich bei „Static“ unten eine Möglichkeit ein GW zu setzen.

Nachtrag: Hab nachgelesen und getestet. Soll wohl angeblich bei der OPNsense bissl anders funktionieren, funktioniert bei mir aber nicht! Also mal wieder super!

Ganz unabhängig von dem was m-electronics dir vorschlägt musst du die MTU in Interfaces [IONOS] anpassen. Du baust den Tunnel via IPv6 auf. Siehe: WireGuard MTU Size 1412 – Best Practices IPv4/IPv6 – MTU Berechnen

Ohne Anpassung wird zwar ping (ICMP) klappen nicht aber alles was udp/tcp betrifft.

Ich habe zwar keine OPNsense, sondern die pfsense, aber meines Wissens nach ist die Vorgabe-MTU auch bei der OPNsense 1500, was zu hoch ist.

Deshalb wies ich ja schon gestern auf die MTU-Problematik hin.

Nur bei PPPoE reicht 1420 nicht.

Korrekt. Aber XV1100 hat

  1. Glasfaser (mit CGNAT). Viele ISP (z.B. Telekom, o2) nutzen auch bei Glasfaser PPPoE und
  2. das Bildschirmfoto von XV1100 Interfaces [IONOS] zeugt ein leeres Feld für die MTU. Und das bedeutet meiner Kenntnis nach default 1500. Da ich aber keine OPNsense habe, mag das nicht (mehr) richtig sein.

Man kann die MTU bei der OPNsense auch in der WG-Instance selbst setzen…

Ihr könnt Euch ja nicht vorstellen wieviele MTU/MSS Einstellungen ich schon probiert habe. Das nützt alles nix. Als wichtig hat sich eine Reduzierung der MSS auf 1380 herausgestellt und die habe ich auch eingetragen. (s. Screeshot oben)

Ein Gateway kann ich auf dem Wireguard-Interface nur setzen, wenn ich eine statische IPv4 vergebe. Das ist jedoch nicht erlaubt.
Cannot assign an IP configuration type to a tunnel interface.
Ich würde die wg0.conf Datei auch manuell bearbeiten, aber das scheint wohl auch nicht zu funktionieren.

 % sudo cat /usr/local/etc/wireguard/wg0.conf
####################################################
# Interface settings, not used by `wg`             #
# Only used for reference and detection of changes #
# in the configuration                             #
####################################################
# Address =  10.20.50.2/24
# DNS =
# MTU = 1420
# disableroutes = 1
# gateway = 10.20.50.1

Ist zwar alles auskommentiert, aber das Gateway (die Adresse des IONOS VPS) ist eingetragen. Ich denke, irgendwie müsste da noch eine Routing-Table rein, aber wie?

Was ich nicht gesetzt habe ist (weil keine Verbesserung feststellbar):

  1. eine manuelle Route nach 10.20.50.0/24 (dort könnte ich allerdings ein Gateway setzen)
  2. eine manuelle Outbound Regel auf dem IONOS-Interface

Die pfsense hat (anders als die OPNsense) kurze Hinweistexte zu den Optionen in den Konfigurationsfeldern. Unter Interfaces / WGTun0 (tun_wg0) finden sich bei mir folgende Hinweise:

  • MTU: If this field is blank, the adapter’s default MTU will be used. This is typically 1500 bytes but can vary in some circumstances.
  • MSS: If a value is entered in this field, then MSS clamping for TCP connections to the value entered above minus 40 for IPv4 (TCP/IPv4 header size) and minus 60 for IPv6 (TCP/IPv6 header size) will be in effect.

Ferner bin ich noch auf dies gestoßen: how to change tcp mss in linux to solve MTU issue.

Die MSS 1380 ist also richtig, wenn die MTU 1420 ist, aber nur wenn kein IPv6 im Spiel ist.

Edit: mit tracepath kannst du dir die pmtu auf der route anzeigen lassen.

In der Wireguardconfig gibt es diesen Gateway-Parameter auch nicht. (Obwohl da steht, dass ist keine Wireguard-Config-File im klassischen Sinne? :thinking:)
Aber ich hab eine Lösung gefunden, wie es geht.
In der WG-Instanz „Advanced mode“ aktivieren.

  • Disable routes
  • Gateway: VPS-WG-IP

In den Gateways ein GW anlegen mit der WG-IP des VPS.
Auf dem WG-Interface (erstmal zuweisen in den Interfaces) in der Firewall eine Allow-All-Inbound-Regel anlegen (da ich das Firewalling von außen auf dem VPS machen würde) und da in den „Advanced-Options“ bei reply-to das vorher angelegte GW auswählen, dann geht es nämlich :slight_smile:

Eigentlich ist das genau die Konfiguration, die ich schon die ganze Zeit benutze… Ich kann gerne nochmal Screenshots machen…
Ich habe ein (Far-) Gateway 10.20.50.1 mit Monitor auf 10.20.50.1 und 0% Paketverlust.
Dieses Gateway ist in der Firewallregel des Wireguardtunnels als reply-to Gateway (Auswahlbox) und in der Wireguardinstanz mit der IP-Adresse eingetragen. Dort ist ebenso Disable routes angehakt.
Da alle Leute behaupten, dass es an der MTU liegt, habe ich die auf 1412 reduziert und die MSS auf 1360 (in der WG-Instanz und im WG-Interface).
Auch den IONOS VPS habe ich auf MTU=1412 gesetzt. Leider ändert das alles gar nichts an dem Verhalten…
Gibt es Pakete, die vom Webserver generiert werden, vielleicht irgendwelche Folgepakete, die dann die öffentliche IP tragen und nicht wissen, dass sie über den WG-Tunnel laufen müssen? Ich muss mich wohl noch mit Wireshark befassen um das rauszukriegen…

Das weiß ich dann jetzt auch nicht genau, aber das mit der MSS auf einen niedrigeren Wert setzen ist Blödsinn, soweit ich das verstehe. Da steht bei der pfSense zumindest, dass die automatisch von dem dort eingetragenen Wert ausgerechnet wird.
Aber dann müsste man wirklich mit tcpdump und Wireshark sich das anschauen, wo welche Pakete fließen.

So, falls das hier nochmal jemand liest…
OPNsense mit Vorgeschaltetem VPS (bei mir IONOS) ohne SNAT: läuft.
Es war alles richtig konfiguriert (MTU und MSS-Einträge werden nicht gebraucht). Hier nochmal meine aktuelle VPS Konfig:

[Interface]
PrivateKey = xxx
Address = 10.20.50.1/24
ListenPort = 51820
Table = off

PostUp   = iptables -t nat -A PREROUTING -i ens6 -p tcp -m multiport --dport 80,443    -j DNAT --to 192.168.11.1
PostUp   = ip route add 192.168.11.1 via 10.20.50.2 dev wg0
PostUp   = iptables -t mangle -A FORWARD -p tcp --tcp-flags SYN,RST SYN -j TCPMSS --clamp-mss-to-pmtu

PostDown = iptables -t nat -D PREROUTING -i ens6 -p tcp -m multiport --dport 80,443    -j DNAT --to 192.168.11.1
PreDown  = ip route del 192.168.11.1 via 10.20.50.2 dev wg0
PostDown = iptables -t mangle -D FORWARD -p tcp --tcp-flags SYN,RST SYN -j TCPMSS --clamp-mss-to-pmtu

[Peer]
PublicKey = xxx
AllowedIPs = 0.0.0.0/0

Auf der OPNsense muss dann ein Gateway (10.20.50.1) angelegt werden und im Wireguard eingetragen werden. Das Gateway muss dann auch in den Firewall-Regeln als reply-to Gateway selektiert werden. Das wars dann im Prinzip. Ich hatte Verbindungsabbrüche, vermeintlich verlorene Pakete jede Menge Mist! Nach wochenlangen Suchen und Einarbeitung in Wireshark bin ich zufällig auf das Übel gestoßen. Scheinbar funktioniert die Hardware nicht wie sie soll. Unter Interfaces-Settings musste ich die Hardware TSO abschalten (also Haken bei Disable). Plötzlich funktioniert alles wie gewünscht. Leider habe ich Monate gebraucht um das zu finden…

1 Like