Tunnel IP très simple, basé sur DTLS.
S'il n'y a pas besoin d'un cryptage fort, vous pouvez envisager d'utiliser l'utun plus léger ?
go install github.com/taoso/dtun/cmd/dtun
# 服务端
dtun -key foo
# 客户端
dtun -connect addr:port -key foo
Voici une liste rapide de quelques facteurs à prendre en compte.
Il n'est pas facile d'obtenir un cryptage stable et fiable des données au niveau de la couche de transport, j'ai donc toujours utilisé TLS comme protocole sous-jacent.
TLS utilise TCP et les données chiffrées sont également dans une large mesure des données TCP. De cette manière, la transmission d'un paquet de données de couche supérieure nécessite la confirmation des connexions TCP internes et externes. Le problème de mise en œuvre de ce type de TCP sur TCP n'est pas minime. Pour plus de détails, voir : Référence http://sites.inka.de/~bigred/devel/tcp-tcp.html.
Il est donc préférable d’utiliser la transmission UDP. Naturellement, DTLS est utilisé pour le cryptage. Actuellement, DTLS ne prend pas en charge la version 1.3 et le langage go ne le prend pas officiellement en charge. Vous ne pouvez utiliser que cette implémentation tierce https://github.com/pion/dtls.
Qu'il s'agisse de TLS ou de DTLS, vous devez généralement créer un certificat. Cette démarche est désormais gratuite, mais elle reste encore compliquée à paramétrer. De plus, le certificat résout uniquement le problème de chiffrement et ne résout pas le problème d’authentification. Habituellement, seul le client vérifie le certificat du serveur. Vous pouvez également laisser le serveur vérifier le certificat client, mais cela est trop gênant.
De plus, DTLS est sans connexion et ne peut effectuer une authentification que lors de la création d'une connexion comme une connexion TCP.
Par conséquent, il est préférable de terminer l’authentification des deux extrémités en même temps lors de la prise de contact DTLS. Je choisis donc le mode Pre-Shared Key (PSK). Nous avons uniquement besoin d'utiliser -key
pour spécifier la clé principale aux deux extrémités afin de terminer l'authentification double. Une session DTLS ne peut pas être établie si le client ne connaît pas le PSK.
De plus, PSK doit également spécifier un paramètre d'indice. Vous pouvez simplement y penser comme au nom de PSK. DTLS n'est pas connecté, il est donc difficile de déterminer si le client était hors ligne. J'ai décidé d'avoir un paramètre d'indice unique pour chaque client. Le serveur alloue des périphériques de réglage pour les astuces. Si le client est déconnecté et reconnecté, plusieurs périphériques Tun ne seront pas créés. Mais l’effet secondaire est que les clients du même niveau ne peuvent pas se connecter en même temps.
Afin de prendre en charge les macos, le périphérique tun ne peut être réglé qu'en mode point à point. Si nous voulons effectuer un routage et un transfert transparents, regardez l'image ci-dessous
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
Nous espérons que les paquets envoyés par PC seront transmis à PC2 via le routeur puis transmis au réseau externe. Généralement, nous ferons du NAT une fois sur le routeur puis une fois sur pc2. L'avantage est que pc2 n'a pas besoin de connaître la configuration réseau du PC avec le routeur. Mais les inconvénients sont aussi évidents, il y a deux nat. Les performances des routeurs ne sont généralement pas bonnes, le NAT doit donc être évité autant que possible.
Mon plan est donc de pousser directement le segment de réseau 10.0.0.0/16 où se trouve le PC vers PC2 et d'ajouter une route sur PC2.
ip route add 10.0.0.0/16 via 10.1.0.1
De cette façon, le routeur peut transmettre les paquets du PC au PC2 intacts et n'a besoin d'effectuer un NAT qu'une seule fois sur PC2.
Parfois, nous devons spécifier une liste blanche de routage. Utilisez la route par défaut sur les segments réseau de la liste blanche et transférez les autres via le tunnel.
Nous pouvons d'abord ajouter une route de liste blanche au routeur et définir le saut suivant sur la route par défaut du routeur. Précisez ensuite l'IP publique de pc2 pour prendre la route par défaut du routeur (clé !). dernier ajouté
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
et 128.0.0.1/1
couvrent ici tout le segment du réseau. L'effet est équivalent à celui par défaut, mais il n'écrasera pas la route par défaut. Si le tunnel est fermé anormalement, tous les itinéraires associés seront automatiquement supprimés, ce qui est très stable.
Vous pouvez l'écrire sous forme de script et l'exécuter à l'aide du paramètre -up
. Mon script est le suivant :
#! /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