Richten Sie Routing und Iptables für eine neue VPN-Verbindung ein, um ** nur ** die Ports 80 und 443 umzuleiten

8

Ich habe eine neue VPN-Verbindung (mit openvpn), mit der ich einige ISP-Einschränkungen umgehen kann. Während es gut funktioniert, nimmt es den gesamten Verkehr über den VPN. Dies führt zu Problemen beim Herunterladen (meine Internetverbindung ist viel schneller als der VPN zulässt) und beim Fernzugriff. Ich verwende einen SSH-Server und einen Daemon, mit dem ich Downloads über mein Telefon planen kann.

Ich habe meine bestehende Ethernet-Verbindung auf eth0 und die neue VPN-Verbindung auf tun0.

Ich glaube, ich muss die Standardroute einrichten, um meine vorhandene eth0-Verbindung im Netzwerk 192.168.0.0/24 zu verwenden, und das Standardgateway auf 192.168.0.1 einstellen (mein Wissen ist wackelig, da ich dies seit einigen Jahren nicht mehr getan habe ). Wenn das richtig ist, bin ich mir nicht ganz sicher, wie ich es machen soll!. Meine aktuelle Routing-Tabelle lautet:

Kernel IP routing table
Destination     Gateway         Genmask         Flags Metric Ref    Use Iface    MSS   Window irtt
0.0.0.0         10.51.0.169     0.0.0.0         UG    0      0        0 tun0     0     0      0
10.51.0.1       10.51.0.169     255.255.255.255 UGH   0      0        0 tun0     0     0      0
10.51.0.169     0.0.0.0         255.255.255.255 UH    0      0        0 tun0     0     0      0
85.25.147.49    192.168.0.1     255.255.255.255 UGH   0      0        0 eth0     0     0      0
169.254.0.0     0.0.0.0         255.255.0.0     U     1000   0        0 eth0     0     0      0
192.168.0.0     0.0.0.0         255.255.255.0   U     1      0        0 eth0     0     0      0

Nach dem Korrigieren des Routings muss ich iptables verwenden, um das Prerouting oder Masquerading zu konfigurieren und alles für den Zielport 80 oder 443 über tun0 zu erzwingen. Auch hier bin ich mir nicht ganz sicher, wie ich das machen soll!

Alles, was ich im Internet gefunden habe, versucht, etwas viel Komplizierteres zu tun, und der Versuch, das Holz von den Bäumen zu sortieren, erweist sich als schwierig.

Jede Hilfe wäre sehr dankbar.

AKTUALISIEREN

Bisher habe ich aus den verschiedenen Quellen Folgendes zusammengeschustert:

#!/bin/sh

DEV1=eth0
IP1=`ifconfig|perl -nE'/dr:(\S+)/&&say$1'|grep 192.`
GW1=192.168.0.1
TABLE1=internet
TABLE2=vpn
DEV2=tun0
IP2=`ifconfig|perl -nE'/dr:(\S+)/&&say$1'|grep 10.`
GW2=`route -n | grep 'UG[ \t]' | awk '{print $2}'`

ip route flush table $TABLE1
ip route flush table $TABLE2
ip route show table main | grep -Ev ^default | while read ROUTE ; do
    ip route add table $TABLE1 $ROUTE
    ip route add table $TABLE2 $ROUTE
done
ip route add table $TABLE1 $GW1 dev $DEV1 src $IP1
ip route add table $TABLE2 $GW2 dev $DEV2 src $IP2
ip route add table $TABLE1 default via $GW1
ip route add table $TABLE2 default via $GW2

echo "1" > /proc/sys/net/ipv4/ip_forward
echo "1" > /proc/sys/net/ipv4/ip_dynaddr

ip rule add from $IP1 lookup $TABLE1
ip rule add from $IP2 lookup $TABLE2
ip rule add fwmark 1 lookup $TABLE1
ip rule add fwmark 2 lookup $TABLE2

iptables -t nat -A POSTROUTING -o $DEV1 -j SNAT --to-source $IP1
iptables -t nat -A POSTROUTING -o $DEV2 -j SNAT --to-source $IP2

iptables -t nat -A PREROUTING           -m state --state ESTABLISHED,RELATED          -j CONNMARK --restore-mark
iptables        -A OUTPUT               -m state --state ESTABLISHED,RELATED          -j CONNMARK --restore-mark
iptables -t nat -A PREROUTING -i $DEV1  -m state --state NEW                          -j CONNMARK --set-mark 1
iptables -t nat -A PREROUTING -i $DEV2  -m state --state NEW                          -j CONNMARK --set-mark 2
iptables -t nat -A PREROUTING           -m connmark --mark 1                          -j MARK --set-mark 1
iptables -t nat -A PREROUTING           -m connmark --mark 2                          -j MARK --set-mark 2
iptables -t nat -A PREROUTING           -m state --state NEW -m connmark ! --mark 0   -j CONNMARK --save-mark

