Yksinkertainen UDP-rei'itys käyttämällä esimerkkinä IPIP-tunnelia

Hyvä kellonaika!

Tässä artikkelissa haluan kertoa kuinka toteutin (vielä yksi) Bash-skripti kahden NAT:n takana sijaitsevan tietokoneen yhdistämiseen UDP-rei'itystekniikalla käyttäen esimerkkinä Ubuntu/Debian-käyttöjärjestelmää.

Yhteyden muodostaminen koostuu useista vaiheista:

  1. Solmun käynnistäminen ja etäsolmun olevan valmis;
  2. Ulkoisen IP-osoitteen ja UDP-portin määrittäminen;
  3. Ulkoisen IP-osoitteen ja UDP-portin siirtäminen etäisäntään;
  4. Ulkoisen IP-osoitteen ja UDP-portin hankkiminen etäisännältä;
  5. IPIP-tunnelin järjestäminen;
  6. Yhteyden seuranta;
  7. Jos yhteys katkeaa, poista IPIP-tunneli.

Mietin pitkään ja ajattelen edelleen, mitä voidaan käyttää tietojen vaihtamiseen solmujen välillä, yksinkertaisin ja nopein minulle tällä hetkellä on työskentely Yandex.diskin kautta.

  • Ensinnäkin se on helppokäyttöinen - tarvitset 3 toimintoa: luo, lue, poista. Curlilla tämä on:
    Luoda:

    curl -s -X MKCOL --user "$usename:$password" https://webdav.yandex.ru/$folder

    Lukea:

    curl -s --user "$usename:$password" -X PROPFIND -H "Depth: 1" https://webdav.yandex.ru/$folder

    Poistaa:

    curl -s -X DELETE --user "$usename:$password" https://webdav.yandex.ru/$folder
  • Toiseksi se on helppo asentaa:
    apt install curl

Ulkoisen IP-osoitteen ja UDP-portin määrittämiseksi käytä stun-client-komentoa:

stun stun.sipnet.ru -v -p $1 2>&1 | grep "MappedAddress"

Asennus komennolla:

apt install stun-client

Tunnelin järjestämiseen käytetään iproute2-paketin vakiokäyttöjärjestelmän työkaluja. Olemassa monia tunneleita jota voidaan nostaa tavallisilla keinoilla (L2TPv3, GRE jne.), mutta valitsin IPIP:n, koska se luo minimaalisen lisäkuormituksen järjestelmään. Kokeilin L2TPv3:a UDP:n yli ja olin pettynyt, nopeus putosi 10 kertaa, mutta nämä voivat olla erilaisia ​​​​palveluntarjoajiin liittyviä rajoituksia tai jotain muuta. Koska IPIP-tunneli toimii IP-tasolla, FOU-tunnelia käytetään toimimaan UDP-porttitasolla. IPIP-tunnelin järjestämiseen tarvitset:

- lataa FOU-moduuli:

modprobe fou

- kuuntele paikallista porttia:

ip fou add port $localport ipproto 4

- luo tunneli:

ip link add name fou$name type ipip remote $remoteip local $localip encap fou  encap-sport $localport encap-dport $remoteport

— nosta tunnelin rajapinta:

ip link set up dev fou$name

— määrittää tunnelin sisäiset paikalliset ja sisäiset etä-IP-osoitteet:

ip addr add $intIP peer $peerip dev fou$name

Tunnelin poistaminen:

ip link del dev fou$name

ip fou del port $localport

Tunnelin tilaa valvotaan pingamalla ajoittain etäsolmun tunnelin sisäistä IP-osoitetta komennolla:

ping -c 1 $peerip -s 0

Säännöllinen ping tarvitaan ensisijaisesti kanavan ylläpitämiseen, muuten tunnelin ollessa käyttämättömänä reitittimien NAT-taulukot voivat tyhjentyä ja yhteys katkeaa.

Jos ping katoaa, IPIP-tunneli poistetaan ja odottaa valmiutta etäisännältä.

Itse käsikirjoitus:

#!/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

muuttujat käyttäjätunnus, salasana и kansio pitäisi olla sama molemmilla puolilla, mutta intip - erilainen, esimerkiksi: 10.0.0.1 ja 10.0.0.2. Solmujen aika on synkronoitava. Voit ajaa skriptin seuraavasti:

nohup script.sh &

Haluan kiinnittää huomionne siihen, että IPIP-tunneli on vaarallinen siltä kannalta, että liikennettä ei ole salattu, mutta tämä voidaan helposti ratkaista käyttämällä IPsec over tässä artikkelissa, se vaikutti minusta yksinkertaiselta ja ymmärrettävältä.

Olen käyttänyt tätä komentosarjaa yhteyden muodostamiseen työtietokoneeseen useiden viikkojen ajan, enkä ole huomannut mitään ongelmia. Kätevää sen asettamisen ja unohtamisen kannalta.

Ehkä sinulla on kommentteja ja ehdotuksia, kuuntelen mielelläni.

Спасибо за внимание!

Lähde: will.com

Lisää kommentti