meltinsands
Goto Top

OpenVPN mit IPv6 Verbindungsprobleme

Hallo liebe Netzwerk-Profis,

wieder mal so ein Problem mit OpenVPN und IPv6....

Ich habe folgendes Setup:
  • Fritzbox Cable
  • Dualstack
  • RasPi mit
IPv4 OpenVPN mit Site-2-Site Konfiguration
Pihole
  • nftables

Ziel:
  • Ich will meine bestehende OpenVPN IPv4 Konfiguration um IPv6 erweitern.

Anpassungen an der bestehenden Konfiguration:
ULA: fd00:abba:abba:abba:
OVPN: fd00:affe:affe:affe:
Client-LAN Site-2-Site: fd00:ace:ace:ace
LLA des RaspberryPi: fe80::beef:beef:beef:beef

  • Server.conf
Befehle für IPv4 und IPv6 hinterlegt. Ergänzungen für IPv6:
proto udp6
push tun-ipv6 
ifconfig-ipv6 fd00:affe:affe:affe::1 fd00:affe:affe:affe::2
server-ipv6 fd00:affe:affe:affe::/64
push "route-ipv6 fd00:abba:abba:abba:: ::2/64"  
route-ipv6 fd00:abba:abba:abba:: ::2/64
#Laut c't Artikel sollen diese beiden Zeilen aaskommentiert werden, aber der gesamte Traffic soll durch den Tunnel und Pihole die Werbung filtern. Daher habe ich es belassen:  
push "redirect-gateway def1 bypass-dhcp"  
push "dhcp-option DNS 10.8.0.1"  

  • Client.ovpn
proto udp6
route-ipv6 fd00:abba:abba:abba:: ::2/64

  • CCD normaler Client
ifconfig-push fd00:affe:affe:affe::30/64

  • CCD Site-2-Site
ifconfig-push fd00:affe:affe:affe::20/64
iroute fd00:abba:abbs:abba::20/64

  • sudo nano /etc/sysctl.conf
net.ipv6.conf.all.forwarding=1

  • Fritz!box (Server-Seite)
Router Advertisement im LAN aktiv
Unique Local Addresses (ULA) immer zuweisen
ULA-Präfix manuell festlegen: fd00:abba:abba:abba
DNSv6-Server auch über Router Advertisement bekanntgeben (RFC 5006): fe80:0:0:0:beef:beef:beef:beef
Portfreigabe UDP 1194 für IPv4 und IPv6
Statische Route OpenVPN Netzwerk fd00:affe:affe:affe:0:0:0:0 Präfix 64 Gateway fe80:0:0:0:beef:beef:beef:beef
Statische Route Site-2-Site Netzwerk fd00:ace:ace:ace:0:0:0:0 Präfix 64 Gateway fe80:0:0:0:beef:beef:beef:beef

  • DynDNS unterstützt IPv6
2a02:: stimmt mit der 2a02:: des RasPi aus der Portfreigabe überein.

  • Fritz!box (Site-2-Site)
Anpassungen folgen nach funktionierender Client-Server-Verbindung

Problem:
- Deaktiviert ich die Portfreigabe für IPv4 kann Client keine Verbindung mehr aufbauen. IPv6 wird also nicht hergestellt.
- Auch bei deaktivierter Firewall kann die Verbindung nicht aufgebaut werden.
- Auf https://www.wieistmeineip.de/ipv6-test/ steht, meine IPv6 ist bei bestehender VPN nicht vorhanden. Angezeigt wird mir nur die IPv4.

Content-ID: 11310790380

Url: https://administrator.de/contentid/11310790380

Ausgedruckt am: 19.12.2024 um 11:12 Uhr

aqui
aqui 22.09.2023 um 12:13:24 Uhr
Goto Top
Laut c't Artikel sollen diese beiden Zeilen auskommentiert werden
Dann musst du aber auch das Pushen der dedizierten Route auskommentieren.
Beides, Split Tunneling und Gateway Redirect ist Unsinn und funktioniert nicht.
Guckst du auch hier.
Deaktiviert ich die Portfreigabe für IPv4 kann Client keine Verbindung mehr aufbauen.
Was ja auch irgendwie verständlich ist bei Port Forwarding.
in der Regel arbeitet die Firewall kombiniert mit IPv4 und IPv6 so das vermutlich das Port Forwarding für beide Protokolle gilt. Das solltest du nochmal genau prüfen. Ansonsten wäre das PFW Verhalten fehlerhaft.
Wie sieht deine IPv6 Routing Tabelle auf dem Client aus wenn der VPN Tunnel aktiv ist??
meltinsands
meltinsands 22.09.2023 aktualisiert um 15:22:50 Uhr
Goto Top
Deaktiviert ich die Portfreigabe für IPv4 kann Client keine Verbindung mehr aufbauen.
Was ja auch irgendwie verständlich ist bei Port Forwarding.
in der Regel arbeitet die Firewall kombiniert mit IPv4 und IPv6 so das vermutlich das Port Forwarding für beide Protokolle gilt. Das solltest du nochmal genau prüfen. Ansonsten wäre das PFW Verhalten fehlerhaft.
Wie sieht deine IPv6 Routing Tabelle auf dem Client aus wenn der VPN Tunnel aktiv ist??
Hier schreibe ich über das Deaktivieren der Portfreigabe für die IPv4 am Router. Zur Sicherheit: Du meintest nicht, dass ich Änderungen in der sudo nano /etc/sysctl.conf beschreibe?
Es sollte doch möglich sein, dass ich eine VPN aufbaue, die nur über IPv6 läuft, so wie es bisher über IPv4 gelaufen ist. Umgekehrt musste bei IPv4 auch nicht die Portfreigabe von IPv6 im Router aktiv sein.
Um einen Fehler und er FW des Pi auszuschließen, habe ich diese schon für den Verbindungstest deaktiviert.


