tinc-boot - Full-Mesh-Netzwerk ohne Schmerzen


Automatisch, sicher, verteilt, mit transitiven Verbindungen (dh Weiterleiten von Nachrichten, wenn kein direkter Zugriff zwischen Teilnehmern besteht), ohne einen einzigen Fehlerpunkt, Peer, bewährtes, ressourcenschonendes, vollständig vermaschtes VPN-Netzwerk mit der Fähigkeit zum "Punch" NAT - ist es möglich?


Die richtigen Antworten sind:


  • Ja, mit Schmerzen, wenn Sie Zink verwenden.
  • Ja, einfach, wenn Sie Tinc + Tinc-Boot verwenden

Einführender Link überspringen


Tinc Beschreibung


Leider wurden einige Informationen über Tinc VPN auf Habré veröffentlicht, aber einige relevante Artikel sind noch zu finden:



Von den englischsprachigen Artikeln kann unterschieden werden:



Die Originalquelle ist besser, um die Originaldokumentation von Tinc Man zu berücksichtigen


Tinc VPN ist ein Dienst ( tincd daemon) (ein kostenloser Nachdruck von der offiziellen Website), der das Funktionieren eines privaten Netzwerks durch Tunneln und Verschlüsseln des Datenverkehrs zwischen Knoten sicherstellt. Der Quellcode ist offen und unter der GPL2-Lizenz verfügbar. Wie die klassische (OpenVPN) Lösung ist das erstellte virtuelle Netzwerk auf IP-Ebene (OSI 3) verfügbar, sodass im Allgemeinen keine Änderungen an den Anwendungen erforderlich sind.


Hauptmerkmale:


  • Verschlüsselung, Authentifizierung und Komprimierung des Datenverkehrs;
  • vollautomatische Full-Mesh-Lösung, die das Herstellen von Verbindungen zu Netzwerkknoten in einem All-with-All-Modus oder das Weiterleiten von Nachrichten zwischen Zwischenhosts umfasst, falls dies nicht zutrifft;
  • Schlag NAT;
  • die Fähigkeit, isolierte Netzwerke auf Ethernet-Ebene zu verbinden (virtueller Switch);
  • Unterstützung mehrerer Betriebssysteme: Linux, FreeBSD, OS X, Solaris, Windows usw.

Es gibt zwei Zweige der Zinkentwicklung: 1.0.x (in fast allen Repositories) und 1.1 (ewiges Beta). Der Artikel verwendet überall Version 1.0.x.


Tinc 1.1x bietet mehrere neue Hauptfunktionen: perfekte Vorwärtssicherheit, vereinfachte Client-Konnektivität (ersetzt tatsächlich tinc-boot ) und ein allgemein durchdachteres Design.

Derzeit wird jedoch auf der offiziellen Website eine stabile Version - 1.0.x angezeigt und hervorgehoben. Wenn Sie also alle Vorteile des 1.1-Zweigs nutzen, sollten Sie alle Vor- und Nachteile einer nicht endgültigen Version bewerten.

Aus meiner Sicht besteht eine der stärksten Möglichkeiten darin, Nachrichten weiterzuleiten, wenn keine direkte Verbindung möglich ist. Gleichzeitig werden Routing-Tabellen automatisch erstellt. Selbst Knoten ohne öffentliche Adresse können Datenverkehr durch sich selbst leiten.



Betrachten Sie die Situation mit drei Servern (China, Russland, Singapur) und drei Clients (Russland, China und die Philippinen):


  • Server haben eine öffentliche Adresse, Clients hinter NAT;
  • ILV während des nächsten Verbots wahrscheinlicher Proxies Das Telegramm blockierte alle Hoster mit Ausnahme des "freundlichen" China;
  • Die Netzwerkgrenze von China <-> RF ist instabil und kann fallen (aufgrund von ILV und / oder aufgrund des chinesischen Zensors).
  • Verbindungen nach Singapur sind bedingt stabil (persönliche Erfahrung);
  • Manila (Philippinen) ist für niemanden eine Bedrohung und daher für alle erlaubt (aufgrund der Entfernung von allen und allem).

