Mit mondunk az IPv6 istenének?

Igen, és az adatvédelmi istenének is ezt fogjuk mondani ma.
Itt arról lesz szó, hogy nem titkosított IPv4 alagútról beszélünk, nem a régi „meleg lámpásról”, hanem a modern „LED-ről”. Emellett itt nyers socketek is felbukkanak, és csomagokkal dolgozunk a felhasználói térben.
N protokoll létezik az alagútozáshoz, ízlés szerint:
- stílusos, divatos, fiatalos
- multifunkcionális, mint a svájci bicskák, OpenVPN és SSH
- öreg és jámbor GRE
- maximálisan egyszerű, gyors, egyáltalán nem titkosított IPIP
- aktívan fejlődő
- sok más.
De én programozó vagyok, így az N-t csak egy kicsit fogom megnövelni, a valódi protokollok fejlesztését pedig az Ö-developereknek hagyom.
Egy még meg nem született protokollal, ami éppen most készül, el kell érni a NAT mögötti hosztokat kívülről. Ehhez felnőtt titkosítással rendelkező protokollokat használva sosem hagyott el az az érzés, hogy ez mintha ágyúval lőnék verebeket. Mivel az alagutat főleg csak a NAT mögötti lyukak felfedezésére használják, a belső forgalom is általában titkosítva van, hiszen mindenki a HTTPS mellett érvel.
A különböző tunneling protokollok tanulmányozása során a belső perfekcionistám figyelmét folyamatosan az IPIP vonzotta a minimális overhead-jével. De van másfél lényeges hátránya a feladataimhoz:
- két oldalon kell nyilvános IP-címek,
- és nincs semmiféle hitelesítés.
Ezért a perfekcionista visszavonult az agy sötét sarkába, vagy ahol is ül.
Valahogy egyszer, cikkeket olvasva Linuxban rátaláltam a FOU-ra (Foo-over-UDP), azaz valami, ami UDP-be van csomagolva. Jelenleg csak az IPIP és a GUE (Generic UDP Encapsulation) támogatott ebből a valaminek.
"Itt van az ezüst golyó! Nekem egy sima IPIP is bőven elég." — gondoltam.
A valóságban a golyó nem volt teljesen ezüst. Az UDP-be való csomagolás megoldja az első problémát — a NAT mögötti kliensekhez kívülről lehet csatlakozni egy előre beállított kapcsolaton keresztül, de itt az IPIP következő hátrányának fele új fényben pompázik — a látható nyilvános IP és kliensport mögött bárki rejtőzhet a privát hálózatból (tisztán IPIP esetén ez a probléma nem áll fenn).
E téma félig megoldódása érdekében született az . Ebben megvalósult egy házi készítésű távoli host hitelesítési mechanizmus, anélkül, hogy megszakítaná a FOU mag működését, ami gyorsan és hatékonyan fogja kezelni a csomagokat a mag térében.
Nincs szükség a scriptedre!
Oké, ha tudod a kliens nyilvános portját és IP-jét (például mivel a NAT megpróbálja 1-1-ben térképezni a portokat, nem járnak mindenhová), létrehozhatsz IPIP-over-FOU alagutat a következő parancsokkal, mindenféle script nélkül.
a szerveren:
# Подгрузить модуль ядра 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
a kliensen:
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
# A local, peer, peer_port, dev opciók nem támogatottak a régi magoknál, elhagyhatók.
# A peer és peer_port a FOU-hallgató létrehozásához használatos.
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
ahol
ipipou*— a helyi alagúthálózati interfész neve203.0.113.1— a szerver nyilvános IP címe198.51.100.2— a kliens nyilvános IP címe192.168.0.2— a kliens IP címe, amely az eth0 interfészhez van rendelve10001— a kliens helyi portja a FOU-hoz20001— a kliens nyilvános portja a FOU-hoz10000— a szerver nyilvános portja a FOU-hozencap-csum— opció a UDP csomagokba beágyazott ellenőrző összeg hozzáadására; helyettesíthetőnoencap-csum, hogy ne számoljunk, az integritás kifelé van ellenőrizve a beágyazás külső rétegénél (amíg a csomag az alagútban van)eth0— a helyi interfész, amelyhez az ipip alagút hozzá lesz rendelve172.28.0.1— a kliens alagut interfész IP címe (privát)172.28.0.0— a szerver alagut interfész IP címe (privát)
Amíg az UDP kapcsolat él, az alagút működésképes állapotban lesz, ha megszakad, akkor csak szerencse kérdése — ha az IP: a kliens portja változatlan marad, működni fog, ha változik — megszakad.
A legkönnyebben úgy lehet visszavonni mindent, ha eltávolítjuk a kernel modulokat: modprobe -r fou ipip
Még ha a hitelesítés nem is szükséges, a kliens nyilvános IP-je és portja nem mindig ismert, és gyakran kiszámíthatatlan vagy változékony (a NAT típusától függően). Ha kihagyjuk encap-dport a szerver oldalán, az alagút nem fog működni, nem elég okos ahhoz, hogy átvegye a távoli kapcsolat portját. Ebben az esetben az ipipou is segíthet, vagy a WireGuard és társai is a segítségedre lehetnek.
Hogyan működik ez?
A kliens (ami általában a NAT mögött van) alagutat állít fel (ahogy a fenti példa mutatja), és elküld egy hitelesítési csomagot a szervernek, hogy az is beállítsa az alagutat a saját oldalán. A beállításoktól függően ez lehet egy üres csomag (csak hogy a szerver lássa a nyilvános IP-t: a kapcsolat portját), vagy olyan adatokkal, amelyek alapján a szerver azonosítani tudja a klienst. Az adatok lehetnek egyszerű jelszó kifejezések, vagy nyilvános kulccsal aláírt speciálisan formázott adatok, hasonlóan a HTTP Digest Auth-hoz, de erősebb formában, lásd a funkciókódot. client_auth a kódban).
A szerveren (a nyilvános IP oldalán) az ipipou indításakor létrehoz egy nfqueue feldolgozó rendszert, és beállítja a netfiltert, hogy a szükséges csomagokat a megfelelő helyre irányítsa: a kapcsolat kezdeményezését szolgáló csomagok az nfqueue-ba, míg [majdnem] az összes többi közvetlenül a FOU figyelőre.
Aki nem tudja, az nfqueue (vagy NetfilterQueue) egy speciális eszköz amatőrök számára, akik nem tudják kifejleszteni a kernel modulokat. Ez a netfilter (nftables/iptables) eszközeivel lehetővé teszi, hogy a hálózati csomagokat a felhasználói térbe irányítsuk, és ott primitív eszközökkel feldolgozzuk őket: módosítani (opcionálisan) és visszaadni a kernelnek, vagy eldobni ezeket.
Néhány programozási nyelvhez léteznek kötések az nfqueue használatához, de a bash-hoz nem találtam (hát, nem meglepő), ezért python-t kellett használni: az ipipou a .
segítségével, ha a teljesítmény nem kritikus, ezzel az eszközzel viszonylag gyorsan és egyszerűen készíthetsz saját logikát a csomagok kezelésére meglehetősen alacsony szinten, például kísérleti adatátviteli protokollok megalkotására, vagy a helyi és távoli szolgáltatások tréfálására nem szabványos viselkedéssel.
A nyers socketek (raw sockets) szorosan együttműködnek az nfqueue-val, például amikor az alagút már be van állítva, és a FOU figyel a megfelelő porton, normális módon nem lehet csomagot küldeni ugyanarról a portról — az foglalt, de lehetőség van arra, hogy tetszőlegesen generált csomagot közvetlenül a hálózati interfészbe küldjünk nyers socket használatával, bár ennek a csomagnak a generálása egy kicsit több munkát igényel. Így készülnek az ipipou-ban a hitelesítési csomagok.
Mivel az ipipou csak a kapcsolat első csomagjait dolgozza fel (és azokat, amelyek a kapcsolat felállítása előtt már bekerültek a sorba) a teljesítmény szinte érintetlen marad.
Amint az ipipou-szerver megkapja a hitelesített csomagot, a tunnel létrejön, és az összes további csomag a kapcsolatban már a kernel által lesz feldolgozva, megkerülve az nfqueue-t. Ha a kapcsolat lejár, a következő első csomag az nfqueue-ba kerül, attól függően, hogy a beállítások mit engednek, ha ez nem a hitelesítő csomag, de az utolsó elmentett IP és a kliens portja, akkor azt vagy elengedhetjük, vagy el kell utasítani. Ha a hitelesített csomag új IP-ről és portról érkezik, a tunnel újra konfigurálódik az új címek használatára.
A hagyományos IPIP-over-FOU-nek van még egy problémája a NAT-tal való működés során — nem lehet két IPIP tunnel-t UDP-be csomagolva ugyanazzal az IP-vel létrehozni, mert a FOU és IPIP modulok eléggé izoláltak egymástól. Vagyis egy pár kliens, aki mögött egy nyilvános IP áll, nem tud egyszerre csatlakozni egy szerverhez ilyen módon. A jövőben, , ezt a kernel szintjén fogják megoldani, de ez még nem biztos. Jelenleg a NAT problémákat NAT-al lehet megoldani — ha előfordul, hogy egy pár IP cím már egy másik tunnel által foglalt, az ipipou végrehajt egy NAT-ot a nyilvános és az alternatív privát IP között, voilà! — lehet tunnel-t létrehozni, amíg a portok el nem fogynak.
Mivel nem minden csomag a kapcsolatban van aláírva, ez az egyszerű védelem sebezhető a MITM támadásokkal szemben, így ha a kliens és a szerver között tanyázik egy rosszindulatú fél, aki hallgatja a forgalmat és irányítja azt, képes lehet átirányítani a hitelesítő csomagokat egy másik címre és létrehozni egy tunnel-t egy megbízhatatlan hosztról.
Ha valakinek van ötlete arra, hogyan lehetne ezt javítani úgy, hogy a legtöbb forgalom a kernelben maradjon, ne habozzon — mondja el a véleményét.
Egyébként az UDP-be való kapszulázás nagyon jól teljesít. Az IP feletti kapszulázáshoz képest sokkal stabilabb és gyakran gyorsabb, a UDP fejlécének plusz költsége ellenére is. Ennek az az oka, hogy az interneten a legtöbb hoszt értelmesen csak a három legnépszerűbb protokollal működik: TCP, UDP, ICMP. Észlelhető részük esetleg teljesen elutasít mindent, vagy lassabban dolgozza fel, mert csak ezekre a háromra van optimalizálva.
Például a QUICK, amelyen az HTTP/3 alapul, pontosan UDP fölött készült, nem pedig IP fölött.
Na jó, elég a szavakból, nézzük meg, hogyan működik ez a 'valós világban'.
Csata
A valós világ szimulálására iperf3. Valósághűségben ez olyan, mint a valós világ szimulációja a Minecraftban, de egyelőre megteszi.
A versenyben részt vevő:
- referencia alapcsatorna
- a cikk hőse ipipou
- OpenVPN hitelesítéssel, de titkosítás nélkül
- OpenVPN "mindent bele" módban
- WireGuard PresharedKey nélkül, MTU=1440 (mivel IPv4 csak)
Technikai adatok a geekek számára
A metrikák ilyen parancsokkal gyűjthetők
a kliensen:
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"
# Ahol "-b 12M" az alapcsatorna sávszélessége elosztva a "-P" szálak számával, hogy felesleges csomagokat ne gerjesszünk és ne rontsuk a teljesítményt.
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 késés
ping -c 10 SERVER_IP | tail -1
a szerveren (együtt fut a klienssel):
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"
Alagút konfiguráció
ipipou
szerver
/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
az ügyfél
/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 (titkosítás nélkül, hitelesítéssel)
szerver
openvpn --genkey --secret ovpn.key # Ezután az ovpn.key-t át kell adni a kliensnek
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
az ügyfél
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 (titkosítással, hitelesítéssel, UDP-n keresztül, minden, ahogy kell)
Beállítva
, telepítjük:
szerver
/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
az ügyfél
/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
Eredmények
Nyers, csúnya táblázat
A szerver CPU terhelése nem nagyon mutatós, mivel sok más szolgáltatás is fut rajta, néha ezek elvonják az erőforrásokat:
prototenysáv sávszélesség[Mbps] CPU_idle_client[%] CPU_idle_server[%]
# 20 Mbps csatorna a mikroszámítógépről (4 mag) a VPS-re (1 mag) az Atlanti-óceánon keresztül
# tiszta
UDP 20,4 99,80 93,34
TCP 19,2 99,67 96,68
ICMP késleltetés min/átlag/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 késleltetés min/átlag/max/mdev = 199,562/208,919/220,222/7,905 ms
# openvpn0 (csak hitelesítés, titkosítás nélkül)
UDP 19,3 99,89 72,90
TCP 16,1 95,95 88,46
ICMP késleltetés min/átlag/max/mdev = 191,631/193,538/198,724/2,520 ms
# openvpn (teljes titkosítás, hitelesítés stb.)
UDP 19,6 99,75 72,35
TCP 17,0 94,47 87,99
ICMP késleltetés min/átlag/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 késleltetés min/átlag/max/mdev = 217,925/223,601/230,696/3,266 ms
## körülbelül 1Gbps csatorna a VPS-ek között Európában és az Egyesült Államokban (1 mag)
# tiszta
UDP 729 73,40 39,93
TCP 363 96,95 90,40
ICMP késleltetés min/átlag/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 késleltetés min/átlag/max/mdev = 107,444/107,523/107,648/0,058 ms
# openvpn0 (csak hitelesítés, titkosítás nélkül)
UDP 193 17,51 1,62
TCP 12 95,45 92,80
ICMP késleltetés min/átlag/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 késleltetés min/átlag/max/mdev = 107,616/107,788/108,038/0,128 ms
csatorna 20 Mbps


csatorna 1 optimista Gbps


Minden esetben az ipipou viszonylag közel áll a alap csatorna paramétereihez, ami nagyszerű!
A titkosítatlan openvpn alagút mindkét esetben meglehetősen furcsán viselkedett.
Ha valaki próbálkozni fog, érdekes lenne hallani a visszajelzéseket.
Legyen velünk az IPv6 és a NetPrickle!
Forrás: habr.com
