ipipou: më shumë se thjesht një tunel i pakriptuar
Çfarë po i themi Zotit të IPv6?
Kjo është e drejtë, ne do t'i themi të njëjtën gjë zotit të kriptimit sot.
Këtu do të flasim për një tunel IPv4 të pakriptuar, por jo për një "llambë të ngrohtë", por për një "LED" moderne. Dhe këtu ka edhe priza të papërpunuara, dhe puna është duke u zhvilluar me paketat në hapësirën e përdoruesit.
Ekzistojnë N protokolle tunelimi për çdo shije dhe ngjyrë:
Por unë jam një programues, kështu që do të rris N vetëm me një fraksion dhe do t'ua lë zhvillimin e protokolleve reale zhvilluesve të Kommersant.
Në një të palindur projektiAjo që po bëj tani është të arrij hostet pas NAT nga jashtë. Duke përdorur protokolle me kriptografi të të rriturve për këtë, nuk mund të lëkundema ndjesinë se ishte si të gjuaje harabela nga një top. Sepse tuneli përdoret në pjesën më të madhe vetëm për të hapur vrima në NAT-e, trafiku i brendshëm zakonisht është gjithashtu i koduar, por ato ende mbyten në HTTPS.
Ndërsa hulumtoja protokollet e ndryshme të tunelit, vëmendja e perfeksionistit tim të brendshëm u tërhoq nga IPIP pa pushim për shkak të shpenzimeve të tij minimale. Por ka një të metë e gjysmë domethënëse për detyrat e mia:
kërkon IP publike nga të dyja anët,
dhe nuk ka vërtetim për ju.
Prandaj, perfeksionisti u shty përsëri në cepin e errët të kafkës, ose kudo që ai ulet atje.
Dhe pastaj një ditë, duke lexuar artikuj në tunele të mbështetur në mënyrë vendase në Linux hasa në FOU (Foo-over-UDP), d.m.th. çfarëdo, të mbështjellë me UDP. Deri më tani, mbështeten vetëm IPIP dhe GUE (Generic UDP Encapsulation).
“Këtu është plumbi i argjendtë! Më mjafton një IPIP i thjeshtë.” - Une mendova.
Në fakt, plumbi rezultoi të mos ishte plotësisht i argjendtë. Enkapsulimi në UDP zgjidh problemin e parë - ju mund të lidheni me klientët pas NAT nga jashtë duke përdorur një lidhje të paracaktuar, por këtu gjysma e pengesës tjetër të IPIP lulëzon në një dritë të re - kushdo nga një rrjet privat mund të fshihet pas të dukshmes IP publike dhe porta e klientit (në IPIP të pastër ky problem nuk ekziston).
Për të zgjidhur këtë problem një e gjysmë, lindi shërbimi ipipou. Ai zbaton një mekanizëm të bërë në shtëpi për vërtetimin e një hosti të largët, pa ndërprerë funksionimin e kernelit FOU, i cili do të përpunojë shpejt dhe me efikasitet paketat në hapësirën e kernelit.
Ne nuk kemi nevojë për skenarin tuaj!
Ok, nëse e dini portën publike dhe IP-në e klientit (për shembull, të gjithë pas saj nuk shkojnë askund, NAT përpiqet të hartojë portet 1-në-1), mund të krijoni një tunel IPIP-mbi-FOU me komandat e mëposhtme, pa asnjë skript.
në server:
# Подгрузить модуль ядра 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
mbi klientin:
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
ku
ipipou* — emri i ndërfaqes së rrjetit të tunelit lokal
203.0.113.1 — server IP publik
198.51.100.2 — IP publike e klientit
192.168.0.2 — IP-ja e klientit e caktuar në ndërfaqen eth0
10001 — porti lokal i klientit për FOU
20001 — porta e klientit publik për FOU
10000 — porta e serverit publik për FOU
encap-csum — opsioni për të shtuar një shumë kontrolli UDP në paketat e kapsuluara të UDP; mund të zëvendësohet nga noencap-csum, për të mos përmendur, integriteti tashmë kontrollohet nga shtresa e jashtme e kapsulimit (ndërsa paketa është brenda tunelit)
eth0 — ndërfaqja lokale në të cilën do të lidhet tuneli ipip
172.28.0.1 — IP e ndërfaqes së tunelit të klientit (private)
172.28.0.0 — Ndërfaqja e serverit të tunelit IP (private)
Për sa kohë që lidhja UDP është e gjallë, tuneli do të jetë në gjendje pune, por nëse prishet, do të keni fat - nëse IP: porti i klientit mbetet i njëjtë - ai do të jetojë, nëse ndryshojnë - do të prishet.
Mënyra më e lehtë për të kthyer gjithçka është të shkarkoni modulet e kernelit: modprobe -r fou ipip
Edhe nëse nuk kërkohet vërtetimi, IP-ja dhe porta publike e klientit nuk njihen gjithmonë dhe shpesh janë të paparashikueshme ose të ndryshueshme (në varësi të llojit NAT). Nëse e lëshoni encap-dport në anën e serverit, tuneli nuk do të funksionojë, nuk është mjaft i zgjuar për të marrë portën e lidhjes në distancë. Në këtë rast, ipipou mund të ndihmojë gjithashtu, ose WireGuard dhe të tjerë si ai mund t'ju ndihmojnë.
Si funksionon kjo gjë?
Klienti (i cili është zakonisht pas NAT) hap një tunel (si në shembullin e mësipërm) dhe dërgon një paketë vërtetimi te serveri në mënyrë që ai të konfigurojë tunelin në anën e tij. Në varësi të cilësimeve, kjo mund të jetë një paketë boshe (vetëm që serveri të shohë IP-në publike: portin e lidhjes), ose me të dhëna me të cilat serveri mund të identifikojë klientin. Të dhënat mund të jenë një frazë e thjeshtë kalimi në tekst të qartë (të vjen ndërmend analogjia me HTTP Basic Auth) ose të dhëna të krijuara posaçërisht të nënshkruara me një çelës privat (i ngjashëm me HTTP Digest Auth vetëm më i fortë, shih funksionin client_auth në kod).
Në server (në anën me IP-në publike), kur ipipou fillon, ai krijon një mbajtës të radhës nfqueue dhe konfiguron netfilterin në mënyrë që paketat e nevojshme të dërgohen aty ku duhet të jenë: paketat që inicializojnë lidhjen me radhën nfqueue, dhe [pothuajse] të gjitha të tjerat shkojnë drejt e te dëgjuesi FOU.
Për ata që nuk e dinë, nfqueue (ose NetfilterQueue) është një gjë e veçantë për amatorët që nuk dinë të zhvillojnë module kernel, të cilat duke përdorur netfilter (nftables/iptables) ju lejon të ridrejtoni paketat e rrjetit në hapësirën e përdoruesit dhe t'i përpunoni ato atje duke përdorur mjete primitive në dispozicion: modifiko (opsionale ) dhe ktheje atë në kernel, ose hidhe atë.
Për disa gjuhë programimi ka lidhje për të punuar me nfqueue, për bash nuk kishte asnjë (heh, nuk është për t'u habitur), më duhej të përdor python: ipipou përdor NetfilterQueue.
Nëse performanca nuk është kritike, duke përdorur këtë gjë, ju mund të krijoni relativisht shpejt dhe me lehtësi logjikën tuaj për të punuar me paketa në një nivel mjaft të ulët, për shembull, të krijoni protokolle eksperimentale të transferimit të të dhënave ose të kontrolloni shërbimet lokale dhe të largëta me sjellje jo standarde.
Prizat e papërpunuara punojnë dorë për dore me nfqueue, për shembull, kur tuneli është tashmë i konfiguruar dhe FOU po dëgjon në portën e dëshiruar, nuk do të mund të dërgoni një paketë nga e njëjta port në mënyrën e zakonshme - është e zënë, por ju mund të merrni dhe dërgoni një paketë të krijuar në mënyrë rastësore direkt në ndërfaqen e rrjetit duke përdorur një prizë të papërpunuar, megjithëse gjenerimi i një pakete të tillë do të kërkojë pak më shumë kujdes. Kështu krijohen paketat me vërtetim në ipipou.
Meqenëse ipipou përpunon vetëm paketat e para nga lidhja (dhe ato që arritën të rrjedhin në radhë përpara se të vendosej lidhja), performanca pothuajse nuk vuan.
Sapo serveri ipipou merr një paketë të vërtetuar, krijohet një tunel dhe të gjitha paketat pasuese në lidhje përpunohen tashmë nga kerneli duke anashkaluar nfqueue. Nëse lidhja dështon, atëherë paketa e parë e asaj tjetër do të dërgohet në radhën nfqueue, në varësi të cilësimeve, nëse nuk është një paketë me vërtetim, por nga IP-ja e fundit e kujtuar dhe porta e klientit, mund të kalohet ose mbi ose hedhur poshtë. Nëse një paketë e vërtetuar vjen nga një IP dhe port i ri, tuneli rikonfigurohet për t'i përdorur ato.
IPIP-mbi-FOU i zakonshëm ka një problem më shumë kur punoni me NAT - është e pamundur të krijohen dy tunele IPIP të kapsuluara në UDP me të njëjtën IP, sepse modulet FOU dhe IPIP janë mjaft të izoluara nga njëri-tjetri. ato. një palë klientësh pas të njëjtës IP publike nuk do të mund të lidhen njëkohësisht me të njëjtin server në këtë mënyrë. Në të ardhmen, ndoshta, do të zgjidhet në nivelin e kernelit, por kjo nuk është e sigurt. Ndërkohë, problemet e NAT mund të zgjidhen nga NAT - nëse ndodh që një palë IP adresash tashmë janë të zëna nga një tunel tjetër, ipipou do të bëjë NAT nga publike në një IP alternative private, voila! - mund të krijoni tunele derisa portat të mbarojnë.
Sepse Jo të gjitha paketat në lidhje janë të nënshkruara, atëherë kjo mbrojtje e thjeshtë është e pambrojtur ndaj MITM, kështu që nëse ka një zuzar që fshihet në rrugën midis klientit dhe serverit i cili mund të dëgjojë trafikun dhe ta manipulojë atë, ai mund t'i ridrejtojë paketat e vërtetuara përmes një adresë tjetër dhe krijoni një tunel nga një host i pabesueshëm.
Nëse dikush ka ide se si ta rregullojë këtë duke lënë pjesën më të madhe të trafikut në thelb, mos hezitoni të flisni.
Nga rruga, kapsulimi në UDP është dëshmuar shumë mirë. Krahasuar me kapsulimin mbi IP, ai është shumë më i qëndrueshëm dhe shpesh më i shpejtë pavarësisht nga shpenzimet shtesë të kokës UDP. Kjo për faktin se shumica e hosteve në internet funksionojnë mirë vetëm me tre protokollet më të njohura: TCP, UDP, ICMP. Pjesa e prekshme mund të heqë plotësisht gjithçka tjetër, ose ta përpunojë më ngadalë, sepse është e optimizuar vetëm për këto tre.
Për shembull, kjo është arsyeja pse QUICK, në të cilin bazohet HTTP/3, u krijua në krye të UDP, dhe jo në krye të IP.
Epo, mjaft fjalë, është koha për të parë se si funksionon në "botën reale".
Beteja
Përdoret për të imituar botën reale iperf3. Për sa i përket shkallës së afërsisë me realitetin, kjo është afërsisht e njëjtë me imitimin e botës reale në Minecraft, por tani për tani do të ndodhë.
Pjesëmarrësit në konkurs:
referencë kanali kryesor
heroi i këtij artikulli është ipipou
OpenVPN me vërtetim, por pa kriptim
OpenVPN në modalitetin gjithëpërfshirës
WireGuard pa PresharedKey, me MTU=1440 (që vetëm me IPv4)
Të dhëna teknike për geeks Metrikat merren me komandat e mëposhtme:
mbi klientin:
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", чтобы лишние пакеты не плодить и не портить производительность.
Shenjë e shëmtuar e lagur
Ngarkesa e CPU-së së serverit nuk është shumë treguese, sepse... Ka shumë shërbime të tjera që funksionojnë atje, ndonjëherë ato hanë burime:
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
Kanali 20 Mbps
kanal për 1 Gbps optimist
Në të gjitha rastet, ipipou është mjaft afër në performancë me kanalin bazë, gjë që është e mrekullueshme!
Tuneli i pakriptuar openvpn u soll mjaft çuditshëm në të dyja rastet.
Nëse dikush do ta testojë atë, do të jetë interesante të dëgjosh reagime.