Auf OpenVPN-Richtlinien basierendes Routing funktioniert nicht richtig

0

Ich versuche, einen OpenVPN-Client unter ArchLinux mit PrivateInternetAccess einzurichten. Standardmäßig pusht PIA Routen so, dass der gesamte Datenverkehr über das VPN geleitet wird. Ich möchte nur, dass einige Anwendungen das VPN verwenden.

Dazu verwende ich "richtlinienbasiertes Routing". Ich habe eine neue Routingtabelle mit dem Namen "vpn" erstellt und werde Benutzer selektiv an diese Routingtabelle senden.

Nach diesen Befehlen wird der Benutzer "media" an die Routingtabelle "vpn" weitergeleitet:

$ echo 100 vpn >> /etc/iproute2/rt_tables
$ iptables -t mangle -I OUTPUT -m owner --uid-owner media -j MARK --set-mark 0x1
$ ip rule add fwmark 0x1 table vpn

Ich habe außerdem meine OpenVPN-Client-Konfiguration so geändert, dass meine Routing-Tabellen korrekt ausgefüllt werden:

$ cat /etc/openvpn/client.conf
    client
    dev tun
    proto udp
    remote us-newyorkcity.privateinternetaccess.com 1194
    resolv-retry infinite
    nobind
    persist-key
    persist-tun
    ca /etc/openvpn/ca.crt
    tls-client
    remote-cert-tls server
    auth-user-pass /etc/openvpn/login.conf
    comp-lzo
    verb 1
    reneg-sec 0
    crl-verify /etc/openvpn/crl.pem

    # This will override PIA so that traffic will route through our normal gateway
    route 0.0.0.0 192.0.0.0 net_gateway
    route 64.0.0.0 192.0.0.0 net_gateway
    route 128.0.0.0 192.0.0.0 net_gateway
    route 192.0.0.0 192.0.0.0 net_gateway

    # Calling these scripts will add the PIA routes to the vpn table
    script-security 2
    up /etc/openvpn/up.sh
    down /etc/openvpn/down.sh

$ cat /etc/openvpn/up.sh
    #!/bin/sh
    ip route add table vpn default via $ifconfig_remote

$ cat /etc/openvpn/down.sh
    #!/bin/sh
    ip route flush table vpn

Hier sind meine Routing-Tabellen nach dem Ausführen openvpn /etc/openvpn/client.conf:

$ ip route show table main
    0.0.0.0/2 via 192.168.1.1 dev eth0
    0.0.0.0/1 via 10.197.1.5 dev tun0
    default via 192.168.1.1 dev eth0  src 192.168.1.124  metric 202
    10.197.1.1 via 10.197.1.5 dev tun0
    10.197.1.5 dev tun0  proto kernel  scope link  src 10.197.1.6
    64.0.0.0/2 via 192.168.1.1 dev eth0
    128.0.0.0/2 via 192.168.1.1 dev eth0
    128.0.0.0/1 via 10.197.1.5 dev tun0
    192.0.0.0/2 via 192.168.1.1 dev eth0
    192.168.1.0/24 dev eth0  proto kernel  scope link  src 192.168.1.124  metric 202
    209.95.50.86 via 192.168.1.1 dev eth0

$ ip route show table vpn
    default via 10.197.1.5 dev tun0

Die Dinge laufen normal als Benutzer, der NICHT an die "vpn" -Tabelle weitergeleitet wird:

$ whoami
    jordan

$ ping -c 2 8.8.8.8
    PING 8.8.8.8 (8.8.8.8) 56(84) bytes of data.
    64 bytes from 8.8.8.8: icmp_seq=1 ttl=46 time=38.9 ms
    64 bytes from 8.8.8.8: icmp_seq=2 ttl=46 time=39.0 ms

    --- 8.8.8.8 ping statistics ---
    2 packets transmitted, 2 received, 0% packet loss, time 1001ms
    rtt min/avg/max/mdev = 38.952/38.999/39.047/0.203 ms

Für einen Benutzer, der an die "vpn" -Tabelle weitergeleitet wird, treten jedoch Fehler auf:

$ whoami
media

$ ping -c 2 8.8.8.8
    PING 8.8.8.8 (8.8.8.8) 56(84) bytes of data.

    --- 8.8.8.8 ping statistics ---
    2 packets transmitted, 0 received, 100% packet loss, time 999ms

Ich warf einen Blick darauf tcpdump -i tun0, was los ist. Es scheint, dass ICMP-Anfragen über tun0 ausgehen, aber nicht zurückkommen ?

