Καλή μέρα!
Σε αυτό το άρθρο θέλω να σας πω πώς υλοποίησα (
Η δημιουργία μιας σύνδεσης αποτελείται από πολλά βήματα:
- Εκκίνηση ενός κόμβου και αναμονή για τον απομακρυσμένο κόμβο να είναι έτοιμος.
- Προσδιορισμός της εξωτερικής διεύθυνσης IP και της θύρας UDP.
- Μεταφορά εξωτερικής διεύθυνσης IP και θύρας UDP σε απομακρυσμένο κεντρικό υπολογιστή.
- Λήψη εξωτερικής διεύθυνσης IP και θύρας UDP από απομακρυσμένο κεντρικό υπολογιστή.
- Οργάνωση μιας σήραγγας IPIP.
- Παρακολούθηση σύνδεσης;
- Εάν η σύνδεση χαθεί, διαγράψτε τη σήραγγα IPIP.
Σκέφτηκα για πολύ καιρό και ακόμα σκέφτομαι τι μπορεί να χρησιμοποιηθεί για την ανταλλαγή δεδομένων μεταξύ κόμβων, το πιο απλό και γρήγορο για μένα αυτή τη στιγμή είναι η εργασία μέσω του Yandex.disk.
- Πρώτον, είναι εύκολο στη χρήση - χρειάζεστε 3 ενέργειες: δημιουργία, ανάγνωση, διαγραφή. Με μπούκλα αυτό είναι:
Δημιουργώ:curl -s -X MKCOL --user "$usename:$password" https://webdav.yandex.ru/$folder
Ανάγνωση:
curl -s --user "$usename:$password" -X PROPFIND -H "Depth: 1" https://webdav.yandex.ru/$folder
Διαγράφω:
curl -s -X DELETE --user "$usename:$password" https://webdav.yandex.ru/$folder
- Δεύτερον, είναι εύκολο να εγκατασταθεί:
apt install curl
Για να προσδιορίσετε την εξωτερική διεύθυνση IP και τη θύρα UDP, χρησιμοποιήστε την εντολή stun-client:
stun stun.sipnet.ru -v -p $1 2>&1 | grep "MappedAddress"
Εγκατάσταση με εντολή:
apt install stun-client
Για την οργάνωση ενός τούνελ, χρησιμοποιούνται τυπικά εργαλεία λειτουργικού συστήματος από το πακέτο iproute2. Υπάρχει
— φορτώστε τη μονάδα FOU:
modprobe fou
— ακούστε το τοπικό λιμάνι:
ip fou add port $localport ipproto 4
— Δημιουργήστε μια σήραγγα:
ip link add name fou$name type ipip remote $remoteip local $localip encap fou encap-sport $localport encap-dport $remoteport
— ανυψώστε τη διεπαφή της σήραγγας:
ip link set up dev fou$name
— εκχώρηση εσωτερικών τοπικών και εσωτερικών απομακρυσμένων διευθύνσεων IP της σήραγγας:
ip addr add $intIP peer $peerip dev fou$name
Διαγραφή ενός τούνελ:
ip link del dev fou$name
ip fou del port $localport
Η κατάσταση της σήραγγας παρακολουθείται κάνοντας περιοδικά ping στην εσωτερική διεύθυνση IP του τούνελ απομακρυσμένου κόμβου με την εντολή:
ping -c 1 $peerip -s 0
Χρειάζεται περιοδικό ping κυρίως για τη διατήρηση του καναλιού, διαφορετικά, όταν το τούνελ είναι αδρανές, οι πίνακες NAT στους δρομολογητές μπορεί να διαγραφούν και στη συνέχεια η σύνδεση θα διακοπεί.
Εάν το ping εξαφανιστεί, τότε η σήραγγα IPIP διαγράφεται και περιμένει για ετοιμότητα από τον απομακρυσμένο κεντρικό υπολογιστή.
Το ίδιο το σενάριο:
#!/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
Μεταβλητές όνομα χρήστη, κωδικό πρόσβασης и φάκελο πρέπει να είναι το ίδιο και στις δύο πλευρές, αλλά κρυφοκοίταγμα - διαφορετικά, για παράδειγμα: 10.0.0.1 και 10.0.0.2. Η ώρα στους κόμβους πρέπει να συγχρονιστεί. Μπορείτε να εκτελέσετε το σενάριο ως εξής:
nohup script.sh &
Θα ήθελα να επιστήσω την προσοχή σας στο γεγονός ότι η σήραγγα IPIP δεν είναι ασφαλής από την άποψη του γεγονότος ότι η κίνηση δεν είναι κρυπτογραφημένη, αλλά αυτό μπορεί εύκολα να λυθεί χρησιμοποιώντας το IPsec over
Χρησιμοποιώ αυτό το σενάριο για σύνδεση σε υπολογιστή εργασίας εδώ και αρκετές εβδομάδες και δεν έχω παρατηρήσει κανένα πρόβλημα. Βολικό όσον αφορά τη ρύθμιση και το ξεχνώντας.
Ίσως θα έχετε σχόλια και προτάσεις, θα χαρώ να ακούσω.
Спасибо за внимание!
Πηγή: www.habr.com