ipipou: shifrlanmagan tunneldan ham ko'proq

Biz IPv6 Xudosiga nima deymiz?

ipipou: shifrlanmagan tunneldan ham ko'proq
To'g'ri, biz bugun shifrlash xudosiga ham shunday deymiz.

Bu erda biz shifrlanmagan IPv4 tunnel haqida gapiramiz, lekin "issiq chiroq" haqida emas, balki zamonaviy "LED" haqida. Shuningdek, bu yerda xom rozetkalar yonib turadi va foydalanuvchi maydonida paketlar bilan ish olib borilmoqda.

Har qanday lazzat va rang uchun N tunnel protokollari mavjud:

  • zamonaviy, moda, yoshlik WireGuard
  • Shveytsariya pichoqlari, OpenVPN va SSH kabi ko'p funktsiyali
  • eski va yomon emas GRE
  • eng oddiy, tezkor, butunlay shifrlanmagan IPIP
  • faol rivojlanmoqda JENEV
  • ko'plab boshqalar.

Ammo men dasturchiman, shuning uchun men N-ni faqat bir qismga oshiraman va haqiqiy protokollarni ishlab chiqishni Kommersant ishlab chiquvchilariga topshiraman.

Bir tug'ilmaganda loyihaHozir men qilayotgan ish NAT ortidagi xostlarga tashqaridan kirishdir. Buning uchun kattalar kriptografiyasi bilan protokollardan foydalanib, men bu to'pdan chumchuqlarni otish kabi tuyg'uni silkita olmadim. Chunki tunnel ko'pincha NAT-e-da teshik ochish uchun ishlatiladi, ichki trafik odatda shifrlangan, ammo ular hali ham HTTPS-da cho'kib ketishadi.

Turli xil tunnel protokollarini o'rganar ekanman, mening ichki perfektsionistimning e'tibori IPIPga minimal yuk tufayli qayta-qayta qaratildi. Ammo mening vazifalarim uchun uning bir yarim muhim kamchiliklari bor:

  • har ikki tomonda ham umumiy IP-larni talab qiladi,
  • va siz uchun autentifikatsiya yo'q.

Shuning uchun, mukammallikchi bosh suyagining qorong'i burchagiga yoki u erda o'tiradigan joyga qaytarildi.

Va keyin bir kuni, maqolalarni o'qiyotganda mahalliy tomonidan qo'llab-quvvatlanadigan tunnellar Linuxda men FOU (Foo-over-UDP) ga duch keldim, ya'ni. nima bo'lishidan qat'iy nazar, UDP bilan o'ralgan. Hozircha faqat IPIP va GUE (Umumiy UDP Encapsulation) qo'llab-quvvatlanadi.

“Mana, kumush o'q! Menga oddiy IPIP yetarli”. - deb o'yladim.

Aslida, o'q butunlay kumush emas edi. UDP-dagi inkapsulyatsiya birinchi muammoni hal qiladi - siz NAT orqasidagi mijozlarga oldindan o'rnatilgan ulanishdan foydalangan holda tashqi tomondan ulanishingiz mumkin, ammo bu erda IPIP-ning keyingi kamchiliklarining yarmi yangi nurda gullaydi - shaxsiy tarmoqdagi har kim ko'rinadigan tarmoq orqasiga yashirinishi mumkin. umumiy IP va mijoz porti (sof IPIPda bu muammo mavjud emas).

Ushbu bir yarim muammoni hal qilish uchun yordamchi dastur tug'ildi ipipou. U yadro maydonida paketlarni tez va samarali qayta ishlovchi FOU yadrosining ishlashini buzmasdan, masofaviy xostni autentifikatsiya qilish uchun uyda ishlab chiqarilgan mexanizmni amalga oshiradi.

Bizga sizning skriptingiz kerak emas!

OK, agar siz mijozning umumiy porti va IP-ni bilsangiz (masalan, uning orqasidagi hamma hech qaerga bormaydi, NAT 1-in-1 portlarini xaritaga solishga harakat qiladi), siz IPIP-over-FOU tunnelini yaratishingiz mumkin. quyidagi buyruqlar, hech qanday skriptlarsiz.

serverda:

# Подгрузить модуль ядра FOU
modprobe fou

# Создать IPIP туннель с инкапсуляцией в FOU.
# Модуль ipip подгрузится автоматически.
ip link add name ipipou0 type ipip 
    remote 198.51.100.2 local 203.0.113.1 
    encap fou encap-sport 10000 encap-dport 20001 
    mode ipip dev eth0