$ tcpdump -i tun0
    listening on tun0, link-type RAW (Raw IP), capture size 262144 bytes
    15:37:30.134399 IP keep > google-public-dns-a.google.com: ICMP echo request, id 10256, seq 1, length 64
    15:37:31.143217 IP keep > google-public-dns-a.google.com: ICMP echo request, id 10256, seq 2, length 64

Gedanken? :(

==== EDIT # 1 ====

Wenn wir zur Überprüfung der Integrität den gesamten Datenverkehr über das VPN senden (indem wir die Zeilen "route xxxx 192.0.0.0 net_gateway" in /etc/openvpn/client.conf entfernen), erhalten wir einwandfreie ICMP-Antworten:

$ tcpdump -i tun0
    listening on tun0, link-type RAW (Raw IP), capture size 262144 bytes
    16:26:54.401732 IP keep > google-public-dns-a.google.com: ICMP echo request, id 10480, seq 1, length 64
    16:26:54.483122 IP google-public-dns-a.google.com > keep: ICMP echo reply, id 10480, seq 1, length 64
    16:26:55.403465 IP keep > google-public-dns-a.google.com: ICMP echo request, id 10480, seq 2, length 64
    16:26:55.485068 IP google-public-dns-a.google.com > keep: ICMP echo reply, id 10480, seq 2, length 64

==== EDIT # 2 ====

Nach dem Rat von MariusMatutiae habe ich versucht, --route-noexecdie Routen mithilfe der Flagge manuell selbst festzulegen /etc/openvpn/up.sh. Wir deaktivieren auch die Rückwärtspfadfilterung in /etc/openvpn/up.shund aktivieren sie wieder in /etc/openvpn/down.sh:

$ cat /etc/openvpn/up.sh
    #!/bin/sh
    ip route add table vpn 0.0.0.0/1 via $ifconfig_remote
    ip route add table vpn 128.0.0.0/1 via $ifconfig_remote
    ip route add table vpn $route_network_1 via $ifconfig_remote
    ip route add table vpn $trusted_ip via $route_net_gateway

    ip route add table vpn $ifconfig_remote dev tun0 proto kernel src $ifconfig_local
    ip route add table vpn 192.168.1.0/24 dev eth0 proto kernel src 192.168.1.124 metric 202

    ip route del table main $ifconfig_remote

    # Disable reverse path filtering
    for f in /proc/sys/net/ipv4/conf/*/rp_filter; do
            echo 0 > $f;
    done

$ cat /etc/openvpn/down.sh
    #!/bin/sh
    ip route flush table vpn

    # Re-enable reverse path filtering
    for f in /proc/sys/net/ipv4/conf/*/rp_filter; do
            echo 1 > $f;
    done

Danach sehen meine Routingtabellen so aus:

$ ip route show table main
    default via 192.168.1.1 dev eth0  src 192.168.1.124  metric 202
    192.168.1.0/24 dev eth0  proto kernel  scope link  src 192.168.1.124  metric 202

$ ip route show table vpn
    0.0.0.0/1 via 10.173.1.5 dev tun0
    10.173.1.1 via 10.173.1.5 dev tun0
    10.173.1.5 dev tun0  proto kernel  scope link  src 10.173.1.6
    128.0.0.0/1 via 10.173.1.5 dev tun0
    192.168.1.0/24 dev eth0  proto kernel  scope link  src 192.168.1.124  metric 202
    209.95.50.133 via 192.168.1.1 dev eth0

Benutzer "Medien" ist jedoch weiterhin nicht in der Lage ping 8.8.8.8. tcpdump -i tun0meldet immer noch, dass keine Antworten zurückkommen :(

user1161657
quelle
Sie müssen die umgekehrte Pfadfilterung im Kernel blockieren: Fügen Sie diese Zeile for f in /proc/sys/net/ipv4/conf/*/rp_filter; do echo 0 > $f; doneIhrer up.shDatei und for f in /proc/sys/net/ipv4/conf/*/rp_filter; do echo 1 > $f; doneIhrer down.shDatei hinzu.
MariusMatutiae
Hey MariusMatutiae, vielen Dank für die Hilfe! Ich habe "Edit # 2" mit Ihrem Vorschlag aktualisiert. Ich habe auch überprüft, ob zwischen den Läufen rp_filterdie Einstellungen korrekt waren for f in /proc/sys/net/ipv4/conf/*/rp_filter; do cat $f; done. Trotz dieser Änderungen ist der Benutzer "media" immer noch nicht in der Lage ping 8.8.8.8:(
user1161657 06.04.16
Mir ist komisch, dass alles funktioniert, wenn der gesamte Datenverkehr über das VPN geleitet wird. Nur wenn ich einige Benutzer an eine andere Routing-Tabelle sende, wird es merkwürdig.
user1161657
Ich habe genau die Kombination ausprobiert, die Sie haben. Sie funktioniert bei mir perfekt, wenn sie rp_filterdeaktiviert ist, es sei denn, ich habe sie im Einzelbenutzermodus ausprobiert. Zum Beispiel mit ping -I tun0 8.8.8.8, oder ssh -b 10.197.1.6 me@remoteserver. Können Sie dies auf Ihrem System überprüfen?
MariusMatutiae
Hey MariusMatutiae, ich habe ping -I tun0 8.8.8.8als Benutzer "jordan" mit der gesamten Konfiguration aus "Edit # 2" getestet . Es funktioniert, aber es tun0tcpdump -i tun0
leitet

Antworten:

1

Sie haben Ihre Routen durch Ihre beiden Routingtabellen falsch partitioniert. Die folgenden in der mainTabelle aufgeführten Routen gehören zur vpnTabelle:

0.0.0.0/1 via 10.197.1.5 dev tun0
128.0.0.0/1 via 10.197.1.5 dev tun0
10.197.1.1 via 10.197.1.5 dev tun0     
10.197.1.5 dev tun0  proto kernel  scope link  src 10.197.1.6
209.95.50.86 via 192.168.1.1 dev eth0

Die folgende Route gehört zu beiden Tabellen:

192.168.1.0/24 dev eth0  proto kernel  scope link  src 192.168.1.124  metric 202

Der Grund dafür ist folgender: Die ersten vier Regeln betreffen die Schnittstelle tun0, die von OpenVPN aufgerufene virtuelle Netzwerkkarte, die eindeutig nichts mit der mainTabelle zu tun hat . Die fünfte Regel bringt Ihrem Kernel bei, wie Sie Ihren PIA-Server erreichen. Die letzte Regel ermöglicht beiden Tabellen den Zugriff auf lokale PCs, z. B. Drucker, NAS usw.

Die automatische Einrichtung wird dadurch etwas komplexer, dass Ihr OpenVPN-Server Ihnen möglicherweise eine tun0IP-Adresse zuweist, die sich jedes Mal ändert: Da Sie den Server nicht steuern, können Sie ihn möglicherweise nicht so konfigurieren, dass er Ihrer tun0Schnittstelle a zugewiesen wird statische Adresse.

Sie müssen also zunächst lernen, die Option zu verwenden --route-no-exec. Das Handbuch besagt:

--route-no-exec

Routen nicht automatisch hinzufügen oder entfernen. Übergeben Sie stattdessen Routen mit Umgebungsvariablen an das Skript --route-up.

Dann sollten Sie lernen, wie man Umgebungsvariablen verwendet (es gibt einen ganzen Abschnitt am Ende des Handbuchs, der oben verlinkt ist), insbesondere solche, die ifconfig--etwas heißen .

Außerdem müssen Sie die Rückwärtspfadfilterung durch den Kernel deaktivieren.

for f in /proc/sys/net/ipv4/conf/*/rp_filter; do echo 0 > $f; done

Ich würde diesen Befehl in Ihr upSkript einfügen und den umgekehrten

for f in /proc/sys/net/ipv4/conf/*/rp_filter; do echo 1 > $f; done

in Ihrem downSkript. Dies ist erforderlich, da Sie ein Standard-Gateway in der Haupttabelle haben. Wenn der Kernel prüft, ob es Spoofing gibt, wird jedes Paket markiert.

Alternativ und einfacher können Sie in Betracht ziehen, die Rolle der beiden Tabellen zu wechseln: Lassen Sie OpenVPN seine Aufgabe automatisch erledigen und richten Sie die Routen für die mainRoutingtabelle ein und richten Sie eine neue Routingtabelle mit non-vpnder üblichen Konfiguration ein.

# ip route show
  default via 192.168.0.1 dev eth0  proto static 
  192.168.0.0/24 dev eth0  proto kernel  scope link  src 192.168.0.74  metric 1 

(oder so ähnlich) für die Pakete, die nicht mit der obigen MARK übereinstimmen. Dies ist viel einfacher einzurichten.

MariusMatutiae
quelle
Danke für die Hilfe! Ich nahm Ihren Vorschlag an und benutzte die --route-noexecFlagge, um die Routen in meiner up.shDatei manuell zu aktualisieren . Ich bin jedoch immer noch nicht in ping 8.8.8.8der Lage, vom mediaBenutzer. Ich werde den Beitrag mit weiteren Informationen aktualisieren.
user1161657