iptables -t mangle -A PREROUTING -i $DEV2 -m state --state NEW -p tcp --dport  80 -j CONNMARK --set-mark 2
iptables -t mangle -A PREROUTING -i $DEV2 -m state --state NEW -p tcp --dport 443 -j CONNMARK --set-mark 2

route del default
route add default gw 192.168.0.1 eth0

Nun scheint das zu funktionieren. Außer es ist nicht!

Verbindungen zu den blockierten Websites werden hergestellt , Verbindungen, die nicht an den Ports 80 und 443 angeschlossen sind, verwenden die Nicht-VPN-Verbindung.

Jedoch Port 80 und 443 Verbindungen , die nicht sind auf die gesperrten Webseiten werden mit der Nicht-VPN - Verbindung auch!

Da das allgemeine Ziel erreicht wurde, bin ich relativ glücklich, aber es wäre schön zu wissen, warum es nicht genau richtig funktioniert.

Irgendwelche Ideen?

Als Referenz habe ich jetzt 3 Routing-Tabellen, main, internet und vpn. Die Auflistung von ihnen ist wie folgt ...

Main:

default via 192.168.0.1 dev eth0 
10.38.0.1 via 10.38.0.205 dev tun0 
10.38.0.205 dev tun0  proto kernel  scope link  src 10.38.0.206 
85.removed via 192.168.0.1 dev eth0 
169.254.0.0/16 dev eth0  scope link  metric 1000 
192.168.0.0/24 dev eth0  proto kernel  scope link  src 192.168.0.73  metric 1 

Internet:

default via 192.168.0.1 dev eth0 
10.38.0.1 via 10.38.0.205 dev tun0 
10.38.0.205 dev tun0  proto kernel  scope link  src 10.38.0.206 
85.removed via 192.168.0.1 dev eth0 
169.254.0.0/16 dev eth0  scope link  metric 1000 
192.168.0.0/24 dev eth0  proto kernel  scope link  src 192.168.0.73  metric 1 
192.168.0.1 dev eth0  scope link  src 192.168.0.73

VPN:

default via 10.38.0.205 dev tun0 
10.38.0.1 via 10.38.0.205 dev tun0 
10.38.0.205 dev tun0  proto kernel  scope link  src 10.38.0.206 
85.removed via 192.168.0.1 dev eth0 
169.254.0.0/16 dev eth0  scope link  metric 1000 
192.168.0.0/24 dev eth0  proto kernel  scope link  src 192.168.0.73  metric 1
Steve
quelle
Das obige Skript funktioniert wie erwartet. Ich habe nur erwartet, dass der Verkehr von der 10. Adresse in netstat stammt. Der gesamte Datenverkehr stammt jedoch von 192. Die Ports 80 und 443 werden jedoch über VPN geleitet. Ich werde die gesamte Lösung in eine Antwort einfügen, aber an @anttir weiterleiten, um iproute2 und fwmark vorzuschlagen. Ich war nicht auf diese gestoßen, und ohne sie würde ich immer noch meinen Kopf gegen eine Mauer schlagen!
Steve

Antworten:

4

Das meiste davon ist oben, aber die gesamte Lösung war wie folgt:

Bearbeiten Sie / etc / iproute2 / rt_tables und fügen Sie unten 2 Zeilen hinzu:

101 internet
102 vpn

Sie können diesen Tabellen andere Namen geben, die sinnvoller sind. Seien Sie einfach konsistent.

Dann müssen Sie ein Skript (ich habe es rt_setup genannt) in /etc/init.d erstellen

#!/bin/sh

DEV1=eth0
IP1=`ifconfig|perl -nE'/dr:(\S+)/&&say$1'|grep 192.`
GW1=192.168.0.1
TABLE1=internet
TABLE2=vpn
DEV2=tun0
IP2=`ifconfig|perl -nE'/dr:(\S+)/&&say$1'|grep 10.`
GW2=`route -n | grep 'UG[ \t]' | awk '{print $2}'`

ip route flush table $TABLE1
ip route flush table $TABLE2
ip route show table main | grep -Ev ^default | while read ROUTE ; do
    ip route add table $TABLE1 $ROUTE
    ip route add table $TABLE2 $ROUTE