Laut c't Artikel sollen diese beiden Zeilen auskommentiert werden
Dann musst du aber auch das Pushen der dedizierten Route auskommentieren.
Beides, Split Tunneling und Gateway Redirect ist Unsinn und funktioniert nicht.
Guckst du auch hier.
Das ist es bisher nicht, weil ich mit push route erreichen will, dass die Clients auf das lokale Netz zugreifen können. Ich habe daher schweren Herzens push "redirect-gateway def1 bypass-dhcp" auskommentiert.

Die FW ist deaktiviert. Durch das auskommentieren ist folgendes passiert:
- Client stellt Verbindung zum Server her, solange Portfreigabe 1194 UDP IPv4 aktiv ist.
- Internet auf Client ist verfügbar.
- Ping auf RasPi und Router mit 192er IP möglich.
- Kein Ping auf NAS möglich. Ping von lokalem Gerät auf NAS ist möglich.
- Zugriff auf NAS ist möglich.
- Ping innerhalb 10.8.0.0 funktioniert


Es scheint dem VPN Server aber noch etwas anderes Probleme zu bereiten:
systemctl status openvpn@PiServer.service
● openvpn@PiServer.service - OpenVPN connection to PiServer
   Loaded: loaded (/lib/systemd/system/openvpn@.service; enabled; vendor preset: enabled)
   Active: activating (auto-restart) (Result: exit-code) since Fri 2023-09-22 14:36:06 CEST; 4s ago
     Docs: man:openvpn(8)
           https://community.openvpn.net/openvpn/wiki/Openvpn24ManPage
           https://community.openvpn.net/openvpn/wiki/HOWTO
  Process: 3392 ExecStart=/usr/sbin/openvpn --daemon ovpn-PiServer --status /run/openvpn/PiServer.status 10 --cd /etc/openvpn --config /etc/openvpn/PiServer.conf --writepid /run/openvpn/PiS
 Main PID: 3392 (code=exited, status=1/FAILURE)
   Status: "Pre-connection initialization successful"  

Obwohl er nicht active ist, kann ich mich damit verbinden. Außerdem bleibt die openvpn-status.log leer.

Ich nutze OpenVPN 2.4 aber aktiviere den Server mit systemctl enable openvpn@PiServer statt openvpn-server. Kann das Fehler verursachen?
aqui
aqui 22.09.2023 um 15:21:32 Uhr
Goto Top
Eine Portfreigabe für IPv6 würde bei dir auch nichts nützen wenn du ULA Adressen verwendest die im Internet nicht geroutet werden.
Nur wenn du den Zugriff von außen auf eine Global v6 Adresse erlaubst wäre die überhaupt routebar. Bei IPv6 gibt es bekanntlich kein NAT. face-wink
meltinsands
meltinsands 22.09.2023 aktualisiert um 16:18:01 Uhr
Goto Top
Habe meine obige Antwort nochmal korrigieren müssen. Ist jetzt auf dem aktuellen Stand.


Zitat von @aqui:

Eine Portfreigabe für IPv6 würde bei dir auch nichts nützen wenn du ULA Adressen verwendest die im Internet nicht geroutet werden.
Nur wenn du den Zugriff von außen auf eine Global v6 Adresse erlaubst wäre die überhaupt routebar. Bei IPv6 gibt es bekanntlich kein NAT. face-wink

Dem DynDNS habe ich doch die Global v6 Adresse des RasPi a la 2a01:: mitgeteilt.

Warum sollte ich den ganzen Spaß machen, wenn es am Ende nichts bringt. face-wink

Das iPhone bekommt vom Server keine IPv6 zugeteilt:
OpenVPN CLIENT LIST
Updated,Fri Sep 22 15:33:36 2023
Common Name,Real Address,Bytes Received,Bytes Sent,Connected Since
iPhone,50.500.5.50:40696,8574,23542,Fri Sep 22 15:33:05 2023
ROUTING TABLE
Virtual Address,Common Name,Real Address,Last Ref
10.8.0.10,iPhone,50.500.5.50:40696,Fri Sep 22 15:33:06 2023
GLOBAL STATS
Max bcast/mcast queue length,0
END

Auch, dass der Server nicht durchstartet, ist ungewöhnlich.

Um es dann doch an einem Endgerät mit Terminal zu testen, stelle ich fest, dass dort die IPv6 Conf, die auf dem iPhone funktioniert, auf dem MacBook nicht funktioniert und ich keine Verbindung aufbauen kann face-sad Mit der IPv4 Conf funktioniert es in Sekunden.
7907292512
7907292512 22.09.2023 aktualisiert um 17:52:25 Uhr
Goto Top
Zitat von @aqui:
Nur wenn du den Zugriff von außen auf eine Global v6 Adresse erlaubst wäre die überhaupt routebar. Bei IPv6 gibt es bekanntlich kein NAT. face-wink
Doch klar gibt es auch bei IPv6 NAT, auch wenn es natürlich gegen denk Gedanken von IPv6 spricht. Wenn er also den Clients im Tunnel keine globale Adresse/Prefix zuweisen kann/will muss er am OUTPUT des VPN-Servers auf die Globale IPv6 Adresse des Servers NATen, dann klappt es auch mit dem IPv6 GW-Redirect in den Tunnel.

