Ví dụ về đục lỗ UDP đơn giản bằng cách sử dụng đường hầm IPIP

Tốt thời gian trong ngày!

Trong bài viết này tôi muốn cho bạn biết tôi đã triển khai như thế nào (một lần nữa(Đoạn mã Bash để kết nối hai máy tính phía sau NAT bằng công nghệ UDP hole punching, sử dụng hệ điều hành làm ví dụ) Ubuntu/Debian.

Thiết lập kết nối bao gồm một số bước:

  1. Khởi động một nút và đợi nút từ xa sẵn sàng;
  2. Xác định địa chỉ IP bên ngoài và cổng UDP;
  3. Chuyển địa chỉ IP bên ngoài và cổng UDP sang máy chủ từ xa;
  4. Lấy địa chỉ IP bên ngoài và cổng UDP từ máy chủ từ xa;
  5. Tổ chức đường hầm IPIP;
  6. Giám sát kết nối;
  7. Nếu kết nối bị mất, hãy xóa đường hầm IPIP.

Tôi đã suy nghĩ rất lâu và vẫn nghĩ thứ có thể dùng để trao đổi dữ liệu giữa các nút, cách đơn giản và nhanh nhất đối với tôi lúc này là làm việc thông qua Yandex.disk.

  • Thứ nhất, nó rất dễ sử dụng - bạn cần 3 hành động: tạo, đọc, xóa. Với cuộn tròn thì đây là:
    Tạo ra:
    curl -s -X MKCOL --user "$usename:$password" https://webdav.yandex.ru/$folder

    Đọc:

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

    Xóa bỏ:

    curl -s -X DELETE --user "$usename:$password" https://webdav.yandex.ru/$folder
  • Thứ hai, nó rất dễ cài đặt:
    apt install curl

Để xác định địa chỉ IP bên ngoài và cổng UDP, hãy sử dụng lệnh stun-client:

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

Cài đặt bằng lệnh:

apt install stun-client

Để tổ chức một đường hầm, các công cụ hệ điều hành tiêu chuẩn từ gói iproute2 được sử dụng. tồn tại nhiều đường hầm có thể được nâng lên bằng các phương tiện tiêu chuẩn (L2TPv3, GRE, v.v.), nhưng tôi đã chọn IPIP vì nó tạo ra tải bổ sung tối thiểu cho hệ thống. Tôi đã thử L2TPv3 qua UDP và rất thất vọng, tốc độ giảm 10 lần, nhưng đây có thể là những hạn chế khác nhau liên quan đến nhà cung cấp hoặc thứ gì khác. Vì đường hầm IPIP hoạt động ở cấp IP nên đường hầm FOU được sử dụng để hoạt động ở cấp cổng UDP. Để tổ chức đường hầm IPIP, bạn cần:

- tải mô-đun FOU:

modprobe fou

- nghe cổng địa phương:

ip fou add port $localport ipproto 4

- tạo đường hầm:

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

- nâng cao giao diện đường hầm:

ip link set up dev fou$name

— gán địa chỉ IP từ xa nội bộ và nội bộ của đường hầm:

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

Xóa một đường hầm:

ip link del dev fou$name

ip fou del port $localport

Trạng thái đường hầm được giám sát bằng cách định kỳ ping địa chỉ IP nội bộ của đường hầm nút từ xa bằng lệnh:

ping -c 1 $peerip -s 0

Ping định kỳ chủ yếu cần thiết để duy trì kênh, nếu không, khi đường hầm không hoạt động, bảng NAT trên bộ định tuyến có thể bị xóa và sau đó kết nối sẽ bị hỏng.

Nếu ping biến mất thì đường hầm IPIP sẽ bị xóa và chờ máy chủ từ xa sẵn sàng.

Bản thân kịch bản:

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

Biến tên truy nhập, mật khẩu и thư mục nên giống nhau ở cả hai bên, nhưng mách nước - khác nhau, ví dụ: 10.0.0.1 và 10.0.0.2. Thời gian trên các nút phải được đồng bộ hóa. Bạn có thể chạy tập lệnh như thế này:

nohup script.sh &

Tôi muốn bạn chú ý đến thực tế là đường hầm IPIP không an toàn xét từ quan điểm lưu lượng truy cập không được mã hóa, nhưng điều này có thể được giải quyết dễ dàng bằng cách sử dụng IPsec trên bài viết này, nó có vẻ đơn giản và dễ hiểu đối với tôi.

Tôi đã sử dụng tập lệnh này để kết nối với PC làm việc được vài tuần và không nhận thấy bất kỳ vấn đề nào. Thuận tiện trong việc thiết lập nó và quên nó.

Có lẽ bạn sẽ có ý kiến ​​​​và đề xuất, tôi sẽ rất vui khi lắng nghe.

Cảm ơn bạn!

Nguồn: www.habr.com

Mua dịch vụ lưu trữ đáng tin cậy cho các trang web có bảo vệ DDoS, máy chủ VPS VDS 🔥 Mua dịch vụ hosting website đáng tin cậy với bảo vệ DDoS, máy chủ VPS VDS | ProHoster