Bon moment de la journée!
Dans cet article, je veux vous expliquer comment j'ai implémenté (
L'établissement d'une connexion comprend plusieurs étapes :
- Démarrer un nœud et attendre que le nœud distant soit prêt ;
- Détermination de l'adresse IP externe et du port UDP ;
- Transfert d'une adresse IP externe et d'un port UDP vers un hôte distant ;
- Obtention d'une adresse IP externe et d'un port UDP à partir d'un hôte distant ;
- Organisation d'un tunnel IPIP ;
- Surveillance des connexions ;
- Si la connexion est perdue, supprimez le tunnel IPIP.
J'ai longtemps réfléchi et je pense toujours à ce qui peut être utilisé pour échanger des données entre nœuds, le plus simple et le plus rapide pour moi en ce moment est de travailler via Yandex.disk.
- Premièrement, il est facile à utiliser - vous avez besoin de 3 actions : créer, lire, supprimer. Avec curl, c'est :
Créer:curl -s -X MKCOL --user "$usename:$password" https://webdav.yandex.ru/$folder
Lire:
curl -s --user "$usename:$password" -X PROPFIND -H "Depth: 1" https://webdav.yandex.ru/$folder
Effacer:
curl -s -X DELETE --user "$usename:$password" https://webdav.yandex.ru/$folder
- Deuxièmement, il est facile à installer :
apt install curl
Pour déterminer l'adresse IP externe et le port UDP, utilisez la commande stun-client :
stun stun.sipnet.ru -v -p $1 2>&1 | grep "MappedAddress"
Installation avec commande :
apt install stun-client
Pour organiser un tunnel, les outils standard du système d'exploitation du package iproute2 sont utilisés. Existe
— charger le module FOU :
modprobe fou
— écoutez le port local :
ip fou add port $localport ipproto 4
— créer un tunnel :
ip link add name fou$name type ipip remote $remoteip local $localip encap fou encap-sport $localport encap-dport $remoteport
— relever l'interface du tunnel :
ip link set up dev fou$name
— attribuer des adresses IP locales internes et distantes internes du tunnel :
ip addr add $intIP peer $peerip dev fou$name
Supprimer un tunnel :
ip link del dev fou$name
ip fou del port $localport
L'état du tunnel est surveillé en envoyant périodiquement une requête ping à l'adresse IP interne du tunnel du nœud distant avec la commande :
ping -c 1 $peerip -s 0
Un ping périodique est nécessaire principalement pour maintenir le canal, sinon, lorsque le tunnel est inactif, les tables NAT sur les routeurs peuvent être effacées et la connexion sera alors interrompue.
Si le ping disparaît, le tunnel IPIP est supprimé et attend la disponibilité de l'hôte distant.
Le scénario lui-même :
#!/bin/bash
username="[email protected]"
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 0
Variables Nom d'utilisateur, Mot de passe и dossier devrait être le même des deux côtés, mais astuce - différents, par exemple : 10.0.0.1 et 10.0.0.2. L'heure sur les nœuds doit être synchronisée. Vous pouvez exécuter le script comme ceci :
nohup script.sh &
Je voudrais attirer votre attention sur le fait que le tunnel IPIP n'est pas sûr du point de vue du fait que le trafic n'est pas crypté, mais cela peut être facilement résolu en utilisant IPsec sur
J'utilise ce script pour me connecter à un PC de travail depuis plusieurs semaines maintenant et je n'ai remarqué aucun problème. Pratique pour le régler et l'oublier.
Peut-être aurez-vous des commentaires et des suggestions, je serai heureux de vous écouter.
Je vous remercie!
Source: habr.com