Via iptables
ip6tables -t nat -A POSTROUTING -s fd00:affe:affe:affe::/64 -o eth0 -j MASQUERADE
Geht natürlich auch mit nftables (chains sind je nach System unterschiedlich, nur ein Beispiel)
table inet nat {
	chain POSTROUTING {
		meta nfproto ipv6 ip saddr fd00:affe:affe:affe::/64 oifname eth0 counter masquerade
	}
}

Wenn man dagegen nur für IPv4 und nicht für IPv6 einen Gateway-Rediect machen will kann man das so in der Client-Config machen
redirect-gateway !ipv6 ipv4
Dann bleibt der globale IPv6 Traffic des Clients abgekoppelt vom Server.

Gruß sid

Denk hier ist nochmal etwas IPv6 Grundlagenarbeit fällig
https://danrl.com/ipv6/
meltinsands
meltinsands 23.09.2023 aktualisiert um 20:51:56 Uhr
Goto Top
Es führte scheinbar kein Weg drum herum, die Privacy Extension aufzugeben.

Die Verbindung zum Server baut das iPhone nun sicher über IPv6 auf, wenn ich die Portweiterleitung für IPv4 an der f!b dicht mache.

Würde mich mit einem Update nochmal melden. Es gibt noch ein paar Dinge, die noch nicht so laufen, wie ich es gerne hätte.
aqui
aqui 24.09.2023 aktualisiert um 12:09:14 Uhr
Goto Top
Na ja, das etwas angestaubte und wenig skalierende OpenVPN zu verwenden ist auch nicht mehr zeitgemäß zumal der RasPi ja mit einer entsprechenden Konfig (Strongswan) problemlos und ohne große Frickelei mit (überflüssigen) externen VPN Client Apps die onboard VPNs aller Smartphones und bestehenden Betriebssysteme supportet inkl. IPv6.
Warum man dann noch mit OpenVPN rumfrickelt erschliesst sich einem nicht so wirklich?!
IKEv2 VPN Server für Windows und Apple Clients mit Raspberry Pi
meltinsands
meltinsands 24.09.2023 um 22:48:18 Uhr
Goto Top
In kurz: Weil es bisher sehr stabil lief und seinen Zweck erfüllt. Aber zugegeben, ich spielte schon oft mit dem Gedanken, es durch ein Wireguard zu ersetzen.

Ich weiß nur nicht, welcher Aufwand für mich dahinter steckt, alles wieder auf Wireguard oder ein IKEv2 umzumodeln. Im Netz findet man meist die super einfachen Setups, aber da kann ich auch gleich Wireguard aus der Fritte nutzen. Bevor ich mich also mit einem neuen VPN beschäftige, bringe ich dass hier noch schnell zu Ende und kann in Ruhe etwas parallel aufbauen. Du wirst davon sicherlich von mir hier lesen face-wink


Auch ist die Config von OpenVPN gerade nicht so das Problem, sondern, wie ich feststellte, habe ich mir wohl in nftables eine Sackgasse ohne Wendemöglichkeit gebaut. Wenn ich sie aktiviere, verliert der Pi seine IPv6 Adresse. Hast du gerade die Muse hier einmal einen Blick drauf zu werfen, wo sie sich versteckt?

define localhost_ipv4 = 127.0.0.0/8
define localhost_ipv6 = ::1/128
define ssh_port = 22
define ovpn_port = 1194
define dns_port = 53
define http_port = 80
define https_port = 443 
define pihole_port = 67
define ovpn_ipv4 = 10.8.0.0/24
define ovpn_ipv6 = fd00:affe:affe:affe::/64


add table inet basic-filter
add chain inet basic-filter INPUT { type filter hook input priority 0; policy accept; }
add chain inet basic-filter FORWARD { type filter hook forward priority 0; policy accept; }
add chain inet basic-filter OUTPUT { type filter hook output priority 0; policy accept; }

add rule inet basic-filter INPUT ct state related,established counter accept

add rule inet basic-filter INPUT iifname "lo" counter accept  
add rule inet basic-filter INPUT iifname != "lo" ip saddr $localhost_ipv4 counter reject  
add rule inet basic-filter INPUT iifname != "lo" ip6 saddr $localhost_ipv6 counter reject  

add rule inet basic-filter INPUT ct state new icmp type echo-request counter accept
add rule inet basic-filter INPUT ip protocol icmp ct state related,established counter accept

add rule inet basic-filter INPUT ct state new icmpv6 type echo-request counter accept
add rule inet basic-filter INPUT ip6 nexthdr icmpv6 ct state related,established counter accept

add rule inet basic-filter INPUT ct state new,related,established tcp dport $ssh_port counter accept