# Добавить порт на котором будет слушать FOU для этого туннеля
ip fou add port 10000 ipproto 4 local 203.0.113.1 dev eth0

# Назначить IP адрес туннелю
ip address add 172.28.0.0 peer 172.28.0.1 dev ipipou0

# Поднять туннель
ip link set ipipou0 up

mijoz haqida:

modprobe fou

ip link add name ipipou1 type ipip 
    remote 203.0.113.1 local 192.168.0.2 
    encap fou encap-sport 10001 encap-dport 10000 encap-csum 
    mode ipip dev eth0

# Опции local, peer, peer_port, dev могут не поддерживаться старыми ядрами, можно их опустить.
# peer и peer_port используются для создания соединения сразу при создании FOU-listener-а.
ip fou add port 10001 ipproto 4 local 192.168.0.2 peer 203.0.113.1 peer_port 10000 dev eth0

ip address add 172.28.0.1 peer 172.28.0.0 dev ipipou1

ip link set ipipou1 up

qayerda

  • ipipou* — mahalliy tunnel tarmoq interfeysining nomi
  • 203.0.113.1 - umumiy IP-server
  • 198.51.100.2 — mijozning umumiy IP manzili
  • 192.168.0.2 — eth0 interfeysiga tayinlangan mijoz IP
  • 10001 — FOU uchun mahalliy mijoz porti
  • 20001 — FOU uchun umumiy mijoz porti
  • 10000 — FOU uchun umumiy server porti
  • encap-csum — kapsullangan UDP paketlariga UDP nazorat summasini qo'shish imkoniyati; bilan almashtirilishi mumkin noencap-csum, eslatib o'tmaslik kerak, yaxlitlik allaqachon tashqi inkapsulyatsiya qatlami tomonidan boshqariladi (paket tunnel ichida bo'lsa)
  • eth0 — ipip tunnel bog'langan mahalliy interfeys
  • 172.28.0.1 — mijoz tunnel interfeysining IP-manzili (xususiy)
  • 172.28.0.0 — IP tunnel server interfeysi (xususiy)

UDP aloqasi tirik ekan, tunnel ish tartibida bo'ladi, lekin agar u buzilib qolsa, omadingiz keladi - agar mijozning IP: porti o'zgarishsiz qolsa - u yashaydi, agar ular o'zgarsa - buziladi.

Hamma narsani orqaga qaytarishning eng oson yo'li yadro modullarini tushirishdir: modprobe -r fou ipip

Agar autentifikatsiya talab etilmasa ham, mijozning umumiy IP va porti har doim ham ma'lum emas va ko'pincha oldindan aytib bo'lmaydigan yoki o'zgaruvchan (NAT turiga qarab). Agar o'tkazib yuborsangiz encap-dport server tomonida tunnel ishlamaydi, masofaviy ulanish portini olish uchun yetarlicha aqlli emas. Bunday holda, ipipou ham yordam berishi mumkin yoki WireGuard va shunga o'xshash boshqalar sizga yordam berishi mumkin.

U qanday ishlaydi?

Mijoz (odatda NAT orqasida joylashgan) tunnelni ochadi (yuqoridagi misolda bo'lgani kabi) va serverga autentifikatsiya paketini yuboradi, shunda u tunnelni o'z tomonida sozlaydi. Sozlamalarga qarab, bu bo'sh paket bo'lishi mumkin (faqat server umumiy IP-ni ko'rishi uchun: ulanish porti) yoki server mijozni aniqlashi mumkin bo'lgan ma'lumotlar bilan. Ma'lumotlar aniq matndagi oddiy parol iborasi bo'lishi mumkin (HTTP Basic Auth bilan o'xshashlik yodga tushadi) yoki maxsus kalit bilan imzolangan maxsus mo'ljallangan ma'lumotlar (HTTP Digest Auth-ga o'xshash faqat kuchliroq, funksiyaga qarang) client_auth kodda).

Serverda (ommaviy IP manzili bo'lgan tomon) ipipou ishga tushganda, u nfqueue navbatini qayta ishlovchini yaratadi va kerakli paketlar bo'lishi kerak bo'lgan joyga yuborilishi uchun tarmoq filtrini sozlaydi: nfqueue navbatiga ulanishni ishga tushiradigan paketlar va [deyarli] qolganlarning hammasi to'g'ridan-to'g'ri tinglovchi FOUga boradi.

Bilmaganlar uchun nfqueue (yoki NetfilterQueue) yadro modullarini qanday ishlab chiqishni bilmagan havaskorlar uchun alohida narsa bo'lib, netfilter (nftables/iptables) yordamida tarmoq paketlarini foydalanuvchi maydoniga yo'naltirish va u erda ularni qayta ishlash imkonini beradi. qo'l ostidagi ibtidoiy vositalar: o'zgartirish (ixtiyoriy) va uni yadroga qaytarib bering yoki uni tashlang.

Ba'zi dasturlash tillari uchun nfqueue bilan ishlash uchun bog'lanishlar mavjud, bash uchun esa yo'q edi (heh, ajablanarli emas), men pythondan foydalanishga majbur bo'ldim: ipipou foydalanadi NetfilterQueue.

Agar unumdorlik muhim bo'lmasa, bu narsadan foydalanib, siz juda past darajadagi paketlar bilan ishlash uchun o'zingizning mantiqingizni nisbatan tez va osonlik bilan to'plashingiz mumkin, masalan, eksperimental ma'lumotlarni uzatish protokollarini yaratishingiz yoki nostandart xatti-harakatlar bilan mahalliy va masofaviy xizmatlarni trollashingiz mumkin.

Xom rozetkalar nfqueue bilan qo'l bilan ishlaydi, masalan, tunnel allaqachon sozlangan va FOU kerakli portda tinglayotgan bo'lsa, siz odatdagidek bir xil portdan paketni yubora olmaysiz - band, lekin siz tasodifiy yaratilgan paketni xom rozetkadan foydalanib to'g'ridan-to'g'ri tarmoq interfeysiga olishingiz va yuborishingiz mumkin, garchi bunday paketni yaratish biroz ko'proq ishlov berishni talab qiladi. Ipipouda autentifikatsiya qilingan paketlar shunday yaratiladi.

Ipipou ulanishdan faqat birinchi paketlarni qayta ishlaganligi sababli (va ulanish o'rnatilgunga qadar navbatga tushishga muvaffaq bo'lganlar), ishlash deyarli yomonlashmaydi.

Ipipou serveri autentifikatsiya qilingan paketni qabul qilishi bilanoq tunnel yaratiladi va ulanishdagi barcha keyingi paketlar nfqueue-ni chetlab o'tgan yadro tomonidan allaqachon qayta ishlanadi. Agar ulanish muvaffaqiyatsiz bo'lsa, keyingisining birinchi paketi sozlamalarga qarab nfqueue navbatiga yuboriladi, agar u autentifikatsiya qilingan paket bo'lmasa, lekin oxirgi eslab qolingan IP va mijoz portidan bo'lsa, uni uzatish mumkin. yoqilgan yoki tashlangan. Agar autentifikatsiya qilingan paket yangi IP va portdan kelgan bo'lsa, tunnel ulardan foydalanish uchun qayta konfiguratsiya qilinadi.

Odatiy IPIP-over-FOU NAT bilan ishlashda yana bir muammoga ega - bir xil IP bilan UDP-ga o'ralgan ikkita IPIP tunnelini yaratish mumkin emas, chunki FOU va IPIP modullari bir-biridan ancha izolyatsiya qilingan. Bular. bir xil umumiy IP orqasidagi bir juft mijoz bir vaqtning o'zida bir xil serverga shu tarzda ulana olmaydi. Kelajakda, ehtimol, u yadro darajasida hal qilinadi, ammo bu aniq emas. Ayni paytda, NAT muammolari NAT tomonidan hal qilinishi mumkin - agar bir juft IP-manzillar boshqa tunnel tomonidan egallab olingan bo'lsa, ipipou NAT-ni ommaviydan muqobil shaxsiy IP-ga o'tkazadi, voila! - portlar tugamaguncha tunnel yaratishingiz mumkin.

Chunki Ulanishdagi barcha paketlar imzolanmagan, bu oddiy himoya MITM uchun zaifdir, shuning uchun mijoz va server o'rtasidagi yo'lda trafikni tinglashi va uni boshqarishi mumkin bo'lgan yovuz odam yashiringan bo'lsa, u autentifikatsiya qilingan paketlarni qayta yo'naltirishi mumkin. boshqa manzil va ishonchsiz xostdan tunnel yaratish.

Agar kimdir traffikning asosiy qismini asosiy qismida qoldirib, buni qanday tuzatish haqida fikrga ega bo'lsa, gapirishdan tortinmang.

Aytgancha, UDP-da inkapsulyatsiya o'zini juda yaxshi isbotladi. IP orqali inkapsulyatsiya bilan solishtirganda, UDP sarlavhasining qo'shimcha yukiga qaramay, u ancha barqaror va tez-tez tezroq. Buning sababi shundaki, Internetdagi ko'pchilik xostlar faqat uchta eng mashhur protokollar bilan yaxshi ishlaydi: TCP, UDP, ICMP. Moddiy qism qolgan hamma narsani butunlay tashlab yuborishi yoki sekinroq ishlov berishi mumkin, chunki u faqat shu uchtasi uchun optimallashtirilgan.

Misol uchun, shuning uchun HTTP/3 asosidagi QUICK IP-ning tepasida emas, balki UDP ustida yaratilgan.

Xo'sh, etarli so'zlar, "haqiqiy dunyoda" qanday ishlashini ko'rish vaqti keldi.

Jang

Haqiqiy dunyoga taqlid qilish uchun ishlatiladi iperf3. Haqiqatga yaqinlik darajasi nuqtai nazaridan, bu Minecraft-da haqiqiy dunyoga taqlid qilish bilan bir xil, ammo hozircha shunday bo'ladi.

Musobaqa ishtirokchilari:

  • asosiy kanalga murojaat qiling
  • ushbu maqolaning qahramoni - ipipou
  • Autentifikatsiya bilan OpenVPN, lekin shifrlanmagan
  • OpenVPN hamma narsani o'z ichiga olgan rejimda
  • PresharedKeysiz WireGuard, MTU=1440 (faqat IPv4 uchun)

Geeks uchun texnik ma'lumotlar
Ko'rsatkichlar quyidagi buyruqlar bilan olinadi:

mijoz haqida:

UDP

CPULOG=NAME.udp.cpu.log; sar 10 6 >"$CPULOG" & iperf3 -c SERVER_IP -4 -t 60 -f m -i 10 -B LOCAL_IP -P 2 -u -b 12M; tail -1 "$CPULOG"
# Где "-b 12M" это пропускная способность основного канала, делённая на число потоков "-P", чтобы лишние пакеты не плодить и не портить производительность.

TCP

CPULOG=NAME.tcp.cpu.log; sar 10 6 >"$CPULOG" & iperf3 -c SERVER_IP -4 -t 60 -f m -i 10 -B LOCAL_IP -P 2; tail -1 "$CPULOG"

ICMP kechikishi

ping -c 10 SERVER_IP | tail -1

serverda (mijoz bilan bir vaqtda ishlaydi):

UDP

CPULOG=NAME.udp.cpu.log; sar 10 6 >"$CPULOG" & iperf3 -s -i 10 -f m -1; tail -1 "$CPULOG"

TCP

CPULOG=NAME.tcp.cpu.log; sar 10 6 >"$CPULOG" & iperf3 -s -i 10 -f m -1; tail -1 "$CPULOG"

Tunnel konfiguratsiyasi

ipipou
server
/etc/ipipou/server.conf:

server
number 0
fou-dev eth0
fou-local-port 10000
tunl-ip 172.28.0.0
auth-remote-pubkey-b64 eQYNhD/Xwl6Zaq+z3QXDzNI77x8CEKqY1n5kt9bKeEI=
auth-secret topsecret
auth-lifetime 3600
reply-on-auth-ok
verb 3

systemctl start ipipou@server

mijozlar
/etc/ipipou/client.conf:

client
number 0
fou-local @eth0
fou-remote SERVER_IP:10000
tunl-ip 172.28.0.1
# pubkey of auth-key-b64: eQYNhD/Xwl6Zaq+z3QXDzNI77x8CEKqY1n5kt9bKeEI=
auth-key-b64 RuBZkT23na2Q4QH1xfmZCfRgSgPt5s362UPAFbecTso=
auth-secret topsecret
keepalive 27
verb 3

systemctl start ipipou@client

openvpn (shifrlashsiz, autentifikatsiya bilan)
server

openvpn --genkey --secret ovpn.key  # Затем надо передать ovpn.key клиенту
openvpn --dev tun1 --local SERVER_IP --port 2000 --ifconfig 172.16.17.1 172.16.17.2 --cipher none --auth SHA1 --ncp-disable --secret ovpn.key

mijozlar

openvpn --dev tun1 --local LOCAL_IP --remote SERVER_IP --port 2000 --ifconfig 172.16.17.2 172.16.17.1 --cipher none --auth SHA1 --ncp-disable --secret ovpn.key

openvpn (shifrlash, autentifikatsiya, UDP orqali, hamma narsa kutilganidek)
yordamida sozlangan openvpn-boshqarish

simni himoya qilish
server
/etc/wireguard/server.conf:

[Interface]
Address=172.31.192.1/18
ListenPort=51820
PrivateKey=aMAG31yjt85zsVC5hn5jMskuFdF8C/LFSRYnhRGSKUQ=
MTU=1440

[Peer]
PublicKey=LyhhEIjVQPVmr/sJNdSRqTjxibsfDZ15sDuhvAQ3hVM=
AllowedIPs=172.31.192.2/32

systemctl start wg-quick@server

mijozlar
/etc/wireguard/client.conf:

[Interface]
Address=172.31.192.2/18
PrivateKey=uCluH7q2Hip5lLRSsVHc38nGKUGpZIUwGO/7k+6Ye3I=
MTU=1440

[Peer]
PublicKey=DjJRmGvhl6DWuSf1fldxNRBvqa701c0Sc7OpRr4gPXk=
AllowedIPs=172.31.192.1/32
Endpoint=SERVER_IP:51820

systemctl start wg-quick@client

Natijalar

Nam yomon belgi
Server protsessorining yuklanishi unchalik ko'rsatkich emas, chunki... U erda boshqa ko'plab xizmatlar mavjud, ba'zida ular resurslarni iste'mol qiladilar:

proto bandwidth[Mbps] CPU_idle_client[%] CPU_idle_server[%]
# 20 Mbps канал с микрокомпьютера (4 core) до VPS (1 core) через Атлантику
# pure
UDP 20.4      99.80 93.34
TCP 19.2      99.67 96.68
ICMP latency min/avg/max/mdev = 198.838/198.997/199.360/0.372 ms
# ipipou
UDP 19.8      98.45 99.47
TCP 18.8      99.56 96.75
ICMP latency min/avg/max/mdev = 199.562/208.919/220.222/7.905 ms
# openvpn0 (auth only, no encryption)
UDP 19.3      99.89 72.90
TCP 16.1      95.95 88.46
ICMP latency min/avg/max/mdev = 191.631/193.538/198.724/2.520 ms
# openvpn (full encryption, auth, etc)
UDP 19.6      99.75 72.35
TCP 17.0      94.47 87.99
ICMP latency min/avg/max/mdev = 202.168/202.377/202.900/0.451 ms
# wireguard
UDP 19.3      91.60 94.78
TCP 17.2      96.76 92.87
ICMP latency min/avg/max/mdev = 217.925/223.601/230.696/3.266 ms

## около-1Gbps канал между VPS Европы и США (1 core)
# pure
UDP 729      73.40 39.93
TCP 363      96.95 90.40
ICMP latency min/avg/max/mdev = 106.867/106.994/107.126/0.066 ms
# ipipou
UDP 714      63.10 23.53
TCP 431      95.65 64.56
ICMP latency min/avg/max/mdev = 107.444/107.523/107.648/0.058 ms
# openvpn0 (auth only, no encryption)
UDP 193      17.51  1.62
TCP  12      95.45 92.80
ICMP latency min/avg/max/mdev = 107.191/107.334/107.559/0.116 ms
# wireguard
UDP 629      22.26  2.62
TCP 198      77.40 55.98
ICMP latency min/avg/max/mdev = 107.616/107.788/108.038/0.128 ms

20 Mbit / s kanal

ipipou: shifrlanmagan tunneldan ham ko'proq

ipipou: shifrlanmagan tunneldan ham ko'proq

1 optimistik Gbit/s uchun kanal

ipipou: shifrlanmagan tunneldan ham ko'proq

ipipou: shifrlanmagan tunneldan ham ko'proq

Barcha holatlarda ipipou ishlash bo'yicha asosiy kanalga juda yaqin, bu ajoyib!

Shifrlanmagan openvpn tunnel ikkala holatda ham o'zini juda g'alati tutdi.

Agar kimdir buni sinab ko'rmoqchi bo'lsa, fikr-mulohazalarni eshitish qiziqarli bo'ladi.

IPv6 va NetPrickle biz bilan bo'lsin!

Manba: www.habr.com

a Izoh qo'shish