Betrachten Sie zum Beispiel den Verkehrsaustausch zwischen Shanghai und Moskau (ungefähr) die Szenarien von Tinc:


  1. Einheimische Situation: Moskau <-> Russland-srv <-> China-srv <-> Shanghai
  2. ILV geschlossene Verbindung nach China: Moskau <-> Russland-srv <-> Manila <-> Singapur <-> Shanghai
  3. (nach 2) Bei einem Serverausfall in Singapur wird der Datenverkehr auf den Server in China übertragen und umgekehrt.

Wann immer möglich, versucht Tinc, durch Stanzen eine direkte Verbindung zwischen den beiden Knoten hinter NAT herzustellen.


Eine kurze Einführung in die Zinkkonfiguration


Tinc ist als einfach zu konfigurierender Dienst positioniert. Es ist jedoch ein Fehler aufgetreten - um einen neuen Knoten zu erstellen, ist dies nur minimal erforderlich:


  • Beschreiben der tinc.conf (Typ, Name) ( tinc.conf );
  • Beschreiben der Konfigurationsdatei (bediente Subnetze, öffentliche Adressen) ( hosts/ );
  • einen Schlüssel erstellen;
  • Erstellen Sie ein Skript, das die tinc-up und die zugehörigen Parameter tinc-up ( tinc-up ).
  • Es ist ratsam, ein Skript zu erstellen, das die erstellten Parameter nach dem Stoppen löscht ( tinc-down ).

Wenn Sie eine Verbindung zu einem vorhandenen Netzwerk herstellen, müssen Sie außerdem die vorhandenen Hostschlüssel erhalten und Ihre eigenen bereitstellen.


Dh für den zweiten Knoten



Zum dritten



Bei Verwendung der bidirektionalen Synchronisation (z. B. unison ) erhöht sich die Anzahl der zusätzlichen Operationen auf N Teile, wobei N die Anzahl der öffentlichen Knoten ist.


Wir müssen den Entwicklern von Tinc Tribut zollen - für die Aufnahme in das Netzwerk tauschen Sie einfach die Schlüssel aus
mit nur einem der Knoten (Bootknoten). Nach dem Starten des Dienstes und dem Herstellen einer Verbindung zum Teilnehmer erhält tinc die Topologie
Netzwerk und wird in der Lage sein, mit allen Teilnehmern zu arbeiten.

Wenn der Boot-Host jedoch nicht mehr verfügbar ist und tinc neu gestartet wurde, gibt es keine Möglichkeit
stellt eine Verbindung zum virtuellen Netzwerk her.

Darüber hinaus bieten die enormen Möglichkeiten von Tinc zusammen mit der akademischen Dokumentation (gut beschrieben, aber nur wenige Beispiele) ein umfangreiches Feld für Fehler.


Gründe, Tinc-Boot zu erstellen


Wenn wir die oben beschriebenen Probleme verallgemeinern und als Aufgaben formulieren, erhalten wir:


  1. Die Fähigkeit, mit minimalem Aufwand eine neue Site zu erstellen, ist erforderlich.
    • Möglicherweise muss es möglich sein, dem durchschnittlichen Spezialisten (enikey) eine kleine Leitung zu geben, um einen neuen Knoten zu erstellen und eine Verbindung zum Netzwerk herzustellen.
  2. Es ist erforderlich, eine automatische Verteilung der Schlüssel zwischen allen aktiven Knoten bereitzustellen.
  3. Es ist erforderlich, ein vereinfachtes Schlüsselaustauschverfahren zwischen dem Bootnod und dem neuen Client bereitzustellen.

Bootknoten - ein Knoten mit einer öffentlichen Adresse (siehe oben);

