Dat is krekt, wy sille hjoed itselde sizze tsjin de god fan fersifering.
Hjir sille wy prate oer in net-fersifere IPv4-tunnel, mar net oer in "waarme lamp", mar oer in moderne "LED". En d'r flitsen hjir ek rauwe sockets, en der wurdt wurke mei pakketten yn brûkersromte.
D'r binne N tunnelingprotokollen foar elke smaak en kleur:
Mar ik bin in programmeur, dus ik sil N mar in fraksje ferheegje, en de ûntwikkeling fan echte protokollen litte oan Kommersant-ûntwikkelders.
Yn ien ûnberne projektWat ik no doch is om hosts efter NAT fan bûten te berikken. Troch dêrfoar protokollen mei kryptografy foar folwoeksenen te brûken, koe ik it gefoel net skodzje dat it wie as it sjitten fan sparrows út in kanon. Omdat de tunnel wurdt brûkt foar it grutste part allinnich te poke gatten yn NAT-e, ynterne ferkear wurdt meastal ek fersifere, mar se noch ferdrinke yn HTTPS.
By it ûndersykjen fan ferskate tunnelingprotokollen, waard de oandacht fan myn ynderlike perfeksjonist hieltyd wer op IPIP lutsen fanwegen syn minimale overhead. Mar it hat ien en in heal wichtige tekoarten foar myn taken:
it fereasket iepenbiere IP's oan beide kanten,
en gjin autentikaasje foar jo.
Dêrom waard de perfeksjonist weromdreaun yn 'e tsjustere hoeke fan 'e skedel, of wêr't er dêr ek sit.
En dan op in dei, by it lêzen fan artikels oer native stipe tunnels yn Linux kaam ik FOU (Foo-over-UDP) tsjin, d.w.s. wat dan ek, ferpakt yn UDP. Oant no wurde allinich IPIP en GUE (Generic UDP Encapsulation) stipe.
"Hjir is de sulveren kûgel! In ienfâldige IPIP is genôch foar my. - Ik tocht.
De kûgel blykte trouwens net hielendal sulver te wêzen. Ynkapseling yn UDP lost it earste probleem op - jo kinne fan bûten ôf ferbine mei kliïnten efter NAT mei in foarôf fêststelde ferbining, mar hjir bloeit de helte fan 'e folgjende neidiel fan IPIP yn in nij ljocht - efter de sichtbere iepenbiere IP en kliïnthaven fan elkenien út in privee netwurk kin ferbergje (yn suver IPIP bestiet dit probleem net).
Om dit ien en in heal probleem op te lossen, waard it nut berne ipipou. It ymplementearret in selsmakke meganisme foar it autentisearjen fan in host op ôfstân, sûnder de wurking fan 'e kernel FOU te fersteuren, dy't pakketten fluch en effisjint yn kernelromte ferwurkje.
Wy hawwe jo skript net nedich!
Ok, as jo de iepenbiere poarte en IP fan 'e kliïnt kenne (bygelyks elkenien derachter giet net oeral, NAT besiket havens 1-in-1 yn kaart te bringen), kinne jo in IPIP-over-FOU-tunnel meitsje mei de folgjende kommando's, sûnder skripts.
op tsjinner:
# Подгрузить модуль ядра 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
op de klant:
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
wêr
ipipou* - namme fan 'e lokale tunnelnetwurkynterface
203.0.113.1 - iepenbiere IP-tsjinner
198.51.100.2 - iepenbiere IP fan 'e kliïnt
192.168.0.2 - client IP tawiisd oan ynterface eth0
10001 - lokale client haven foar FOU
20001 - iepenbiere client haven foar FOU
10000 - iepenbiere tsjinner haven foar FOU
encap-csum - opsje om in UDP-kontrôlesum ta te foegjen oan ynkapsele UDP-pakketten; kin wurde ferfongen troch noencap-csum, net te ferjitten, yntegriteit wurdt al regele troch de bûtenste ynkapselingslaach (wylst it pakket yn 'e tunnel is)
eth0 - lokale ynterface wêrmei de ipip-tunnel sil wurde bûn
172.28.0.1 - IP fan 'e client tunnel ynterface (privee)
172.28.0.0 - IP-tunnelserverynterface (privee)
Salang't de UDP-ferbining libbet, sil de tunnel yn wurkjende steat wêze, mar as it brekt, sille jo gelok wêze - as de IP-poarte fan 'e kliïnt itselde bliuwt - it sil libje, as se feroarje - it sil brekke.
De maklikste manier om alles werom te kearen is om de kernelmodules út te laden: modprobe -r fou ipip
Sels as autentikaasje net fereaske is, binne de iepenbiere IP en poarte fan 'e kliïnt net altyd bekend en binne faaks ûnfoarspelber of fariabele (ôfhinklik fan it NAT-type). As jo weilitte encap-dport oan de tsjinner kant, de tunnel sil net wurkje, it is net tûk genôch te nimmen de ôfstân ferbining haven. Yn dit gefal kin ipipou ek helpe, of WireGuard en oaren lykas it kinne jo helpe.
Hoe wurket it?
De kliïnt (dy't meastentiids efter NAT is) iepenet in tunnel (lykas yn it foarbyld hjirboppe), en stjoert in autentikaasjepakket nei de tsjinner, sadat it de tunnel oan 'e kant konfigurearret. Ofhinklik fan 'e ynstellings kin dit in leech pakket wêze (krekt sadat de tsjinner de iepenbiere IP: ferbiningspoarte sjen kin), of mei gegevens wêrmei't de tsjinner de kliïnt identifisearje kin. De gegevens kinne in ienfâldige passphrase wêze yn dúdlike tekst (de analogy mei HTTP Basic Auth komt yn 't sin) of spesjaal ûntworpen gegevens ûndertekene mei in privee kaai (lykas HTTP Digest Auth allinich sterker, sjoch funksje client_auth yn de koade).
Op 'e tsjinner (de kant mei it iepenbiere IP), as ipipou begjint, makket it in nfqueue-wachtrige handler en konfigurearret netfilter sadat de nedige pakketten stjoerd wurde wêr't se moatte wêze: pakketten dy't de ferbining mei de nfqueue-wachtrige initialisearje, en [hast] al de rest giet direkt nei de harker FOU.
Foar dyjingen dy't it net witte, is nfqueue (as NetfilterQueue) in spesjaal ding foar amateurs dy't net witte hoe't se kernelmodules ûntwikkelje moatte, wêrmei jo netfilter (nftables / iptables) kinne omliede netwurkpakketten nei brûkersromte en ferwurkje se dêr mei primitive middels by de hân: wizigje (opsjoneel) en jou it werom nei de kearn, of ferwiderje it.
Foar guon programmeartalen binne d'r bindingen foar wurkjen mei nfqueue, foar bash wie d'r gjin (heh, net ferrassend), ik moast python brûke: ipipou brûkt NetfilterQueue.
As prestaasje net kritysk is, mei dit ding kinne jo relatyf fluch en maklik jo eigen logika meitsje foar it wurkjen mei pakketten op in frij leech nivo, bygelyks eksperimintele gegevensferfierprotokollen oanmeitsje, of lokale en op ôfstân tsjinsten mei net-standert gedrach trollje.
Raw sockets wurkje hân yn hân mei nfqueue, bygelyks, as de tunnel al konfigurearre is en FOU harket op 'e winske poarte, kinne jo net op 'e gewoane manier in pakket fan deselde haven stjoere - it is drok, mar jo kinne nimme en stjoer in willekeurich oanmakke pakket direkt nei it netwurk ynterface mei help fan in rau socket, hoewol't it generearjen fan sa'n pakket sil fereaskje in bytsje mear tinken. Dit is hoe't pakketten mei autentikaasje wurde makke yn ipipou.
Om't ipipou allinich de earste pakketten fan 'e ferbining ferwurket (en dejingen dy't yn 'e wachtrige slaggen te lekken foardat de ferbining waard oprjochte), hat prestaasjes hast net lije.
Sadree't de ipipou-tsjinner in authentisearre pakket ûntfangt, wurdt in tunnel makke en alle folgjende pakketten yn 'e ferbining binne al ferwurke troch de kernel dy't nfqueue omgiet. As de ferbining mislearret, dan sil it earste pakket fan 'e folgjende stjoerd wurde nei de nfqueue-wachtrige, ôfhinklik fan' e ynstellings, as it net in pakket is mei autentikaasje, mar fan 'e lêste ûnthâlde IP en client-poarte, kin it trochjûn wurde op of ôfset. As in authentisearre pakket komt fan in nije IP en poarte, wurdt de tunnel opnij konfigureare om se te brûken.
De gewoane IPIP-over-FOU hat noch ien probleem by it wurkjen mei NAT - it is ûnmooglik om twa IPIP-tunnels te meitsjen ynkapsele yn UDP mei deselde IP, om't de FOU- en IPIP-modules frijwat isolearre binne fan elkoar. Dy. in pear kliïnten efter deselde iepenbiere IP sil net tagelyk kinne ferbine mei deselde tsjinner op dizze manier. Yn de takomst, mooglik, it sil oplost wurde op it kernelnivo, mar dit is net wis. Yn 'e tuskentiid kinne NAT-problemen wurde oplost troch NAT - as it bart dat in pear IP-adressen al beset binne troch in oare tunnel, sil ipipou NAT dwaan fan iepenbier nei in alternatyf privee IP, voila! - jo kinne tunnels oanmeitsje oant de havens op binne.
Omdat Net alle pakketten yn 'e ferbining binne ûndertekene, dan is dizze ienfâldige beskerming kwetsber foar MITM, dus as d'r in smjunt op it paad leit tusken de kliïnt en de tsjinner dy't nei it ferkear harkje kin en it manipulearje kin, kin hy autentike pakketten omliede fia in oar adres en meitsje in tunnel fan in net fertroude host.
As immen ideeën hat oer hoe't jo dit kinne reparearje wylst it grutste part fan it ferkear yn 'e kearn bliuwt, aarf dan net om te praten.
Trouwens, ynkapseling yn UDP hat himsels tige goed bewiisd. Yn ferliking mei ynkapseling oer IP is it folle stabiler en faak flugger nettsjinsteande de ekstra overhead fan 'e UDP-header. Dit komt troch it feit dat de measte hosts op it ynternet allinich goed wurkje mei de trije populêrste protokollen: TCP, UDP, ICMP. It taastbere diel kin al it oare folslein ferwiderje, of it stadiger ferwurkje, om't it allinich foar dizze trije is optimalisearre.
Dit is bygelyks wêrom QUICK, wêrop HTTP/3 basearre is, is makke boppe op UDP, en net boppe IP.
No, genôch wurden, it is tiid om te sjen hoe't it wurket yn 'e "echte wrâld".
Fjildslach
Wurdt brûkt om de echte wrâld te emulearjen iperf3. Wat de mjitte fan tichtby de realiteit oanbelanget, is dit sawat itselde as it emulearjen fan 'e echte wrâld yn Minecraft, mar foar no sil it dwaan.
Dielnimmers oan de kompetysje:
ferwizing wichtichste kanaal
de held fan dit artikel is ipipou
OpenVPN mei autentikaasje mar gjin fersifering
OpenVPN yn all-inclusive modus
WireGuard sûnder PresharedKey, mei MTU = 1440 (sûnt IPv4-allinnich)
Technyske gegevens foar geeks Metriken wurde nommen mei de folgjende kommando's:
op de klant:
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", чтобы лишние пакеты не плодить и не портить производительность.