GNU/Linux >> LINUX-Kenntnisse >  >> Linux

Linux:Routing basierend auf Domänennamen

Routing basierend auf der Zieldomäne ist nicht unmöglich und mit den richtigen Tools gar nicht so schwer.

Ich werde einige Methoden vorstellen, die wenig oder gar keine spezielle clientseitige Konfiguration erfordern. Diese gehen alle davon aus, dass Sie OpenVPN für die Verbindung verwenden. Dies sollte mit anderen VPNs möglich sein, erfordert jedoch möglicherweise mehr manuelle Konfiguration, nachdem das VPN gestartet wurde.

Als Beispiel verwende ich die Domains „example.com“, „us1.example.com“, „us2.example.com“ und „geoblocked.com“ für die Domains, die wir über das Nicht-VPN weiterleiten möchten Schnittstelle.

Alle Befehle sollten als root ausgeführt werden.

Methode 1 – OpenVPN

Ich würde dies nur empfehlen, wenn Sie sicher sind, dass die IP-Adressen, die Sie weiterleiten, statische IPs haben, die sich nie ändern.

Vorteile:

  • Extrem einfach

Nachteile:

  • Nur zuverlässig für Domains mit IPs, die nie ändern
  • Benötigen Sie einen expliziten Eintrag für jede Domain und Subdomain

Methode:

Fügen Sie Ihrer OpenVPN-Konfiguration die folgenden Zeilen hinzu:

route example.com     255.255.255.255 net_gateway
route us1.example.com 255.255.255.255 net_gateway
route us2.example.com 255.255.255.255 net_gateway
route geoblocked.com  255.255.255.255 net_gateway

Starten Sie OpenVPN neu.

Das ist es, aber Sie müssen VPN erneut neu starten, wenn sich diese IP-Adressen jemals ändern.

HINWEIS :Einige Quellen sagen, dass Sie auch allow-pull-fqdn angeben müssen , aber das scheint meiner Erfahrung nach nicht der Fall zu sein. YMMV.

Methode 2 - Richtlinienbasiertes Routing

Richtlinienbasiertes Routing ist die Fähigkeit, basierend auf bestimmten Kriterien zu routen; normalerweise eine Quelladresse oder ein Protokoll, aber in diesem Fall prüfen wir den Zieldomänennamen vor dem Routing und verwenden markierte Pakete ("fwmark").

Also müssen wir zuerst eine separate Tabelle für Ihre VPN-Routing-Pakete erstellen, damit wir diejenigen markieren können, die durch das VPN gehen, und markierte Pakete durch die Nicht-VPN-Schnittstelle leiten. (Denken Sie daran, dass dies ein Ansatz ist und es viele andere Möglichkeiten gibt, wie Sie das VPN wie gewohnt über die Haupttabelle weiterleiten lassen und eine separate Tabelle für Nicht-VPN-Verkehr erstellen.)

Ihr Kernel muss aktuell genug sein und die richtigen Module haben, obwohl moderne Systeme sie wahrscheinlich in ihren Standardkerneln haben.

Der Name „vpn_table“ (Routing-Tabellenname) und die Nummern „201“ (Routing-Tabellen-ID) und „3“ (fwmark) sind willkürlich gewählt.

Erstellen Sie die neue Routing-Tabelle (als root):

echo 201 vpn_table >> /etc/iproute2/rt_tables

OpenVPN konfigurieren:

Erstellen Sie irgendwo das folgende Skript (ich nenne es "/etc/openvpn/client/setup-routing") und machen Sie es ausführbar:

#!/bin/bash
ip route add 0.0.0.0/1 via $route_vpn_gateway dev $dev scope global table vpn_table
ip route add 128.0.0.0/1 via $route_vpn_gateway dev $dev scope global table vpn_table
sysctl -w net.ipv4.conf.$dev.rp_filter=2

# You can optionally leave the next two lines out but run the `ip rule add`
# command at each boot instead
ip rule del fwmark 3 table vpn_table &>/dev/null # This might fail but that's ok
ip rule add fwmark 3 table vpn_table