done
ip route add table $TABLE1 $GW1 dev $DEV1 src $IP1
ip route add table $TABLE2 $GW2 dev $DEV2 src $IP2
ip route add table $TABLE1 default via $GW1
ip route add table $TABLE2 default via $GW2

echo "1" > /proc/sys/net/ipv4/ip_forward
echo "1" > /proc/sys/net/ipv4/ip_dynaddr

ip rule add from $IP1 lookup $TABLE1
ip rule add from $IP2 lookup $TABLE2
ip rule add fwmark 1 lookup $TABLE1
ip rule add fwmark 2 lookup $TABLE2

iptables -t nat -A POSTROUTING -o $DEV1 -j SNAT --to-source $IP1
iptables -t nat -A POSTROUTING -o $DEV2 -j SNAT --to-source $IP2

iptables -t nat -A PREROUTING           -m state --state ESTABLISHED,RELATED          -j CONNMARK --restore-mark
iptables        -A OUTPUT               -m state --state ESTABLISHED,RELATED          -j CONNMARK --restore-mark
iptables -t nat -A PREROUTING -i $DEV1  -m state --state NEW                          -j CONNMARK --set-mark 1
iptables -t nat -A PREROUTING -i $DEV2  -m state --state NEW                          -j CONNMARK --set-mark 2
iptables -t nat -A PREROUTING           -m connmark --mark 1                          -j MARK --set-mark 1
iptables -t nat -A PREROUTING           -m connmark --mark 2                          -j MARK --set-mark 2
iptables -t nat -A PREROUTING           -m state --state NEW -m connmark ! --mark 0   -j CONNMARK --save-mark

iptables -t mangle -A PREROUTING -i $DEV2 -m state --state NEW -p tcp --dport  80 -j CONNMARK --set-mark 2
iptables -t mangle -A PREROUTING -i $DEV2 -m state --state NEW -p tcp --dport 443 -j CONNMARK --set-mark 2

route del default
route add default gw 192.168.0.1 eth0

Dann verlinke es natürlich von /etc/rc2.d (ich benutze Ubuntu, Runlevel kann für dich unterschiedlich sein). Stellen Sie sicher, dass Sie eine S-Nummer höher als den openvpn-Link eingeben!

Das Skript macht eine Reihe von Dingen. Im oberen Teil werden die Variablen mit einigen Perl- und Awk-Anweisungen eingerichtet, mit denen die dynamischen IPs und Gateway-Adressen abgerufen werden. Im zweiten Abschnitt werden die in ipruote2 eingerichteten Tabellen bereinigt und die aktuelle Routing-Tabelle in diese kopiert. Anschließend werden zwei neue Routen und zwei Standardgateways für diese erstellt, wobei die VPN-Route über das VPN und die Internet-Route über mein lokales Netzwerk erfolgt.

Ich bin nicht davon überzeugt, dass die nächsten 2 Zeilen notwendig sind, aber sie ermöglichen die IP-Weiterleitung für die Verwendung in iptables.

Als Nächstes erstellt das Skript einige Regeln, wo nach Datenverkehr gesucht werden soll, der von der entsprechenden IP-Adresse stammt, und wo gesucht werden soll, ob der Datenverkehr speziell markiert ist.

Das POSTROUTING und PREROUTING stellt sicher, dass der von einer Adresse stammende Verkehr die Antwort erhält!

Die endgültigen iptables PREROUTING sind der Teil, der den Datenverkehr markiert, und stellen sicher, dass alles, was an die Ports 80 oder 443 geht, für die Verwendung von Tabelle 2 (VPN) markiert ist.

Die letzten beiden Zeilen entfernen das VPN-Gateway aus der Standard-Routing-Tabelle und fügen mein lokales Netzwerk-Gateway wieder hinzu.

So wie es aussieht, funktioniert der Prozess hervorragend. Das VPN wird beim Hochfahren des Computers gestartet und dieses Skript wird einige Sekunden später ausgeführt (ich kann eine Sleep-Anweisung hinzufügen, um sicherzustellen, dass das VPN vollständig initialisiert ist, bevor dieses Skript ausgeführt wird). Meine Fernzugriffsverbindung (ssh usw.) funktioniert hervorragend. Meine Verbindungen, die nicht zu den Ports 80 oder 443 führen, verwenden meine lokale Verbindung, aber der gesamte Webverkehr läuft über das VPN und umgeht die von meinem ISP eingerichteten Kontrollen!