Aufgrund der Anforderungen von Anspruch 2 kann argumentiert werden, dass nach dem Schlüsselaustausch zwischen dem Bootknoten und dem neuen Knoten und danach
Wenn Sie den Knoten mit dem Netzwerk verbinden, erfolgt die Verteilung des neuen Schlüssels automatisch.


Es sind diese Aufgaben, die tinc-boot ausführt.


tinc-boot ist eine eigenständige Open-Source-Anwendung, die neben tinc bietet:


  • einfache Erstellung eines neuen Knotens;
  • automatische Verbindung zu einem bestehenden Netzwerk;
  • Standardmäßig die meisten Parameter einstellen;
  • Schlüsselverteilung zu Honigknoten.

Architektur


Die ausführbare Datei von tinc-boot besteht aus vier Komponenten: einem Bootknotenserver, einem Schlüsselverteilungsverwaltungsserver und RPC-Verwaltungsbefehlen dafür sowie einem Knotengenerierungsmodul.


Knotengenerierungsmodul


Das Knotengenerierungsmodul ( tinc-boot gen ) erstellt alle erforderlichen Dateien, damit tinc erfolgreich ausgeführt werden kann.


Vereinfacht kann sein Algorithmus wie folgt beschrieben werden:


  1. Definieren Sie den Hostnamen, das Netzwerk, die IP-Parameter, den Port, die Subnetzmaske usw.
  2. Normalisieren Sie sie (tinc hat eine Grenze für einige Werte) und erstellen Sie die fehlenden
  3. Überprüfen Sie die Parameter
  4. Installieren Sie gegebenenfalls tinc-boot auf dem System (deaktivierbar).
  5. Erstellen Sie tinc-up , tinc-down , tinc-up und tinc-down subnet-down
  6. Erstellen tinc.conf Konfigurationsdatei tinc.conf
  7. hosts/ erstellen hosts/
  8. Führen Sie die Schlüsselgenerierung durch
  9. Führen Sie einen Schlüsselaustausch mit dem Bootknoten durch
    1. Verschlüsseln und signieren Sie Ihre eigene Hostdatei mit einem öffentlichen Schlüssel, einem zufälligen Initialisierungsvektor (Nounce) und einem Hostnamen mit xchacha20poly1305, wobei der Verschlüsselungsschlüssel das Ergebnis der sha256-Funktion des Tokens ist
    2. Senden Sie Daten über das HTTP-Protokoll an den Bootknoten
    3. Entschlüsseln Sie die empfangene Antwort und den X-Node Header, der den Namen des Bootknotens enthält, unter Verwendung des ursprünglichen Nouncings und des gleichen Algorithmus
    4. Wenn dies erfolgreich ist, speichern Sie den empfangenen Schlüssel in hosts/ und fügen Sie der Konfigurationsdatei einen ConnectTo Eintrag hinzu (d. H. Eine Empfehlung, wo eine Verbindung hergestellt werden soll).
    5. Verwenden Sie andernfalls die folgende Adresse in der Liste des Startknotens und wiederholen Sie den Vorgang ab Schritt 2
  10. Empfehlungen zum Starten eines Dienstes anzeigen

Die Konvertierung über SHA-256 wird nur verwendet, um den Schlüssel auf 32 Byte zu normalisieren

Für den allerersten Knoten (dh wenn nichts als Startadresse anzugeben ist) wird Schritt 9 übersprungen. Flagge - --standalone .


Beispiel 1 - Erstellen der ersten öffentlichen Site


Die öffentliche Adresse lautet 1.2.3.4


sudo tinc-boot gen --standalone -a 1.2.3.4


  • Mit dem Flag -a können Sie öffentlich verfügbare Adressen angeben

Beispiel 1 - Hinzufügen eines nicht öffentlichen Knotens zum Netzwerk


Der Startknoten wird dem obigen Beispiel entnommen. Auf dem Host muss der Tinc-Boot-Bootknoten ausgeführt werden (später beschrieben).


