Dynamisches Routing (insbesondere BGP) über den OpenVPN-Tunnel unter Linux (und wahrscheinlich * BSD) einrichten

Warum und worum geht es in diesem Artikel?


Wenn Sie zum Thema "openvpn bgp" googeln, finden Sie mehrere interessante und nützliche Artikel aus praktischer Sicht (zum Beispiel ein- oder zweimal ). Aber als ich anfing, das Problem in der Überschrift zu lösen, habe ich mich aus vielen Gründen nicht einmal darum gekümmert, es zu googeln. Die Idee kam irgendwie von selbst während einer langen Arbeit mit OpenVPN im Allgemeinen (im Rahmen ganz typischer Aufgaben, mit einem festen Satz von Netzwerken auf beiden Seiten), der Arbeit mit der OpenVPN-Implementierung auf MikroTiks RouterOS-System und dem Verbinden der Linux- und RouterOS-Systeme miteinander. Als wir die Gründe für das Schreiben unserer eigenen Implementierung von OpenVPN in RouterOS erkannten, kam tatsächlich die Erkenntnis, wie dieses Problem im Rahmen der voll besetzten OpenVPN-Edition gelöst werden kann. Dann gab es eine kurze experimentelle Überprüfung, die die volle Leistungsfähigkeit der Idee und die Einführung dieser Lösung in den „industriellen“ Betrieb zeigte.


In Anbetracht der Tatsache, dass diese Situation für verschiedene Anwendungen recht typisch ist und die unten beschriebene Lösung noch nicht vorgestellt wurde, habe ich beschlossen, die Idee mit der Community zu teilen.



Die Essenz des Problems ("Wer ist schuld?")


Was ist der Unterschied zwischen der regulären Version von OpenVPN und der in RouterOS implementierten? Es gibt wahrscheinlich ein paar Unterschiede, aber in diesem Artikel werden wir nur eines betrachten: Das reguläre OpenVPN in anderen Systemen als RouterOS (und möglicherweise einigen anderen) ist ein Mähdrescher, der den Transportteil enthält (dh die Paketübertragung selbst, es wird auch weitergeleitet, es ist auch eine Datenebene) ) und Routing (dh Informationen über Routen austauschen, es ist Routing, es ist auch eine Steuerebene), und in RouterOS ist der OpenVPN-Dienst nur für den Transportteil verantwortlich , und das Routing wird von einem anderen Systemprozess ausgeführt, der es einerseits ermöglicht, die Funktionalität des Routings unter nicht zu duplizieren System (und darüber hinaus nicht mehrere identische Routentabellen in verschiedenen Diensten zu halten und ständig miteinander zu synchronisieren) und andererseits die transparente Übertragung von Routentabellen über solche Fahrzeuge und das Ändern von Routentabellen auf beiden Seiten im laufenden Betrieb zu ermöglichen.


Darüber hinaus hat die reguläre Implementierung von OpenVPN einen weiteren Nachteil: Die Übertragung von Routen erfolgt nur in einer Richtung (vom Server zum Client) und nur zum Zeitpunkt des Aufbaus einer Sitzung (d. H. Beim Erhöhen des Tunnels). Es gibt keine normale Möglichkeit, während des Tunnelbetriebs unterwegs eine Route zur internen OpenVPN-Routentabelle hinzuzufügen und Routen von einer Seite zur anderen zu übertragen. Darüber hinaus ist es nicht einmal möglich, die Routentabelle selbst abzurufen.


Lösung des Problems ("Was ist zu tun?")


Bei der Analyse meiner Skripte, die die Zuordnung von Routen zu verschiedenen Clients automatisieren, stellte ich fest, dass OpenVPN über zwei verschiedene Optionen verfügt, mit denen Routen angegeben werden:


  • i route - Legt die Routen in der Routing-Tabelle des OpenVPN-Prozesses fest.
  • route - Legt die Routen fest, die der OpenVPN-Prozess an die Systemroutentabelle übergibt (dh, er fügt der Tabelle Routen über die Tunnelschnittstelle hinzu, wenn eine Verbindung besteht, und löscht sie, wenn die Verbindung getrennt wird).

Die naheliegende Frage stellte sich: Was passiert, wenn i route Route 0.0.0.0/0 auf beiden Seiten mit i route hinzufüge und dann die erforderlichen Routen (einschließlich der dynamisch angezeigten oder verschwindenden) auf der Tunnelschnittstelle selbst hinzufüge oder entferne, z. B. mit einem Routing-Dienst ( geroutet, Zebra / Quagga, Vogel usw.)?


Das Experiment hat gezeigt, dass ein solches Schema tatsächlich mit einer geringfügigen Einschränkung verbunden ist: Es kann nur ein Client mit einem Servertunnel verbunden werden. Der Rest der Schaltung erwies sich als voll funktionsfähig.


Das Schema wird im TLS-over-TCP-Modus ausgeführt. Für die Konfiguration müssen Sie also zuerst SSL-Schlüssel und -Zertifikate generieren.


Im Folgenden gebe ich ein Beispiel für eine OpenVPN-Konfiguration für die Server- und Client-Seite.


Serverseitige Konfiguration (eine für jeden Client).