Wie ich in meinem Kommentar unter meiner Frage sagte, hätte ich ohne den Vorschlag von @anttir nicht einmal angefangen, diese Route zu betrachten. Ausgehend von diesem Vorschlag wurden die Websites http://blog.khax.net/2009/11/28/multi-gateway-routing-with-iptables-and-iproute2/ und http://linux-ip.net/ veröffentlicht. html / adv-multi-internet.html war sehr nützlich (auch wenn der Code nicht 100% vollständig ist!)

Steve
quelle
1
Eine letzte Ergänzung, ich habe ein sleep 20am Anfang des Skripts hinzugefügt, da die openvpn-Verbindung nicht rechtzeitig hergestellt wurde. Ich echo 2 > /proc/sys/net/ipv4/conf/tun0/rp_filterhabe das Skript auch hinzugefügt , da der Reverse-Packet-Filter für tun0 deaktiviert werden muss. Wenn eine Antwort von tun0 mit der Quelladresse S zurückkommt, prüft der Rückwärtspaketfilter "Wenn ich ein Paket an die Adresse S weiterleiten würde und es nicht über tun0 gehen würde, werde ich das Paket verwerfen" - und weil, wenn ich dies tue Nachschlagen gibt es kein gültiges fwmark, es bestimmt, dass die Route die übliche Standardroute ist, also verwirft es das Paket.
Steve
Ich musste Ihr Skript bearbeiten, damit es für mich funktioniert. Die letzte Linie route add default gw 192.168.0.1 eth0schien den Verkehr von Port 80/443 durch das lokale Gateway anstatt wie vorgesehen über tun0 zu leiten. Das Ändern der letzten Zeile in route add default tun0scheint den Trick für mich zu tun.
1

Das Routing pro Protokoll ist etwas kompliziert. Normalerweise wird die Routing-Tabelle verwendet, um das Gateway anhand der Ziel-IP zu überprüfen und entweder das openvpn- oder das 192.168.0.1-Standardgateway zu verwenden.

Es wäre einfacher, zB Squid http-Proxy am anderen Ende des VPN einzurichten und den Browser so einzustellen, dass er den Proxy verwendet.

Sie würden die iptables nicht verwenden, da dies die Ziel-IP der HTTP-Verbindung ändern würde und nicht funktionieren würde.

Sie können eine neue Routing-Tabelle (/ etc / iproute2 / rt_tables) erstellen, deren Standardroute auf den VPN-Endpunkt festgelegt ist. Verwenden Sie iptables fwmark (-j MARK), um alle HTTP-Pakete zu markieren, und erstellen Sie dann mithilfe der IP-Regel eine benutzerdefinierte Regel für die markierte Pakete zur Verwendung der neuen Routing-Tabelle.

Antti Rytsölä
quelle
Danke für Ihre Hilfe. Ich werde mir diese auf jeden Fall ansehen. Die Dinge sind etwas knifflig, da ich nicht die Kontrolle über das Serverende habe, sondern nur meine Seite. Außerdem kann ich Squid nicht verwenden, da ich https-Verkehr über die Verbindung leiten muss und Squid damit nicht so gut funktioniert.
Steve
Wie wäre es, wenn Sie nur ein paar IPs über das VPN und den Rest der Welt außerhalb des VPN weiterleiten?
Antti Rytsölä
Ich habe daran gedacht, nur ein paar IPs weiterzuleiten, aber die Liste ändert sich, wenn sich die Sites bewegen, und ich muss dies für andere Benutzer auf dem PC einfach zu verwenden machen. Ich habe begonnen, eine neue Routing-Tabelle einzurichten und die Pakete zu markieren. Das Markieren von Paketen war das einfache Stück, es sind die Routing-Tabellen, bei denen ich mir nicht so sicher bin. Ich kann eine für VPN einrichten, die richtig aussieht, und eine für alles andere, was richtig aussieht, aber ich bin mir nicht sicher, was ich mit main tun soll, da dies immer noch auf die Standardeinstellungen eingestellt ist (was VPN ist). Spielt immer noch ...
Steve
linux-ip.net/html/adv-multi-internet.html IP-Regel anzeigen und IP-Regel hinzufügen fwmark 4 Tabelle 4 Priorität 10000
Antti Rytsölä
Dem Original wurde ein Update hinzugefügt, das genau angibt, wo ich bisher bin! AH! Ich habe gerade festgestellt, dass ich Ihre Antwort bearbeitet habe, nicht meine Frage. Es tut uns leid! Ich habe nicht so viel benutzt und wusste nicht, dass ich die Antwort einer anderen Person bearbeiten kann!
Steve