sudo tinc-boot gen --token "MY TOKEN" http://1.2.3.4:8655


  • --token Flag --token setzt das Autorisierungstoken

Bootstrap-Modul


Das tinc-boot bootnode löst einen HTTP-Server mit einer API für den Primärschlüsselaustausch mit neuen Clients aus.


Standardmäßig wird Port 8655 .


Vereinfacht kann der Algorithmus wie folgt beschrieben werden:


  1. Akzeptieren Sie eine Anfrage von einem Client
  2. Entschlüsseln und überprüfen Sie die Anforderung mit xchacha20poly1305, wobei Sie den während der Anforderung übergebenen Initialisierungsvektor verwenden und der Verschlüsselungsschlüssel das Ergebnis der Funktion sha256 aus dem Token ist
  3. Überprüfen Sie den Namen
  4. Datei speichern, wenn noch keine Datei mit demselben Namen vorhanden ist
  5. Verschlüsseln und signieren Sie Ihre eigene Hostdatei und Ihren eigenen Namen mit dem oben beschriebenen Algorithmus
  6. Zurück zu Punkt 1

Zusammen ist der Primärschlüsselaustauschprozess wie folgt:



Beispiel 1 - Starten des Download-Knotens


Es wird davon ausgegangen, dass die tinc-boot gen des Knotens durchgeführt wurde ( tinc-boot gen )


tinc-boot bootnode --token "MY TOKEN"


  • --token Flag --token setzt das Autorisierungstoken. Dies sollte auch für Clients gelten, die eine Verbindung zum Host herstellen.

Beispiel 2 - Starten des Download-Knotens als Dienst


tinc-boot bootnode --service --token "MY TOKEN"


  • --service Flag --service an, einen systemd-Dienst zu erstellen (standardmäßig in diesem Beispiel tinc-boot-dnet.service ).
  • --token Flag --token setzt das Autorisierungstoken. Dies sollte auch für Clients gelten, die eine Verbindung zum Host herstellen.

Schlüsselverteilungsmodul


Das Schlüsselverteilungsmodul ( tinc-boot monitor ) löst einen HTTP-Server mit einer API zum Austausch von Schlüsseln mit anderen Knoten im VPN aus . Es ist auf die vom Netzwerk ausgegebene Adresse festgelegt (der Standardport ist 1655 , es treten keine Konflikte mit mehreren Netzwerken auf, da jedes Netzwerk eine eigene Adresse hat / haben muss).


Das Modul startet und arbeitet vollautomatisch: Sie müssen nicht im manuellen Modus damit arbeiten.


Dieses Modul startet automatisch, wenn das Netzwerk aktiv ist (im tinc-up Skript) und stoppt automatisch, wenn es stoppt (im tinc-down Skript).


Unterstützt Operationen:


  • GET / - Geben Sie Ihre Knotendatei an
  • POST /rpc/watch?node=<>&subnet=<> - POST /rpc/watch?node=<>&subnet=<> eine Datei von einem anderen Knoten ab, sofern ein ähnlicher Dienst darauf ausgeführt wird. Standardmäßig läuft das Zeitlimit für Versuche alle 30 Sekunden auf 10 Sekunden ab, bis Erfolg oder Abbruch eintreten.
  • POST /rpc/forget?node=<> - Versuche (falls vorhanden) hinterlassen, die Datei von einem anderen Knoten POST /rpc/forget?node=<>
  • POST /rpc/kill - POST /rpc/kill den Dienst

Zusätzlich wird jede Minute (standardmäßig) und wenn eine neue Konfigurationsdatei empfangen wird, die Indizierung der gespeicherten Knoten für neue öffentliche Knoten durchgeführt. Wenn Knoten mit dem tinc.conf erkannt werden, wird der Konfigurationsdatei tinc.conf ein Eintrag hinzugefügt, um die Verbindung beim Neustart zu empfehlen.


Schlüsselverteilungsmodul (Verwaltung)