Die Variablen im obigen Skript werden von OpenVPN als Umgebungsvariablen ausgefüllt. Beachten Sie auch, dass dies das Routing zu all einrichtet Adressen durch das VPN-Gateway in der Routing-Tabelle „vpn_table“. Wenn Ihre VPN-Einrichtung ein komplexeres Routing erfordert, lesen Sie die OpenVPN-Dokumentation und passen Sie sie entsprechend an.

Fügen Sie Folgendes zu Ihrer OpenVPN-Konfiguration hinzu:

## Policy routing
route-noexec
script-security 2
route-up /etc/openvpn/client/setup-routing

Die „route-noexec“-Zeile erlaubt OpenVPN, die Route vom Server zu holen, verhindert aber, dass es die Routen tatsächlich füllt. Stattdessen wird das route-up-Skript aufgerufen. "script-security 2" ist notwendig, um ein benutzerdefiniertes Skript aufzurufen.

Das ist alles, was zum Weiterleiten der markierten Pakete erforderlich ist, aber wir müssen einen Weg finden, um die Pakete tatsächlich zu markieren. Zwei Optionen sind die Verwendung von dnsmasq mit ipset oder die Einrichtung eines Squid-Proxys.

Methode 2a - Richtlinienbasiertes Routing mit ipset und dnsmasq

Ich würde diese Methode empfehlen, wenn Sie diese bereits auf einem dnsmasq-basierten Router ausführen oder Ihre Clients keine Proxy-Konfiguration unterstützen. Dies ist praktisch dasselbe wie ein Caching-DNS, das die Routing-Tabelle aktualisiert, wenn ein Domänenname nachgeschlagen wird.

Vorteile:

  • Verarbeitet Subdomains
  • Funktioniert auf Geräten, die nicht auf Proxys zugreifen können (gibt es solche?)

Nachteile:

  • Verarbeitet das Referrer-Feld nicht (siehe Methode 2b)
  • Benötigt komplizierte ipset- und iptables-Konfigurationen
  • Erfordert, dass das mit VPN verbundene System als Router eingerichtet wird (benötigt eine dedizierte Schnittstelle)
  • Ich habe keine Ahnung, wie skalierbar ipset ist (mein Anwendungsfall ist für eine ganze ccTLD)

Dies setzt voraus, dass Sie dnsmasq bereits konfiguriert und eingerichtet haben und als Gateway und DNS-Server für Clients fungieren, die mit einer dedizierten Schnittstelle „eth1“ verbunden sind.

Erstellen Sie das ipset:

ipset create SKIP_VPN_IPSET iphash

Sagen Sie iptables, dass es die ipset-Pakete markieren soll (n.b., das muss nach erfolgen Erstellung der ipset-Liste):

# Mark ALL packets coming in on eth1 - change this to the interface dnsmasq listens on
iptables -A PREROUTING -i eth1 -t mangle -j MARK --set-mark 3

# REMOVE mark on any addresses that match our ipset
iptables -A PREROUTING -t mangle -m set --match-set SKIP_VPN_IPSET dst -j MARK --set-mark 0/3

HINWEIS :Die obigen Befehle (ipset und iptables ) muss bei jedem Start ausgeführt werden. Alternativ bietet Ihr Betriebssystem möglicherweise einige Optionen zum Speichern/Wiederherstellen von iptable-Regeln und ipsets.

HINWEIS2 :Es ist ein inverser ! --match-set dokumentiert aber das führte dazu, dass alle Pakete einfach verschwanden, als ich es versuchte.

Fügen Sie Folgendes zu Ihrer dnsmasq.conf hinzu:

ipset=/example.com/geoblocked.com/SKIP_VPN_IPSET

Passen Sie natürlich auch diese Zeile an die Domainnamen an, die Sie weiterleiten möchten. Dadurch wird auch ALLE hinzugefügt Unterdomänen zum ipset, sodass Sie sie nicht explizit angeben müssen. Auch die Verwendung einer TLD funktioniert.

