Ĝuste, ni diros la samon al la dio de ĉifrado hodiaŭ.
Ĉi tie ni parolos pri neĉifrita IPv4 tunelo, sed ne pri "varma lampo", sed pri moderna "LED". Kaj ankaŭ estas krudaj ingoj fulmantaj ĉi tie, kaj laboro okazas kun pakoj en uzantspaco.
Estas N tunelaj protokoloj por ĉiu gusto kaj koloro:
Sed mi estas programisto, do mi pliigos N nur je frakcio, kaj lasos la disvolviĝon de realaj protokoloj al programistoj de Kommersant.
En unu nenaskita projektoKion mi nun faras, estas atingi gastigantojn malantaŭ NAT de ekstere. Uzante protokolojn kun plenkreska kriptografio por tio, mi ne povis skui la senton, ke ĝi estas kiel pafi paserojn el kanono. Ĉar la tunelo estas uzata plejparte nur por trui en NAT-e, interna trafiko estas kutime ankaŭ ĉifrita, sed ili ankoraŭ dronas en HTTPS.
Dum esplorado de diversaj tunelaj protokoloj, la atento de mia interna perfektisto estis tirita al IPIP ree kaj ree pro ĝia minimuma superkosto. Sed ĝi havas unu kaj duonon gravajn malavantaĝojn por miaj taskoj:
ĝi postulas publikajn IP-ojn ambaŭflanke,
kaj neniu aŭtentigo por vi.
Tial, la perfektisto estis pelita reen en la malhelan angulon de la kranio, aŭ kie ajn li sidas tie.
Kaj tiam unu tagon, dum legado de artikoloj denaske subtenataj tuneloj en Linukso mi renkontis FOU (Foo-over-UDP), t.e. kio ajn, envolvita en UDP. Ĝis nun, nur IPIP kaj GUE (Generic UDP Encapsulation) estas subtenataj.
“Jen la arĝenta kuglo! Simpla IPIP sufiĉas por mi.” - Mi pensis.
Fakte, la kuglo montriĝis ne tute arĝenta. Enkapsuligo en UDP solvas la unuan problemon - vi povas konektiĝi al klientoj malantaŭ NAT de ekstere uzante antaŭestablitan konekton, sed ĉi tie duono de la sekva malavantaĝo de IPIP floras en nova lumo - iu ajn el privata reto povas kaŝi sin malantaŭ la videbla. publika IP kaj klienta haveno (en pura IPIP ĉi tiu problemo ne ekzistas).
Por solvi ĉi tiun unu kaj duonon problemon, la utileco naskiĝis ipipou. Ĝi efektivigas memfaritan mekanismon por aŭtentikigi malproksiman gastiganton, sen interrompi la funkciadon de la kerno FOU, kiu rapide kaj efike prilaboros pakaĵetojn en kernspaco.
Ni ne bezonas vian skripton!
Bone, se vi konas la publikan havenon kaj IP de la kliento (ekzemple, ĉiuj malantaŭ ĝi ne iras ien, NAT provas mapi pordojn 1-en-1), vi povas krei IPIP-super-FOU tunelon kun la sekvaj komandoj, sen ajnaj skriptoj.
sur servilo:
# Подгрузить модуль ядра 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
sur la kliento:
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
kie
ipipou* — nomo de la loka tunela reto-interfaco
203.0.113.1 — publika IP-servilo
198.51.100.2 — publika IP de la kliento
192.168.0.2 — klienta IP asignita al interfaco eth0
10001 — loka klienta haveno por FOU
20001 — publika klienta haveno por FOU
10000 — publika servila haveno por FOU
encap-csum — opcio aldoni UDP-kontrolsumon al enkapsuligitaj UDP-pakaĵoj; povas esti anstataŭigita per noencap-csum, sen mencii, integreco jam estas kontrolita per la ekstera enkapsuliga tavolo (dum la pakaĵeto estas ene de la tunelo)
eth0 — loka interfaco al kiu la ipip-tunelo estos ligita
172.28.0.1 — IP de la klienta tunela interfaco (privata)
Dum la UDP-konekto estos viva, la tunelo estos en funkciado, sed se ĝi rompiĝos, vi estos bonŝanca - se la IP: haveno de la kliento restas la sama - ĝi vivos, se ili ŝanĝiĝos - ĝi rompiĝos.
La plej facila maniero reŝalti ĉion estas malŝarĝi la kernajn modulojn: modprobe -r fou ipip
Eĉ se aŭtentigo ne estas postulata, la publika IP kaj haveno de la kliento ne estas ĉiam konataj kaj ofte estas neantaŭvideblaj aŭ variaj (depende de la NAT-tipo). Se vi preterlasas encap-dport ĉe la servilo, la tunelo ne funkcios, ĝi ne estas sufiĉe inteligenta por preni la foran konektan havenon. En ĉi tiu kazo, ipipou ankaŭ povas helpi, aŭ WireGuard kaj aliaj similaj povas helpi vin.
Kiel ĝi funkcias?
La kliento (kiu kutime estas malantaŭ NAT) malfermas tunelon (kiel en la supra ekzemplo), kaj sendas aŭtentikigpakaĵon al la servilo por ke ĝi agordu la tunelon sur sia flanko. Depende de la agordoj, ĉi tio povas esti malplena pako (nur por ke la servilo povu vidi la publikan IP: konekta haveno), aŭ kun datumoj per kiuj la servilo povas identigi la klienton. La datumoj povas esti simpla pasfrazo en klara teksto (pensas la analogio kun HTTP Basic Auth) aŭ speciale dezajnitaj datumoj subskribitaj per privata ŝlosilo (simila al HTTP Digest Auth nur pli forta, vidu funkcion). client_auth en la kodo).
Sur la servilo (la flanko kun la publika IP), kiam ipipou komenciĝas, ĝi kreas nfqueue queue-traktilon kaj agordas netfilter tiel ke la necesaj pakaĵetoj estas senditaj kie ili devus esti: pakaĵetoj praviganta la konekton al la nfqueue queue, kaj [preskaŭ] ĉiuj ceteraj iras rekte al la aŭskultanto FOU.
Por tiuj, kiuj ne scias, nfqueue (aŭ NetfilterQueue) estas speciala afero por amatoroj, kiuj ne scias kiel evoluigi kernajn modulojn, kiuj uzante netfilter (nftables/iptables) ebligas al vi redirekti retpakaĵojn al uzantspaco kaj prilabori ilin tie uzante primitiva signifas ĉemane: modifi (laŭvola ) kaj redoni ĝin al la kerno, aŭ forĵeti ĝin.
Por iuj programlingvoj ekzistas ligoj por labori kun nfqueue, por bash ne estis (he, ne mirinde), mi devis uzi python: ipipou uzas NetfilterQueue.
Se agado ne estas kritika, uzante ĉi tiun aferon vi povas relative rapide kaj facile elpensi vian propran logikon por labori kun pakaĵetoj je sufiĉe malalta nivelo, ekzemple, krei eksperimentajn transigajn protokolojn, aŭ troli lokajn kaj forajn servojn kun ne-norma konduto.
Krudaj ingoj funkcias man-en-mane kun nfqueue, ekzemple, kiam la tunelo jam estas agordita kaj FOU aŭskultas sur la dezirata haveno, vi ne povos sendi paketon el la sama haveno laŭ la kutima maniero - ĝi estas okupata, sed vi povas preni kaj sendi hazarde generitan pakaĵeton rekte al la reto-interfaco uzante krudan ingon, kvankam generi tian pakaĵeton postulos iom pli da tuŝado. Tiel estas kreitaj pakoj kun aŭtentigo en ipipou.
Ĉar ipipou prilaboras nur la unuajn pakaĵetojn de la konekto (kaj tiujn, kiuj sukcesis liki en la voston antaŭ ol la konekto estis establita), rendimento preskaŭ ne suferas.
Tuj kiam la ipipou-servilo ricevas aŭtentikigitan pakaĵeton, tunelo estas kreita kaj ĉiuj postaj pakoj en la konekto jam estas prilaboritaj de la kerno preterpasante nfqueue. Se la konekto malsukcesas, tiam la unua pako de la sekva estos sendita al la nfqueue-vico, depende de la agordoj, se ĝi ne estas pako kun aŭtentigo, sed de la lasta memorita IP kaj klienta haveno, ĝi povas aŭ esti preterpasita. sur aŭ forĵetita. Se aŭtentikigita pako venas de nova IP kaj haveno, la tunelo estas reagordita por uzi ilin.
La kutima IPIP-over-FOU havas unu plian problemon kiam laboras kun NAT - estas neeble krei du IPIP-tunelojn enkapsuligitajn en UDP kun la sama IP, ĉar la FOU kaj IPIP-moduloj estas sufiĉe izolitaj unu de la alia. Tiuj. paro da klientoj malantaŭ la sama publika IP ne povos samtempe konektiĝi al la sama servilo tiamaniere. Estontece, eble, ĝi estos solvita ĉe la kerna nivelo, sed ĉi tio ne estas certa. Intertempe NAT-problemoj povas esti solvitaj per NAT - se okazas, ke paro da IP-adresoj jam estas okupata de alia tunelo, ipipou faros NAT de publika al alternativa privata IP, voila! - vi povas krei tunelojn ĝis la havenoj finiĝas.
Ĉar Ne ĉiuj pakaĵetoj en la konekto estas subskribitaj, tiam ĉi tiu simpla protekto estas vundebla al MITM, do se estas fiulo kaŝatendanta sur la vojo inter la kliento kaj la servilo, kiu povas aŭskulti la trafikon kaj manipuli ĝin, li povas redirekti aŭtentikigitajn pakaĵojn tra alian adreson kaj kreu tunelon de nefidinda gastiganto.
Se iu havas ideojn pri kiel ripari ĉi tion lasante la plej grandan parton de la trafiko en la kerno, ne hezitu paroli.
Cetere, enkapsuligo en UDP pruvis sin tre bone. Kompare kun enkapsulado super IP, ĝi estas multe pli stabila kaj ofte pli rapida malgraŭ la kroma supraĵo de la UDP-kapo. Ĉi tio estas pro la fakto, ke plej multaj gastigantoj en Interreto funkcias bone nur kun la tri plej popularaj protokoloj: TCP, UDP, ICMP. La palpebla parto povas tute forĵeti ĉion alian, aŭ prilabori ĝin pli malrapide, ĉar ĝi estas optimumigita nur por ĉi tiuj tri.
Ekzemple, jen kial QUICK, sur kiu baziĝas HTTP/3, estis kreita aldone al UDP, kaj ne al IP.
Nu, sufiĉas vortoj, estas tempo por vidi kiel ĝi funkcias en la "reala mondo".
Batalo
Uzita por imiti la realan mondon iperf3. Koncerne la gradon de proksimeco al realeco, ĉi tio estas proksimume la sama kiel kopii la realan mondon en Minecraft, sed nuntempe ĝi faros.
Partoprenantoj en la konkurso:
referenca ĉefa kanalo
la heroo de ĉi tiu artikolo estas ipipou
OpenVPN kun aŭtentigo sed sen ĉifrado
OpenVPN en ĉio-inkluziva reĝimo
WireGuard sen PresharedKey, kun MTU=1440 (ekde IPv4-nur)
Teknikaj datumoj por geeks Metrikoj estas prenitaj per la sekvaj komandoj:
sur la kliento:
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", чтобы лишние пакеты не плодить и не портить производительность.