Sehr einfacher IP-Tunnel, basierend auf DTLS.
Wenn keine starke Verschlüsselung erforderlich ist, können Sie die einfachere Verwendung von utun in Betracht ziehen?
go install github.com/taoso/dtun/cmd/dtun
# 服务端
dtun -key foo
# 客户端
dtun -connect addr:port -key foo
Hier finden Sie eine kurze Liste einiger zu berücksichtigender Faktoren.
Es ist nicht einfach, eine stabile und zuverlässige Datenverschlüsselung auf der Transportschicht zu erreichen, daher habe ich immer TLS als zugrunde liegendes Protokoll verwendet.
TLS verwendet TCP, und die verschlüsselten Daten sind zu einem großen Teil ebenfalls TCP-Daten. Auf diese Weise erfordert die Übertragung eines Datenpakets der oberen Schicht eine Bestätigung der inneren und äußeren TCP-Verbindungen. Das Implementierungsproblem dieser Art von TCP über TCP ist nicht gering. Weitere Informationen finden Sie unter: Referenz http://sites.inka.de/~bigred/devel/tcp-tcp.html
Daher ist es am besten, die UDP-Übertragung zu verwenden. Zur Verschlüsselung kommt selbstverständlich DTLS zum Einsatz. Derzeit unterstützt DTLS 1.3 nicht und die Go-Sprache unterstützt es nicht offiziell. Sie können nur diese Drittanbieter-Implementierung verwenden: https://github.com/pion/dtls
Unabhängig davon, ob es sich um TLS oder DTLS handelt, müssen Sie im Allgemeinen ein Zertifikat erstellen. Mittlerweile ist dieser Vorgang kostenlos, allerdings ist die Konfiguration immer noch kompliziert. Darüber hinaus löst das Zertifikat nur das Verschlüsselungsproblem und nicht das Authentifizierungsproblem. Normalerweise überprüft nur der Client das Serverzertifikat. Sie können das Client-Zertifikat auch vom Server überprüfen lassen, dies ist jedoch zu mühsam.
Darüber hinaus ist DTLS verbindungslos und kann nicht nur eine Authentifizierung durchführen, wenn eine Verbindung wie eine TCP-Verbindung hergestellt wird.
Daher ist es am besten, die Authentifizierung beider Enden gleichzeitig während des DTLS-Handshakes abzuschließen. Also wähle ich den Pre-Shared Key (PSK)-Modus. Wir müssen nur -key
verwenden, um den Hauptschlüssel an beiden Enden anzugeben, um die doppelseitige Authentifizierung abzuschließen. Eine DTLS-Sitzung kann nicht aufgebaut werden, wenn der Client den PSK nicht kennt.
Darüber hinaus muss PSK auch einen Hinweisparameter angeben. Man kann es sich einfach als den Namen PSK vorstellen. DTLS ist nicht verbunden, daher ist es schwierig festzustellen, ob der Client offline war. Ich habe beschlossen, für jeden Client einen eindeutigen Hinweisparameter zu verwenden. Der Server weist Tun-Geräte für Hinweise zu. Wenn der Client getrennt und erneut verbunden wird, werden nicht mehrere Tun-Geräte erstellt. Der Nebeneffekt ist jedoch, dass sich Clients desselben Hinits nicht gleichzeitig anmelden können.
Um macOS zu unterstützen, kann das Tun-Gerät nur auf den Punkt-zu-Punkt-Modus eingestellt werden. Wenn wir transparentes Routing und Weiterleiten durchführen möchten, sehen Sie sich das Bild unten an
pc <-----------> router <====== dtun ======> pc2 <---------> www
10.0.0.2/16 10.0.0.1/16 10.1.0.1/16 10.1.0.2/16
Wir hoffen, dass die vom PC gesendeten Pakete über den Router an PC2 und dann an das externe Netzwerk weitergeleitet werden. Im Allgemeinen führen wir NAT einmal auf dem Router und dann einmal auf PC2 durch. Dies hat den Vorteil, dass pc2 die Netzwerkkonfiguration des PCs zum Router nicht kennen muss. Aber auch die Nachteile liegen auf der Hand, es gibt zwei nat. Die Leistung von Routern ist im Allgemeinen nicht hoch, daher sollte NAT so weit wie möglich vermieden werden.
Mein Plan ist es also, das Netzwerksegment 10.0.0.0/16, in dem sich der PC befindet, direkt auf PC2 zu verschieben und eine Route auf PC2 hinzuzufügen
ip route add 10.0.0.0/16 via 10.1.0.1
Auf diese Weise kann der Router die Pakete intakt vom PC an PC2 weiterleiten und muss NAT nur einmal auf PC2 durchführen.
Manchmal müssen wir eine Routing-Whitelist angeben. Verwenden Sie die Standardroute für die Netzwerksegmente in der Whitelist und leiten Sie die anderen durch den Tunnel weiter.
Wir können dem Router zunächst eine Whitelist-Route hinzufügen und den nächsten Hop auf die Standardroute des Routers festlegen. Geben Sie dann die öffentliche IP von pc2 an, um die Standardroute des Routers zu übernehmen (Schlüssel!). zuletzt hinzugefügt
ip route add 0.0.0.0/1 via 10.1.0.2
ip route add 128.0.0.0/1 via 10.1.0.2
0.0.0.0/1
und 128.0.0.1/1
decken hier nur das gesamte Netzwerksegment ab. Die Wirkung entspricht der Standardroute, überschreibt jedoch nicht die Standardroute. Wenn der Tunnel ungewöhnlich geschlossen wird, werden alle zugehörigen Routen automatisch gelöscht, was sehr stabil ist.
Sie können es als Skript schreiben und mit dem Parameter -up
ausführen. Mein Skript ist wie folgt:
#! /bin/sh
# curl -S https://cdn.jsdelivr.net/gh/misakaio/chnroutes2@master/chnroutes.txt|grep -v '#'|xargs -I % ip route add % via $DEFAULT_GW 2>/dev/null
VPN_IP= $( ping your-server-name -c 1 | grep from | cut -d ' ' -f4 | cut -d: -f1 )
DEFAULT_GW= $( ip route | grep default | cut -d ' ' -f3 )
ip route add $VPN_IP /32 via $DEFAULT_GW
ip route add 0.0.0.0/1 via $PEER_IP
ip route add 128.0.0.0/1 via $PEER_IP