Befehle zum Anfordern ( tinc-boot watch ) und Abbrechen der Anforderung ( tinc-boot forget ) der Konfigurationsdatei von anderen Knoten werden automatisch ausgeführt, wenn ein neuer Knoten erkannt ( subnet-up Skript) bzw. gestoppt ( subnet-down Skript) wird.


Beim Beenden des Dienstes wird das tinc-down Skript tinc-down bei dem der tinc-boot kill das Schlüsselverteilungsmodul stoppt.


Anstelle von total


Dieses Dienstprogramm wurde unter dem Einfluss kognitiver Dissonanzen zwischen dem Genie der Tinc-Entwickler und der linear wachsenden Komplexität beim Einrichten neuer Knoten erstellt.


Die Hauptideen im Entwicklungsprozess waren:


  • Wenn etwas automatisiert werden kann, muss es automatisiert werden.
  • Standardwerte sollten mindestens 80% der Nutzung abdecken (Pareto-Prinzip);
  • Jeder Wert kann sowohl mit Flags als auch mit Umgebungsvariablen neu definiert werden.
  • Das Dienstprogramm sollte helfen und nicht den Wunsch hervorrufen, dem Schöpfer die ganze Bestrafung des Himmels aufzuerlegen.
  • Die Verwendung eines Autorisierungstokens für die Erstinitialisierung ist ein offensichtliches Risiko, wurde jedoch nach Möglichkeit aufgrund der vollständigen Kryptografie und Authentifizierung minimiert (selbst der Knotenname im Antwortheader kann nicht ersetzt werden).

Eine kleine Chronologie:


  • Das erste Mal vor mehr als 4 Jahren habe ich Tinc verwendet. Studierte eine bedeutende Menge an Material. Richten Sie ein ideales (meiner Meinung nach) Netzwerk ein
  • Nach einem halben Jahr wurde Zink zugunsten von Nullpunkt als bequemeres / flexibleres Werkzeug ersetzt
  • Vor 2 Jahren habe ich ein ansible Playbook erstellt, um tinc bereitzustellen
  • Einen Monat später brach mein Skript bei der inkrementellen Bereitstellung zusammen (d. H. Wenn es nicht möglich ist, auf alle Netzwerkknoten zuzugreifen, was bedeutet, dass Schlüssel verteilt werden).
  • Vor zwei Wochen habe ich ein Bash-Skript geschrieben, das der Prototyp für tinc-boot
  • Vor 3 Tagen nach der zweiten Iteration wurde die erste (genauer gesagt 0.0.1) Version des Dienstprogramms geboren
  • Vor einem Tag habe ich die Installation eines neuen Knotens auf eine Zeile reduziert: curl -L https://github.com/reddec/tinc-boot/releases/latest/download/tinc-boot_linux_amd64.tar.gz | sudo tar -xz -C /usr/local/bin/ tinc-boot curl -L https://github.com/reddec/tinc-boot/releases/latest/download/tinc-boot_linux_amd64.tar.gz | sudo tar -xz -C /usr/local/bin/ tinc-boot
  • In Kürze wird die Möglichkeit einer noch einfacheren Verbindung zum Netzwerk hinzugefügt (ohne die Sicherheit zu beeinträchtigen).

Während der Entwicklung habe ich aktiv auf realen Servern und Clients getestet (das Bild aus der obigen Beschreibung von tinc stammt aus dem realen Leben). Jetzt funktioniert das System einwandfrei und alle VPN-Dienste von Drittanbietern sind jetzt deaktiviert.


Der Anwendungscode ist in GO geschrieben und unter der MPL 2.0-Lizenz geöffnet . Eine Lizenz (kostenlose Übersetzung) ermöglicht die kommerzielle Nutzung (falls dies plötzlich erforderlich ist), ohne das Quellprodukt zu öffnen. Die einzige Voraussetzung ist, dass die Änderungen in das Projekt übertragen werden.


Poolanfragen sind willkommen.


Nützliche Links


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


All Articles