add rule inet basic-filter INPUT ct state new udp dport $dns_port counter accept
add rule inet basic-filter INPUT ct state new tcp dport $dns_port counter accept
add rule inet basic-filter INPUT ct state new tcp dport $http_port counter accept
add rule inet basic-filter INPUT ct state new tcp dport $https_port counter accept

add rule inet basic-filter INPUT iifname "tun0" ct state new counter accept  

add rule inet basic-filter INPUT iifname "eth0" ct state new udp dport $ovpn_port counter accept  

add rule inet basic-filter INPUT ct state new tcp dport $pihole_port counter accept

add rule inet basic-filter INPUT ct state invalid counter drop


add rule inet basic-filter INPUT limit rate 3/minute burst 5 packets counter log prefix "nftables_INPUT_denied: "  

add rule inet basic-filter INPUT counter reject

add rule inet basic-filter FORWARD ct state related,established counter accept

add rule inet basic-filter FORWARD iifname "tun0" oifname "eth0" ct state new counter accept  
add rule inet basic-filter FORWARD iifname "eth0" oifname "tun0" ct state new counter accept  
add rule inet basic-filter FORWARD iifname "tun0" oifname "tun0" ct state new counter accept  


add rule inet basic-filter FORWARD limit rate 3/minute burst 5 packets counter log prefix "nftables_FORWARD_denied: "  

add rule inet basic-filter FORWARD counter reject

add rule inet basic-filter OUTPUT ct state new,established counter accept


add rule inet basic-filter OUTPUT limit rate 3/minute burst 5 packets counter log prefix "nftables_OUTPUT_denied: "  

add rule inet basic-filter OUTPUT counter reject


add table inet basic-nat
add chain inet basic-nat PREROUTING { type nat hook prerouting priority -100; policy accept; }
add chain inet basic-nat INPUT { type nat hook input priority 100; policy accept; }
add chain inet basic-nat OUTPUT { type nat hook output priority -100; policy accept; }
add chain inet basic-nat POSTROUTING { type nat hook postrouting priority 100; policy accept; }

add rule inet basic-nat POSTROUTING oifname "eth0" ip saddr $ovpn_ipv4 counter masquerade  
add rule inet basic-nat POSTROUTING oifname "eth0" ip6 saddr $ovpn_ipv6 counter masquerade  
7907292512
7907292512 24.09.2023 aktualisiert um 23:19:05 Uhr
Goto Top
Ist ja auch klar weil du alles außer icmpv6 echo requests dropst, da werden sämtliche RouterAdvertisements etc. weg gefiltert.
Fur IPv6 sind ICMPv6 Pakete essentiell da sämtliche abstimmende Kommunikation darüber abläuft.

Du brauchst also mindestens diese ICMP Typen in der Input Chain und zwar stateless oder im state "new"
ip6 nexthdr icmpv6 icmpv6 type { nd-neighbor-solicit, nd-router-advert, nd-neighbor-advert } accept
Und in der Forward Chain für die Clients die ICMPv6 Basics für Problemmeldungen ohne state
ip6 nexthdr icmpv6 icmpv6 type { destination-unreachable, packet-too-big, time-exceeded, parameter-problem } accept
Und wenn ein DHCPv6 Client zum Einsatz kommt im INPUT auch noch eine Freigabe von Port 546 UDP.
ip6 daddr fe80::/64 udp dport dhcpv6-client accept
meltinsands
meltinsands 24.09.2023 aktualisiert um 23:38:13 Uhr
Goto Top
Top, habe beides in die INPUT Chain gepackt! face-smile

Bisher läuft, aber bei dir nicht anders zu erwarten.
7907292512
7907292512 24.09.2023 aktualisiert um 23:42:32 Uhr
Goto Top
Mit kommt nur ArchLinux auf diese Bananen, alles andere ist mir schon zu viel überflüssiges Gedöhns mit an Bord. Da reichen dann auch schon mal weit weniger als 100MB Arbeitsspeicher für so ne Kiste.
Nur mal so nebenbei als Tipp.
aqui
aqui 25.09.2023 aktualisiert um 09:09:28 Uhr
Goto Top
welcher Aufwand für mich dahinter steckt, alles wieder auf Wireguard oder ein IKEv2 umzumodeln.
Das wissen wir natürlich auch nicht, denn wir kennen dich und deine Fähigkeiten ja leider nicht.
Für einen durchschnittlichen Netzwerker ist sowas in 30 Min bis maximal einer Stunde erledigt. Bei WG eher noch die Hälfte da dort lediglich nur 7 oder weniger Konfig Zeilen zu tippen sind und keine Zeretifikate erforderlich sind. Hat aber den nachteil das du wieder mit zusätzlicher Client Software frickeln muss was bei IKEv2 entfällt, da alle onboard.
Its your choice! face-wink
Du wirst davon sicherlich von mir hier lesen
Immer gerne! 😉
Wenn ich sie aktiviere, verliert der Pi seine IPv6 Adresse.
Oha, zeigt das du ihm vermutlich IPv6 abgedreht hast...?!
Etwas sinnvolle und kostenlose Lektüre zum IPv6 Protokoll kann da ganz sicher nicht schaden:
https://danrl.com/ipv6/

So sähe es z.B. in der input Chain aus:
# Interface name
define pub_iface = "eth0"  
# OpenVPN port
define ovpn_port = 1194

