Guten Tag!
In diesem Artikel möchte ich beschreiben, wie ich () Bash-Skript entwickelt habe, um zwei Computer, die sich hinter NAT befinden, mithilfe der UDP-Hole-Punching-Technologie zu verbinden, am Beispiel von Ubuntu/Debian.
Die Verbindung erfolgt in mehreren Schritten:
- Start des Knotens und Warten auf die Bereitschaft des entfernten Knotens;
- Bestimmung der externen IP-Adresse und des UDP-Ports;
- Ăbertragung der externen IP-Adresse und des UDP-Ports an den entfernten Knoten;
- Empfang der externen IP-Adresse und des UDP-Ports vom entfernten Knoten;
- Etablierung eines IPIP-Tunnels;
- Ăberwachung der Verbindung;
- Bei VerbindungsabbrĂŒchen den IPIP-Tunnel entfernen.
Ich habe lange nachgedacht und denke immer noch darĂŒber nach, was ich zum Austausch von Daten zwischen den Knoten verwenden kann; fĂŒr mich ist derzeit die einfachste und schnellste Lösung die Nutzung von Yandex.Disk.
- Erstens ist es einfach zu verwenden â es sind nur 3 Schritte erforderlich: erstellen, lesen, löschen. Mit curl sieht das so aus:
Erstellen:curl -s -X MKCOL --user "$usename:$password" https://webdav.yandex.ru/$folderLesen:
curl -s --user "$usename:$password" -X PROPFIND -H "Depth: 1" https://webdav.yandex.ru/$folderLöschen:
curl -s -X DELETE --user "$usename:$password" https://webdav.yandex.ru/$folder - Zweitens ist es einfach zu installieren:
apt install curl
Zur Bestimmung der externen IP-Adresse und des UDP-Ports verwenden Sie den stun-client mit dem Befehl:
stun stun.sipnet.ru -v -p $1 2>&1 | grep "MappedAddress"Installation mit dem Befehl:
apt install stun-clientFĂŒr die Organisation des Tunnels werden die integrierten Werkzeuge des Betriebssystems aus dem Paket iproute2 verwendet. Es gibt die man mit den integrierten Mitteln aufbauen kann (L2TPv3, GRE usw.), aber ich habe mich fĂŒr IPIP entschieden, da es die geringste zusĂ€tzliche Belastung fĂŒr das System verursacht. Ich habe L2TPv3 ĂŒber UDP ausprobiert und war enttĂ€uscht, die Geschwindigkeit fiel um das 10-Fache, aber dies könnten verschiedene EinschrĂ€nkungen mit den Providern oder anderen Faktoren sein. Da der IPIP-Tunnel auf der IP-Ebene funktioniert, wird ein FOU-Tunnel verwendet, um auf der Ebene der UDP-Ports zu arbeiten. FĂŒr die Einrichtung eines IPIP-Tunnels sind folgende Schritte erforderlich:
â Laden Sie das FOU-Modul:
modprobe fouâ Lokalen Port ab hören:
ip fou add port $localport ipproto 4â Tunnel erstellen:
ip link add name fou$name type ipip remote $remoteip local $localip encap fou encap-sport $localport encap-dport $remoteportâ Schnittstelle des Tunnels aktivieren:
ip link set up dev fou$nameâ Interne lokale und entfernte IP-Adresse des Tunnels zuweisen:
ip addr add $intIP peer $peerip dev fou$nameTunnel entfernen:
ip link del dev fou$nameip fou del port $localportDer Zustand des Tunnels wird durch regelmĂ€Ăiges Pingen der internen IP-Adresse des Remote-Knotens ĂŒberwacht, mit dem Befehl:
ping -c 1 $peerip -s 0Das regelmĂ€Ăige Pingen ist vor allem wichtig, um den Kanal aufrechtzuerhalten, da sonst bei InaktivitĂ€t des Tunnels auf Routern die NAT-Tabellen gelöscht werden können und die Verbindung dann unterbrochen wird.
Wenn das Pingen ausbleibt, wird der IPIP-Tunnel entfernt und wartet auf die Bereitschaft vom Remote-Knoten.
Das eigentliche Skript:
#!/bin/bash
username="username@yandex.ru"
password="password"
folder="vpnid"
intip="10.0.0.1"
localport=`shuf -i 10000-65000 -n 1`
cid=`shuf -i 10000-99999 -n 1`
tid=`shuf -i 10-99 -n 1`
function yaread {
curl -s --user "$1:$2" -X PROPFIND -H "Depth: 1" https://webdav.yandex.ru/$3 | sed 's/></>n</g' | grep "displayname" | sed 's/<d:displayname>//g' | sed 's/</d:displayname>//g' | grep -v $3 | grep -v $4 | sort -r
}
function yacreate {
curl -s -X MKCOL --user "$1:$2" https://webdav.yandex.ru/$3
}
function yadelete {
curl -s -X DELETE --user "$1:$2" https://webdav.yandex.ru/$3
}
function myipport {
stun stun.sipnet.ru -v -p $1 2>&1 | grep "MappedAddress" | sort | uniq | awk '{print $3}' | head -n1
}
function tunnel-up {
modprobe fou
ip fou add port $4 ipproto 4
ip link add name fou$7 type ipip remote $1 local $3 encap fou encap-sport $4 encap-dport $2
ip link set up dev fou$7
ip addr add $6 peer $5 dev fou$7
}
function tunnel-check {
sleep 10
pings=0
until [[ $pings == 4 ]]; do
if ping -c 1 $1 -s 0 &>/dev/null;
then echo -n .; n=0
else echo -n !; ((pings++))
fi
sleep 15
done
}
function tunnel-down {
ip link del dev fou$1
ip fou del port $2
}
trap 'echo -e "nDisconnecting..." && yadelete $username $password $folder; tunnel-down $tunnelid $localport; echo "IPIP tunnel disconnected!"; exit 1' 1 2 3 8 9 14 15
until [[ -n $end ]]; do
yacreate $username $password $folder
until [[ -n $ip ]]; do
mydate=`date +%s`
timeout="60"
list=`yaread $username $password $folder $cid | head -n1`
yacreate $username $password $folder/$mydate:$cid
for l in $list; do
if [ `echo $l | sed 's/:/ /g' | awk {'print $1'}` -ge $(($mydate-65)) ]; then
#echo $list
myipport=`myipport $localport`
yacreate $username $password $folder/$mydate:$cid:$myipport:$intip:$tid
timeout=$(( $timeout + `echo $l | sed 's/:/ /g' | awk {'print $1'}` - $mydate + 3 ))
ip=`echo $l | sed 's/:/ /g' | awk '{print $3}'`
port=`echo $l | sed 's/:/ /g' | awk '{print $4}'`
peerip=`echo $l | sed 's/:/ /g' | awk '{print $5}'`
peerid=`echo $l | sed 's/:/ /g' | awk '{print $6}'`
if [[ -n $peerid ]]; then tunnelid=$(($peerid*$tid)); fi
fi
done
if ( [[ -z "$ip" ]] && [ "$timeout" -gt 0 ] ) ; then
echo -n "!"
sleep $timeout
fi
done
localip=`ip route get $ip | head -n1 | sed 's|.*src ||' | cut -d' ' -f1`
tunnel-up $ip $port $localip $localport $peerip $intip $tunnelid
tunnel-check $peerip
tunnel-down $tunnelid $localport
yadelete $username $password $folder
unset ip port myipport
done
exit 0Variablen Benutzername, Passwort und Ordner mĂŒssen auf beiden Seiten identisch sein, wĂ€hrend intip unterschiedlich sein kann, zum Beispiel: 10.0.0.1 und 10.0.0.2. Die Zeit auf den Knoten sollte synchronisiert sein. Das Skript kann wie folgt gestartet werden:
nohup script.sh &Ich weise darauf hin, dass der IPIP-Tunnel aus SicherheitsgrĂŒnden unsicher ist, da der Verkehr nicht verschlĂŒsselt ist, aber dies lĂ€sst sich leicht mit IPsec lösen. , erschien mir einfach und verstĂ€ndlich.
Ich benutze dieses Skript seit mehreren Wochen, um mich mit meinem Arbeits-PC zu verbinden, und habe keine Probleme festgestellt. Es ist praktisch, da ich es eingerichtet und vergessen habe.
Vielleicht haben Sie Anmerkungen oder VorschlÀge, ich freue mich darauf, diese zu hören.
Vielen Dank fĂŒr Ihre Aufmerksamkeit!
Quelle: habr.com