Starten Sie dnsmasq neu und richten Sie Ihre Clients so ein, dass sie das mit VPN verbundene System sowohl als Gateway als auch als DNS verwenden (was impliziert sein sollte, wenn es als DHCP-Server eingerichtet ist).

Methode 2b - Richtlinienbasiertes Routing mit Squid

Dies ist meine bevorzugte Methode und funktioniert gut mit meiner PS4 und anderen Geräten, die ich zum Verbinden verwende.

Vorteile:

  • Verarbeitet Subdomains
  • Verarbeitet das Referrer-Feld
  • Erfordert keinen Austausch Ihres vorhandenen Routers
  • Clients (Browser) können es wahlweise verwenden oder nicht

Nachteile:

  • Clients müssen Proxy-Verbindungen unterstützen

Dies setzt voraus, dass Sie über ein funktionierendes Squid-Setup und grundlegende Kenntnisse der Squid-Konfiguration verfügen.

Fügen Sie der squid.conf die folgenden Zeilen hinzu:

# redirect example domains
acl domain_to_remote_proxy dstdomain .example.com
acl ref_to_remote_proxy referer_regex [^.]*\.example.com.*

# redirect geoblocked domain
acl domain_to_remote_proxy dstdomain .geoblocked.com
acl ref_to_remote_proxy referer_regex [^.]*\.geoblocked.com.*

# mark packets that we want routed through the VPN
tcp_outgoing_mark 0x03 !ref_to_remote_proxy !domain_to_remote_proxy

Beachten Sie, dass es 2 Zeilen pro Domain gibt und Subdomains abgeglichen werden. Die erste Zeile prüft die Zieldomain, die zweite gleicht den „Referer“-Header ab. Dies ist nützlich, da Browser den Referrer senden, wenn sie Inhalte auf einer Webseite abrufen, z. B. Bilder, CSS oder Javascript. Das bedeutet, dass von der Website angeforderte Inhalte auch über die Nicht-VPN-Adresse geleitet werden, selbst wenn sie auf einer anderen Domain gehostet werden (z. B. example-cdn.com).

Richten Sie auf den Clients die Verbindung wie gewohnt ein, aber stellen Sie die Proxy-Einstellungen so ein, dass der Proxy-Server und der Port für dieses System verwendet werden. Die meisten Geräte (einschließlich Spielekonsolen) ermöglichen eine systemweite Konfiguration. Auf PCs können die meisten Browser so konfiguriert werden, dass sie unabhängig von den Systemeinstellungen einen Proxy verwenden.

Schlussbemerkung – Mein Anwendungsfall besteht darin, bestimmte Domänen durch das VPN und alles andere durch das Nicht-VPN zu leiten. Die Methoden sind ähnlich wie oben, aber invertiert.


Ich würde Ihnen empfehlen, das Routing auf der Grundlage von Domainnamen zu vermeiden (übrigens ist es auch unmöglich, Wildcard-Subdomains aufzulösen, ob es Bonuspunkte dafür gibt oder nicht :D)

Um ein bisschen beschreibend zu sein, sollten Sie das nicht tun, weil:

1) Einige Domains ändern von Zeit zu Zeit ihre IPs,

2) Es ist unmöglich, Wildcards in Subdomains abzugleichen

3) Es ist unmöglich, alle Subdomains einer Domain zu kennen/abzurufen

4) Jede zufällige Subdomain kann jede zufällige IP-Adresse haben.

Daher ist die Lösung als Browser-Addon (und/oder benutzerdefinierter lokaler Proxy wie Squid) die beste Option für Ihr Problem.

Aber ich denke, das "FoxyProxy"-Addon (es ist ursprünglich ein Firefox-Addon, aber AFAIRC, es ist auch eine Chrome-Version vorhanden) ist genau das, was Sie wollen.

Und auch als Antwort auf Ihre Mitteilung, dass „FoxyProxy ein kostenpflichtiger Dienst ist und Sie Ihr VPN bereits haben“:

FoxyProxyPlus ist ein kostenpflichtiger Dienst, aber nicht FoxyProxy.