table inet filter {
	chain input {
		type filter hook input priority 0; policy drop;
		# accept any localhost traffic
		iif lo accept

		# accept any OpenVPN traffic
		iifname "tun0" accept  

		# accept traffic originated from RasPi
		ct state established,related accept

		# accepted ICMP types		
		ip protocol icmp icmp type { time-exceeded, parameter-problem, destination-unreachable } accept

		# accept common local TCP services 
		# tcp dport { ssh, http, https } ct state new accept
		iif $pub_iface tcp dport { ssh } ct state new accept

		# accepted UDP VPN ports on public interface 
		iif $pub_iface udp dport { isakmp, ipsec-nat-t, $ovpn_port } accept 
		iif $pub_iface ip protocol esp accept 

		# allow IPsec VPN networks
		meta ipsec exists accept

		# accept neighbour discovery otherwise IPv6 connectivity breaks.
		ip6 nexthdr icmpv6 icmpv6 type { nd-neighbor-solicit, nd-router-advert, nd-neighbor-advert } accept

		# log and count dropped traffic
		# log prefix "[nftables]Denied: " counter drop 
		# only count dropped traffic
		counter drop
	} 
Wenn du "inet" nutzt als Protokoll Family Definition gilt das Regelwerk für v4 und v6. Guckst du HIER.
Kollege @7907292512 hat ja oben schon alles gepostet zu der Thematik... face-wink
meltinsands
meltinsands 25.09.2023, aktualisiert am 28.09.2023 um 20:15:57 Uhr
Goto Top
Zum Client:
Es gibt vermutlich noch einen Syntaxfehler im Client oder Server. Status des VPN Clients:
OpenVPN ROUTE6: cannot parse gateway spec '::2/64'  
oder
Options error: route-ipv6 parameter gateway '::2/64' must be a valid address  

Zu Client/Server:
Und in der Forward Chain für die Clients die ICMPv6 Basics für Problemmeldungen ohne state
ip6 nexthdr icmpv6 icmpv6 type { destination-unreachable, packet-too-big, time-exceeded, parameter-problem } accept

Sollte der Client/Server nicht bereits DHCPv6 akzeptieren und senden können? Für DHCP geht es doch ebenfalls ohne.

Zum Server:
Manchmal verliert der RPi Server die IPv6, trotz:
Du brauchst also mindestens diese ICMP Typen in der Input Chain und zwar stateless oder im state "new"
ip6 nexthdr icmpv6 icmpv6 type { nd-neighbor-solicit, nd-router-advert, nd-neighbor-advert } accept

Bei einem Reboot ohne nftables kommt die IPv6 wieder. Schalte ich nftables an, roboote, bleibt die IPv6, geht aber nach einiger Zeit verloren.
meltinsands
meltinsands 28.09.2023 aktualisiert um 20:16:35 Uhr
Goto Top
Update: Nach fast 24 Stunden ist die IPv6 mit FW noch da.
Update: Nach ca. 36 Stunden seit reboot ist die IPv6 wieder verloren gegangen. Kann die Ursache noch bei nftables liegen?


Wie könnte die Lösung für die Client-Verbindung aussehen und die beiden Ergänzungen der nftables?
meltinsands
meltinsands 28.09.2023 um 13:45:04 Uhr
Goto Top
Update vom Update: Ohne einen Reboot ist die IPv6 wieder zurück.
meltinsands
meltinsands 09.10.2023 um 21:23:38 Uhr
Goto Top
Guten Abend,

die Firewall scheint noch etwas notwendiges für die IPv6 Verbindung zu blockieren. Das gilt primär für den RPi, der später als Client für Site-2-Site agieren soll:

In der Log mit verb3 finde ich auf dem Client:
TLS Error: TLS key negotiation failed to occur within 60 seconds (check your network connectivity)
TLS Error: TLS handshake failed
SIGUSR1[soft,tls-error] received, process restarting
Restart pause, 5 second(s)
^[[0;1;31mFailed to query password: Timer expired^[[0m
ERROR: Failed retrieving username or password
Exiting due to fatal error

...erklärt vermutlich auch diese Nachricht:
Password entry required for 'Enter Private Key Password:' (PID 2889).  
Please enter password with the systemd-tty-ask-password-agent tool.

In der Server.log sind mit verb3 keine Einträge zum Verbindungsversuch zu finden.

  • Die selbe Client.conf mit IPv4 verbindet sich tadellos.
  • Andere Clients (iPhone, iPad) connecten sich ebenfalls mit IPv6 zum Server.
  • Die Verbindung mit IPv6 ohne aktive nfttables auf dem Server funktioniert ebenfalls.

Kann mir das leider nicht herleiten. Was kann ich übersehen haben?
aqui
aqui 09.10.2023 um 22:08:51 Uhr
Goto Top
Du hast auf dem Key noch ein Passwort und vermutlich in der Konfig vergessen das an die Textdatei zu binden in der dieser User/Pass konfiguriert ist. Das geht z.B. mit dem folgenden Eintrag in der Konfig Datei:
auth-user-pass /etc/openvpn/auth.txt
https://openvpn.net/community-resources/reference-manual-for-openvpn-2-5 ...
meltinsands
meltinsands 10.10.2023 um 08:20:01 Uhr
Goto Top
Hallo @aqui, das ist es leider nicht. Ich habe die auth.data in der Client.conf verknüpft.
askpass /etc/openvpn/client/auth.data ist hinterlegt
auth-user-pass nutze ich nicht

Was der Annahme widerspricht:
- IPv4 Verbindung funktioniert.
- IPv6 funktioniert mit leerem nft ruleset
aqui
aqui 10.10.2023 aktualisiert um 11:03:40 Uhr
Goto Top
IPv6 funktioniert mit leerem nft ruleset
Dann ist es ja eine Einstellung der Firewall! Wie sieht denn dein v6 Ruleset aus??
Dort sollte für die Input Chain bei v6 sowas stehen:
# Interface name
define pub_iface = "eth0"  
# OpenVPN port
define ovpn_port = 1194

table inet filter {
	chain input {
		type filter hook input priority 0; policy drop;
		# Accept any localhost traffic
		iif lo accept

		# Accept any OpenVPN traffic
		iifname "tun0" accept  

		# Accept traffic originated from us
		ct state established,related accept

		# Accepted ICMP types
		# ip protocol icmp icmp type {echo-request, echo-reply, time-exceeded, parameter-problem, destination-unreachable } accept		
		ip protocol icmp icmp type { time-exceeded, parameter-problem, destination-unreachable } accept

		# Accept  local TCP services on public interface
		iif $pub_iface tcp dport { ssh } ct state new accept

		# Accepted OpenVPN on public interface 
		iif $pub_iface udp dport { $ovpn_port } accept 

		# Accept neighbour discovery otherwise IPv6 connectivity breaks.
		ip6 nexthdr icmpv6 icmpv6 type { nd-neighbor-solicit, nd-router-advert, nd-neighbor-advert } accept

		counter drop
	} 
meltinsands
meltinsands 10.10.2023 um 22:57:21 Uhr
Goto Top
Hallo @aqui,

ich habe hier das gesamte Regelwerk abgebildet. Ich hatte es auch mit deinem abgeglichen und deine Regeln sollten auch bei mir in leichter Abwandlung (z.B. iifname statt iif) vorhanden sein. Eventuell hat sich am Ende doch irgendwo ein Fehler eingeschlichen.

define localhost_ipv4 = 127.0.0.0/8
define localhost_ipv6 = ::1/128
define ssh_port = 22
define dhcpv6_port = 546
define ovpn_port = 1194
define dns_port = 53
define http_port = 80
define https_port = 443 
define pihole_port = 67
define samba_port = 445
define xrdp_port = 3389
define ovpn_ipv4 = 10.8.0.0/24
define ovpn_ipv6 = fd00:beef:beef:beef::/64
define homebridge_ui_port = 8581

add table inet basic-filter
add chain inet basic-filter INPUT { type filter hook input priority 0; policy accept; }
add chain inet basic-filter FORWARD { type filter hook forward priority 0; policy accept; }
add chain inet basic-filter OUTPUT { type filter hook output priority 0; policy accept; }
 
add rule inet basic-filter INPUT ct state related,established counter accept
 
add rule inet basic-filter INPUT iifname "lo" counter accept  
add rule inet basic-filter INPUT iifname != "lo" ip saddr $localhost_ipv4 counter reject  
add rule inet basic-filter INPUT iifname != "lo" ip6 saddr $localhost_ipv6 counter reject  
 
add rule inet basic-filter INPUT ct state new icmp type echo-request counter accept
add rule inet basic-filter INPUT ip protocol icmp ct state related,established counter accept
 
add rule inet basic-filter INPUT ct state new icmpv6 type echo-request counter accept
add rule inet basic-filter INPUT ip6 nexthdr icmpv6 ct state related,established counter accept
 
add rule inet basic-filter INPUT ip6 nexthdr icmpv6 icmpv6 type { nd-neighbor-solicit, nd-router-advert, nd-neighbor-advert } accept
 
add rule inet basic-filter INPUT ip protocol icmp icmp type { time-exceeded, parameter-problem, destination-unreachable } accept
 
add rule inet basic-filter INPUT ip6 daddr fe80::/64 udp dport dhcpv6-client accept
 
add rule inet basic-filter INPUT ct state new,related,established tcp dport $ssh_port counter accept
 
add rule inet basic-filter INPUT ct state new udp dport $dns_port counter accept
add rule inet basic-filter INPUT ct state new tcp dport $dns_port counter accept
add rule inet basic-filter INPUT ct state new tcp dport $http_port counter accept
add rule inet basic-filter INPUT ct state new tcp dport $https_port counter accept
 
add rule inet basic-filter INPUT iifname "tun0" ct state new counter accept  
 
add rule inet basic-filter INPUT iifname "eth0" ct state new udp dport $ovpn_port counter accept  
 
add rule inet basic-filter INPUT ct state new tcp dport $pihole_port counter accept
 
add rule inet basic-filter INPUT ct state new tcp dport $samba_port counter accept
 
add rule inet basic-filter INPUT ct state new tcp dport $xrdp_port counter accept
 
add rule inet basic-filter INPUT ct state new tcp dport $homebridge_ui_port counter accept
 
add rule inet basic-filter INPUT ct state invalid counter drop
 
add rule inet basic-filter INPUT limit rate 3/minute burst 5 packets counter log prefix "nftables_INPUT_denied: "  
 
add rule inet basic-filter INPUT counter reject
 
add rule inet basic-filter FORWARD ct state related,established counter accept
 
add rule inet basic-filter FORWARD iifname "tun0" oifname "eth0" ct state new counter accept  
add rule inet basic-filter FORWARD iifname "eth0" oifname "tun0" ct state new counter accept  
add rule inet basic-filter FORWARD iifname "tun0" oifname "tun0" ct state new counter accept  
 
add rule inet basic-filter FORWARD ip6 nexthdr icmpv6 icmpv6 type { destination-unreachable, packet-too-big, time-exceeded, parameter-problem } accept
 
add rule inet basic-filter FORWARD limit rate 3/minute burst 5 packets counter log prefix "nftables_FORWARD_denied: "  
 
add rule inet basic-filter FORWARD counter reject
 
add rule inet basic-filter OUTPUT ct state new,established counter accept
 
add rule inet basic-filter OUTPUT limit rate 3/minute burst 5 packets counter log prefix "nftables_OUTPUT_denied: "  
 
add rule inet basic-filter OUTPUT counter reject
  
add table inet basic-nat
add chain inet basic-nat PREROUTING { type nat hook prerouting priority -100; policy accept; }
add chain inet basic-nat INPUT { type nat hook input priority 100; policy accept; }
add chain inet basic-nat OUTPUT { type nat hook output priority -100; policy accept; }
add chain inet basic-nat POSTROUTING { type nat hook postrouting priority 100; policy accept; }
 
add rule inet basic-nat POSTROUTING oifname "eth0" ip saddr $ovpn_ipv4 counter masquerade  
add rule inet basic-nat POSTROUTING oifname "eth0" ip6 saddr $ovpn_ipv6 counter masquerade  
aqui
aqui 11.10.2023 um 08:40:32 Uhr
Goto Top
Für feste Interfaces sollte man immer "iif" verwenden, weil das deutlich weniger Resourcen bindet! Nur für dynamische Interfaces wie die bei SSL VPN z.B. ist es besser "iifname" zu verwenden.

Hier ein vollständiger /etc/nftables.conf Ruleset mit dem es fehlerfrei rennt.
#!/usr/sbin/nft -f

flush ruleset

define pub_iface = "eth0"  
define ovpn_port = 1194

table inet drop-bad-ct-states {
	chain prerouting {
		type filter hook prerouting priority -150; policy accept;
		# drop packets in "invalid" connection-tracking state 
		ct state invalid drop
		# drop tcp packets for new connections that aren't syn packets 
		tcp flags & (fin|syn|rst|ack) != syn ct state new counter drop
		# drop XMAS packets.
		tcp flags & (fin|syn|rst|psh|ack|urg) == fin|syn|rst|psh|ack|urg counter drop
		# drop NULL packets.
		tcp flags & (fin|syn|rst|psh|ack|urg) == 0x0 counter drop
		# drop new connections over rate limit
		ct state new limit rate over 1/second burst 10 packets drop
		}
}

table inet filter {
	chain input {
		type filter hook input priority 0; policy drop;
		# Accept any localhost traffic
		iif lo accept

		# Accept any OpenVPN traffic
		iifname "tun0" accept  

		# Accept traffic self originated
		ct state established,related accept

		# Accepted ICMP types
		# ip protocol icmp icmp type {echo-request, echo-reply, time-exceeded, parameter-problem, destination-unreachable } accept
		ip protocol icmp icmp type {time-exceeded, parameter-problem, destination-unreachable } accept

		# Accept local TCP services on public interface
		# tcp dport { ssh, http, https } ct state new accept
		iif $pub_iface tcp dport { ssh } ct state new accept

		# Accepted UDP ports on public interface 
		iif $pub_iface udp dport { $ovpn_port } accept 

		# Accept neighbour discovery otherwise IPv6 connectivity breaks.
		ip6 nexthdr icmpv6 icmpv6 type { nd-neighbor-solicit, nd-router-advert, nd-neighbor-advert } accept

		counter drop
	}
	chain forward {
		type filter hook forward priority 0;
	}
	chain output {
		type filter hook output priority 0;
	}
} 
meltinsands
meltinsands 11.10.2023, aktualisiert am 15.10.2023 um 23:20:05 Uhr
Goto Top
Hallo @aqui,

leider passiert auch mit deinem Ruleset dasselbe. Die Ursache muss daher eine andere sein. Ich habe mir gerade nochmal die Verbindung vom iPhone mit IPv4 und IPv6 Conf angesehen. Bei beiden kommen die ersten 4 Zeilen, doch bei IPv6 kommen weitere TLS Fehler. Die Firewall ist für den Test nicht aktiv. Während das iPhone also trotz der Fehler die Verbindung aufbaut, bricht der Raspberry-Client ab.

Auszug auf der Log des Servers:

IPv4 & IPv6 Server.conf
IPv6 iPhone.ovpn
Wed Oct 11 18:32:59 2023 99.999.999.999:57715 TLS: Initial packet from [AF_INET6]::ffff:99.999.999.999:57715, sid=c597232a 7cff126c
Wed Oct 11 18:32:59 2023 99.999.999.999:57715 tls-crypt unwrap error: bad packet ID (may be a replay): [ #1 / time = (1697041976) Wed Oct 11 18:32:56 2023 ] -- see the man page entry for --no-replay and $
Wed Oct 11 18:32:59 2023 99.999.999.999:57715 tls-crypt unwrap error: packet replay
Wed Oct 11 18:32:59 2023 99.999.999.999:57715 TLS Error: tls-crypt unwrapping failed from [AF_INET6]::ffff:99.999.999.999:57715
…
…
Wed Oct 11 18:35:57 2023 2a02:777:777:777:4444:4444:4444:4444 TLS Error: TLS key negotiation failed to occur within 60 seconds (check your network connectivity)
Wed Oct 11 18:35:57 2023 2a02:777:777:777:4444:4444:4444:4444 TLS Error: TLS handshake failed

IPv4 & IPv6 Server.conf
IPv4 iPhone.ovpn
Wed Oct 11 18:57:24 2023 99.999.999.999:52780 TLS: Initial packet from [AF_INET6]::ffff:99.999.999.999:52780, sid=1c0b23a6 674cc3a4
Wed Oct 11 18:57:24 2023 99.999.999.999:52780 tls-crypt unwrap error: bad packet ID (may be a replay): [ #1 / time = (1697043441) Wed Oct 11 18:57:21 2023 ] -- see the man page entry for --no-replay and $
Wed Oct 11 18:57:24 2023 99.999.999.999:52780 tls-crypt unwrap error: packet replay
Wed Oct 11 18:57:24 2023 99.999.999.999:52780 TLS Error: tls-crypt unwrapping failed from [AF_INET6]::ffff:99.999.999.999:52780


Hier nochmal die Log vom PiClient mit IPv6:
UDPv6 link local: (not bound)
UDPv6 link remote: [AF_INET6]2a02:777:777:777:4444:4444:4444:4444:1194
read UDPv6 [EHOSTUNREACH|EHOSTUNREACH]: No route to host (fd=3,code=113)
read UDPv6 [EHOSTUNREACH]: No route to host (fd=3,code=113)
read UDPv6 [EHOSTUNREACH]: No route to host (fd=3,code=113)
read UDPv6 [EHOSTUNREACH]: No route to host (fd=3,code=113)
TLS Error: TLS key negotiation failed to occur within 60 seconds (check your network connectivity)
TLS Error: TLS handshake failed
SIGUSR1[soft,tls-error] received, process restarting
Restart pause, 1 second(s)
Failed to query password: Timer expired
ERROR: Failed retrieving username or password
Exiting due to fatal error
aqui
aqui 12.10.2023 um 11:40:51 Uhr
Goto Top
Das "no route to host" deutet ja auf ein Routing Problem hin. Vermutlich kann der Client das v6 Zielnetz nicht finden und scheitert deshalb am TLS Handshake. Das solltest du nochmal im ip r genau checken in der v6 Routing Tabelle.
meltinsands
meltinsands 15.10.2023, aktualisiert am 16.10.2023 um 07:49:25 Uhr
Goto Top
@aqui, nach einigem Probieren: Es liegt doch an nft, denn mit deinem Regelset klappt der Verbindungsaufbau.

Ich habe dein Set und mein Set abgeglichen:
  • Du nutzt weder OUTPUT, noch FORWARD oder NAT.
  • Die Regeln aus deiner INPUT Chain finden sich auch bei mir.
  • Ich habe Stück für Stück die Regeln deaktiviert und mich deinem Set anzunähern.
  • Stand jetzt, scheint es an der OUTPUT Chain zu liegen.

Die Verbindung funktioniert mit OUTPUT, wenn:
OUTPUT ct state untracked,new,established counter accept

Dann kann man OUTPUT aber tatsächlich leer lassen - invalid stört dann auch nicht mehr face-wink.
Kann ich untracked stärker auf OpenVPN einschränken oder hältst du es für sicher? Schließlich grenzt du OUTPUT überhaupt nicht ein.

Ich bin hier einigermaßen überrascht, dass OpenVPN bei IPv6 untracked Pakete nutzt. Weißt du hier den Hintergrund oder kannst mir allgemein etwas dazu sagen?
7907292512
7907292512 15.10.2023 aktualisiert um 23:57:25 Uhr
Goto Top
Ich bin hier einigermaßen überrascht, dass OpenVPN bei IPv6 untracked Pakete nutzt
Ganz einfach UDP ist ein stateless protocol deswegen auch kein connection state, ergo untracked 😁. Gibt bei UDP ja kein ACK der Gegenseite wie bei TCP ...
https://www.thegeeksclan.com/stateful-and-stateless-protocols/#:~:text=U ....
meltinsands
meltinsands 16.10.2023 um 07:48:26 Uhr
Goto Top
Das ist das erste "aha!". face-smile

Also nichts, was erst seit gestern so ist und dennoch hat iptables zuvor und nun auch nftbles mit IPv4 funktioniert. UDP ist ja bei beiden Protokollen stateless und ich führe es mal auf einen mir noch nicht in dem Zusammenhang bekannten Unterscheid von IPv4 und IPv6 zurück.
aqui
aqui 16.10.2023 um 10:33:14 Uhr
Goto Top
Und...die Output Chain benutzt man auch so gut wie nie. Wozu auch, denn man will ja schon von vorn herein verhindern das Pakete überhaupt in den Rechner gelangen.
Man lässt ja auch keine Einbrecher ins Haus, die dann in Ruhe alles verwüsten und erst wenn sie aus dem Haus gehen steht da die Polizei und wartet... 😉