server_dyn_rt.conf Datei (serverseitig)


 daemon compress ping-timer-rem persist-tun persist-key tls-server proto tcp-server topology net30 mode server script-security 3 keepalive 15 45 tun-mtu 1500 remote-cert-tls client verify-x509-name <CLIENT_DISTINGUISHED_NAME> name auth <TLS_AUTH_ALGORITHM> cipher <CIPHER_ALGORITHM> local <SERVER_PUBLIC_IP> lport <SERVER_PUBLIC_PORT> dev-type tun dev <TUNNEL_INTERFACE_NAME> ifconfig <TUNNEL_SERVER_SIDE_IP> <TUNNEL_CLIENT_SIDE_IP> client-connect client_connect.sh push "route-gateway <TUNNEL_SERVER_SIDE_IP>" push "topology net30" push&nbsp"persist-tun" push&nbsp"persist-key" <dh> ... Diffie-Hellman data <</dh> <ca> ... Certificate Authority certificate data </ca> <cert> ... Server certificate data </cert> <key> ... Server Private Key data </key> 

Datei client_connect.sh (serverseitig)


 #!/bin/sh echo 'ifconfig-push TUNNEL_CLIENT_SIDE_IP TUNNEL_SERVER_SIDE_IP' >> ${1} echo 'push "iroute 0.0.0.0 0.0.0.0"' >> ${1} echo 'iroute 0.0.0.0 0.0.0.0' >> ${1} exit 0 

client_dyn_rt.conf Datei (clientseitig)


 daemon compress tls-client auth <TLS_AUTH_ALGORITHM> cipher <CIPHER_ALGORITHM> client dev-type tun dev <TUNNEL_INTERFACE_NAME> script-security 3 remote-cert-tls server verify-x509-name <SERVER_DISTINGUISHED_NAME> name remote <SERVER_PUBLIC_IP> <SERVER_PUBLIC_PORT> tcp <ca> ... Certificate Authority certificate data </ca> <cert> ... Client certificate data </cert> <key> ... Client Private Key data </key> 

Ich zitiere die Einstellungen von Paketen und Routing-Protokollen weder wegen der Vielzahl von Paketen noch wegen der Vielzahl von Einstellungen selbst (tatsächlich können Sie als Quelle für Konfigurationsbeispiele den zweiten Artikel verwenden, zu dem die Links am Anfang des Artikels angegeben sind). Ich möchte nur darauf hinweisen, dass Sie mit der obigen Einstellung insbesondere BGP verwenden können (was mir persönlich sowohl wegen seiner "Steuerbarkeit" als auch wegen der Möglichkeit, Routen verschiedener Protokolle innerhalb derselben Sitzung zu übertragen, gefällt). Bei BGP sollte die Adresse <TUNNEL_CLIENT_SIDE_IP> als Adresse des Nachbarn auf der "Server" -Seite und die Adresse <TUNNEL_SERVER_SIDE_IP> oder die "internen" Adressen der jeweiligen Parteien auf der Client-Seite verwendet werden. Anschließend müssen Sie jedoch die entsprechenden Routen zur Konfiguration hinzufügen Server und / oder Client.



Vor- und Nachteile der obigen Lösung


Nachteile:

  1. Es muss genau ein Client pro Server vorhanden sein, sodass Sie für mehrere Clients mehrere OpenVPN-Prozesse aktiv halten müssen. Infolgedessen - etwas Speicherüberlauf und all das.
  2. Sie können den Preshared-Key-Modus in OpenVPN nicht verwenden, da in diesem Modus die dynamische Übertragung von Parametern vom Server zum Client (Push / Pull) verboten ist. Aus diesem Grund ist eine komplexere Konfiguration erforderlich, einschließlich der Generierung eines Satzes von Schlüsseln und Zertifikaten sowie eines Skripts zum Generieren eines client-connect-dir /path/to/config/dir auf der Serverseite (das jedoch durch ein Verzeichnis statischer Dateien ersetzt werden kann, indem die Option client-connect /path/to/script durch die Option client-connect-dir /path/to/config/dir option ersetzt wird client-connect-dir /path/to/config/dir , wodurch die Sicherheitsstufe der Serverseite erhöht wird.

Vorteile:

  1. Im Gegensatz zu Protokollen wie GRE / IPIP können OpenVPN-Tunnel eine MTU von 1500 Byte aufweisen (da der OpenVPN-Prozess alle Fragmentierungen / Defragmentierungen „unter der Haube“ verbirgt, indem Pakete voller Länge an die Tunnelschnittstelle gesendet werden). Dies macht es einfach, alle Arten von sekundären Tunneln über den OpenVPN-Tunnel zu konfigurieren.
  2. Der OpenVPN-Tunnel unterstützt gleichzeitig die Übertragung von IPv4 und IPv6, wodurch die Anzahl der Tunnel zwischen Knotenpaaren, die Kosten für deren Konfiguration und Verwaltung sowie die Übertragung von IPv6-Routen innerhalb derselben BGP-Sitzung wie IPv4-Routen verringert werden.
  3. Alle Vorteile des OpenVPN-Protokolls, wie die einfache Einrichtung von Netzwerk-Zwischengeräten (oder das völlige Fehlen von Netzwerk-Zwischengeräten), die Möglichkeit, den Verkehr unter HTTPS zu maskieren, das Vorhandensein einer Implementierung für die meisten Plattformen und so weiter.

Ich hoffe, dass jemand den obigen Leitfaden nützlich finden wird.

Source: https://habr.com/ru/post/de483740/


All Articles