FoxyProxy ist ein Addon, verfügbar für die wichtigsten Browser:

Standardausgabe (Firefox) | Basisversion (Firefox)

Standard Edition (Chrom{e,ium}) | Basic Edition (Chrom{e,ium})

Wenn Sie also über VPN zu einigen Domains gehen möchten, sollten Sie:

1) Schreiben Sie Regeln für foxyproxy, um Ihre Squid-Instanz für die Liste der Domänen zu durchlaufen

2) und/oder schreibe die Regelliste für Squid

3) http/https-Traffic erfassen nicht im Besitz von squid mit iptables und richten Sie es nach folgender Regel auf squid aus:

iptables -m owner -m multiport -t nat -A OUTPUT ! -o lo ! --uid-owner $squid_user_id -p tcp --dports 80,443,8080,... -j REDIRECT --to-ports $SQUID_PORT

(--syn Option kann für -p tcp benötigt werden)

4) http/https-Traffic im Eigentum erfassen von Squid, und markieren Sie es für das nächste Routing an VPN mit einer Regel wie dieser:

iptables -A OUTPUT -m owner --uid-owner $squid_user_id -j MARK --set-mark 11

5)

echo 11 forcevpn >> /etc/iproute2/rt_tables
ip rule add fwmark 11 table forcevpn
ip route add default via 10.0.0.1 table forcevpn

wobei 10.0.0.1 ist Ihr Gateway innerhalb von VPN. Oder Sie können dev $VPN_IF verwenden statt via 10.0.0.1 wenn Sie kein Gateway haben und nur den gesamten Datenverkehr in die VPN-Schnittstelle schieben möchten.

6) Optional müssen Sie möglicherweise sudo sysctl ipv4.conf.all.rp_filter =0 ausführen

===

Und noch was:

Wenn Sie dieselbe Magie mit Nicht-http(s)-TCP-Traffic ausführen möchten, benötigen Sie so etwas wie Proxychains und führen eine ähnliche Erfassungsmagie durch.

Und wenn Sie diese Magie mit UDP ausführen möchten, habe ich eine schlechte Nachricht:Ich kenne keinen Proxy, der UDP als Proxy verwenden kann (aufgrund der Natur dieses Protokolls) :)

⇓⇓⇓ BEARBEITEN ⇓⇓⇓

Falls Sie das Gegenteil wollen (standardmäßig gw =vpn und einige Domains direkt über ISP regieren), kann es sein:

1) Schreiben Sie Regeln für foxyproxy, um Ihre Squid-Instanz für die Liste der Domänen zu durchlaufen

2) Traffic erfassen im Besitz von Squid, und markieren Sie es für das nächste Routing auf andere Weise mit einer Regel wie dieser:

iptables -A OUTPUT -m owner --uid-owner $squid_user_id -j MARK --set-mark 11

3)

echo 11 novpn >> /etc/iproute2/rt_tables
ip rule add fwmark 11 table novpn
ip route add default via ${ISP_GW} table novpn

wobei ISP_GW ist das Gateway, das Sie verwenden, um den Datenverkehr an Ihren VPN-Server weiterzuleiten. Einige Benutzer möchten vielleicht dev ppp0 verwenden (oder ppp1 , ..., pppN ) statt via ${ISP_GW} für den Fall, dass sie pptp verwenden, um sich mit dem Internet zu verbinden.


Linux
  1. Linux – Routing über Iptables?

  2. So zeigen Sie die Routing-Tabelle in Linux an

  3. Linux Monitornamen abrufen

  4. Linux-Routing-Fehler?

  5. Längenbeschränkungen für Dateinamen unter Linux?

Beste Linux-Distributionen basierend auf KDE

So finden Sie Dateien anhand ihrer Berechtigungen in Linux

Host-Befehl unter Linux

So finden Sie Dateien basierend auf dem Zeitstempel in Linux

Die 5 besten auf Arch Linux basierenden Linux-Distributionen

route-Befehlsbeispiele in Linux