Vad sÀger vi till IPv6-guden?

Korrekt, och vi sÀger samma sak till kryptografins gud idag.
HÀr kommer vi att prata om den okrypterade IPv4-tunneln, men inte om den "varma lampan", utan om den moderna "LED-en". HÀr finns ocksÄ rÄa sockets, och det pÄgÄr arbete med paket i anvÀnderrummet.
Det finns N tunneleringsprotokoll för alla smaker och fÀrger:
- styliga, trendiga, ungdomliga
- multifunktionella, som schweiziska arméknivar, OpenVPN och SSH
- gamla och snÀlla GRE
- maximalt enkla, snabba, helt okrypterade IPIP
- aktivt utvecklande
- mÄnga andra.
Men jag Àr programmerare, sÄ jag ökar N med bara en brÄkdel, och överlÄter utvecklingen av riktiga protokoll till ď-utvecklarna.
I ett Ànnu ofött projekt som jag arbetar med nu, mÄste jag nÄ hostar bakom NAT utifrÄn. Genom att anvÀnda protokoll med vuxen kryptografi, har jag hela tiden haft en kÀnsla av att detta Àr att skjuta med kanoner pÄ sparvar. Eftersom tunneln mestadels anvÀnds för att borra ett hÄl i NAT:en, Àr den interna trafiken vanligtvis ocksÄ krypterad, man satsar ÀndÄ pÄ HTTPS.
NÀr jag undersökte olika tunneleringsprotokoll, fÄngade min inre perfektionists uppmÀrksamhet IPIP pÄ grund av dess minimala overhead. Men det har en och en halv betydande nackdel för mina uppgifter:
- det krÀver offentliga IP pÄ bÄda sidor,
- och ingen autentisering.
SÄ perfektionisten satt fast i ett mörkt hörn av skallen, eller dÀr han nu befinner sig.
Och en gÄng lÀste jag artiklar om i Linux, och snubblade över FOU (Foo-over-UDP), dvs. vad som helst inbÀddat i UDP. Just nu stöds bara IPIP och GUE (Generic UDP Encapsulation).
"DĂ€r har vi silverkulan! För mig rĂ€cker det med vanlig IPIP." â tĂ€nkte jag.
I verkligheten visade sig kulan inte vara helt silverfĂ€rgad. InbĂ€ddningen i UDP löser det första problemet â kunder bakom NAT kan nĂ„s utifrĂ„n med en förhandsinstallerad anslutning, men hĂ€r blomstrar en del av IPIPs nĂ€sta nackdel i ett nytt ljus â bakom de synliga offentliga IP och klientens port kan vem som helst frĂ„n det privata nĂ€tverket gömma sig (i ren IPIP finns det inget sĂ„dant problem).
För att lösa detta halvproblem föddes verktyget I den implementeras en egen mekanism för autentisering av den fjÀrranslutna vÀrden, utan att störa den kÀrnfulla FOU, som snabbt och effektivt kommer att hantera paket i kÀrnans utrymme.
Din skript behövs inte!
Okej, om du kÀnner till den offentliga porten och IP-adressen för klienten (till exempel för att sÀkerstÀlla att de inte gÄr vart som helst, NAT försöker mappa portar 1-1), kan du skapa en IPIP-over-FOU-tunnel med följande kommandon, utan nÄgra skript.
pÄ servern:
# ĐĐŸĐŽĐłŃŃĐ·ĐžŃŃ ĐŒĐŸĐŽŃĐ»Ń ŃĐŽŃа 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
pÄ klienten:
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
# Alternativen local, peer, peer_port, dev kan kanske inte stödjas av Àldre kÀrnor, de kan utelÀmnas.
# peer och peer_port anvÀnds för att skapa en anslutning direkt nÀr FOU-lyssnaren skapas.
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
ipipou*â namnet pĂ„ det lokala tunnel-nĂ€tverksgrĂ€nssnittet203.0.113.1â den offentliga IP-adressen för servern198.51.100.2â den offentliga IP-adressen för klienten192.168.0.2â klientens IP-adress tilldelad grĂ€nssnittet eth010001â klientens lokala port för FOU20001â klientens offentliga port för FOU10000â serverns offentliga port för FOUencap-csumâ alternativ för att lĂ€gga till en kontrollsumma i inkapslade UDP-paket; kan bytas ut motnoencap-csum, sĂ„ att det inte berĂ€knas, integriteten kontrolleras av det yttre inkapslingslagret (sĂ„ lĂ€nge paketet befinner sig inom tunneln)eth0â den lokala grĂ€nssnitt dĂ€r ipip-tunneln kommer att kopplas172.28.0.1â IP-adressen för klientens tunnelgrĂ€nssnitt (privat)172.28.0.0â IP-adressen för serverns tunnelgrĂ€nssnitt (privat)
SĂ„ lĂ€nge UDP-anslutningen lever, kommer tunneln att förbli i fungerande tillstĂ„nd, men nĂ€r den bryts Ă€r det som det Ă€r â om IP: porten för klienten förblir densamma â kommer det att fungera, om de Ă€ndras â bryts den.
Det Àr enklast att ÄterstÀlla allt genom att ladda ur kÀrnmodulerna: modprobe -r fou ipip
Ăven om autentisering inte krĂ€vs, Ă€r offentliga IP-adresser och klientportar inte alltid kĂ€nda och Ă€r ofta oförutsĂ€gbara eller förĂ€nderliga (beroende pĂ„ typ av NAT). Om man utelĂ€mnar encap-dport pĂ„ servern, kommer tunneln inte att fungera, den Ă€r inte tillrĂ€ckligt smart för att ta den fjĂ€rranslutna porten för anslutningen. I sĂ„dana fall kan ipipou ocksĂ„ hjĂ€lpa, eller sĂ„ kan WireGuard och dess alternativ vara till hjĂ€lp.
Hur fungerar det?
Klienten (som vanligt bakom en NAT) etablerar en tunnel (som i exemplet ovan) och skickar en autentisering paket till servern för att konfigurera tunneln frÄn sin sida. Beroende pÄ instÀllningarna kan detta vara ett tomt paket (bara sÄ att servern ser den offentliga IP-adressen och portanslutningen), eller med data som servern kan anvÀnda för att identifiera klienten. Data kan vara en enkel lösenfras i ren text (jag kommer att tÀnka pÄ en liknelse med HTTP Basic Auth) eller signerad med en privat nyckel, speciellt formaterade data (i analogi med HTTP Digest Auth, men starkare, se funktionen client_auth i koden).
PÄ servern (sidan med den offentliga IP-adressen) skapar ipipou en hanterare för kön nfqueue vid start och konfigurerar netfilter sÄ att nödvÀndiga paket dirigeras dit de ska: paket som initierar anslutningen gÄr till kön nfqueue, medan [nÀstan] alla andra gÄr direkt till FOU-lyssnaren.
För de som inte Àr insatta, nfqueue (eller NetfilterQueue) Àr en speciell grej för nybörjare som inte kan utveckla kÀrnmoduler, som medel för netfilter (nftables/iptables) gör det möjligt att omdirigera nÀtverkspaket till anvÀndarutrymmet och bearbeta dem dÀr med primitiva verktyg: modifiera (valfritt) och skicka tillbaka dem till kÀrnan, eller slÀnga dem.
För vissa programmeringssprÄk finns det bindningar för att arbeta med nfqueue, men för bash hittade jag inget (heh, inte förvÄnande), sÄ jag var tvungen att anvÀnda python: ipipou anvÀnder .
Om prestanda inte Àr kritisk kan man med hjÀlp av detta enkelt och relativt snabbt skapa egen logik för arbetet med paket pÄ en ganska lÄg nivÄ, till exempel designa experimentella datatransmissionsprotokoll eller trolla lokala och fjÀrrtjÀnster med ovanligt beteende.
Tillsammans med nfqueue fungerar rĂ„a sockets (raw sockets), till exempel nĂ€r tunneln redan Ă€r konfigurerad och FOU lyssnar pĂ„ rĂ€tt port, gĂ„r det inte att skicka ett paket frĂ„n den porten pĂ„ vanligt sĂ€tt â den Ă€r upptagen, men man kan ta och skicka ett godtyckligt genererat paket direkt till nĂ€tverksgrĂ€nssnittet med en rĂ„ socket, Ă€ven om det krĂ€vs lite mer arbete för genereringen av ett sĂ„dant paket. SĂ„ hĂ€r skapas autentiseringspaket i ipipou.
Eftersom ipipou endast bearbetar de första paketen frÄn anslutningen (och Àven de som lyckades smita in i kön innan anslutningen upprÀttades) pÄverkas prestandan nÀstan inte.
SÄ snart ipipou-servern fÄr ett paket som har passerat autentiseringen, skapas tunneln och alla efterföljande paket i anslutningen bearbetas redan av kÀrnan utan att gÄ igenom nfqueue. Om anslutningen har tidsbegrÀnsats, kommer det första paketet för nÀsta att skickas till nfqueue, beroende pÄ instÀllningarna; om detta inte Àr ett autentiseringspaket, utan frÄn den senaste registrerade IP-adressen och klientens port, kan det antingen tillÄtas att gÄ vidare eller kastas bort. Om ett autentiserat paket anlÀnder frÄn nya IP-adresser och portar, omkonfigureras tunneln för att anvÀnda dem.
En vanlig IPIP-over-FOU har ytterligare ett problem nĂ€r den arbetar med NAT â det gĂ„r inte att skapa tvĂ„ IPIP-tunnlar inkapslade i UDP med samma IP, eftersom FOU och IPIP-modulerna Ă€r ganska isolerade frĂ„n varandra. Det vill sĂ€ga, ett par klienter bakom en offentlig IP kan inte ansluta till samma server pĂ„ det sĂ€ttet samtidigt. I framtiden, , kommer detta att lösas pĂ„ kĂ€rnnivĂ„, men det Ă€r osĂ€kert. Under tiden kan NAT-problem hanteras genom NAT â om det sĂ„ hĂ€nder att ett par IP-adresser redan anvĂ€nds av en annan tunnel, kommer ipipou att göra NAT frĂ„n den offentliga till en alternativ privat IP, voila! â du kan skapa tunnlar tills portar tar slut.
Eftersom inte alla paket i anslutningen Àr signerade, Àr denna enkla skyddsmetod sÄrbar för MITM, sÄ om det finns en skurk pÄ vÀgen mellan klienten och servern som kan lyssna pÄ trafiken och styra den, kan denne omdirigera autentiseringspaket via en annan adress och skapa en tunnel frÄn en otillförlitlig vÀrd.
Om nÄgon har idéer om hur man kan ÄtgÀrda detta och samtidigt behÄlla huvudparten av trafiken i kÀrnan, tveka inte - kom med förslag.
För att nÀmna det, har inkapslingen i UDP visat sig vara mycket pÄlitlig. JÀmfört med inkapsling ovanpÄ IP Àr den mycket mer stabil och ofta snabbare trots de extra overheadkostnaderna för UDP-huvudet. Detta beror pÄ att en stor del av vÀrdarna pÄ Internet endast fungerar anstÀndigt med de tre mest populÀra protokollen: TCP, UDP, ICMP. En mÀrkbar del kan helt enkelt avvisa allt annat eller bearbeta det lÄngsammare, eftersom de endast Àr optimerade för dessa tre.
Till exempel, dÀrför byggdes QUICK, pÄ vilket HTTP/3 Àr baserat, just ovanpÄ UDP, och inte ovanpÄ IP.
NÄvÀl, nog med snack, lÄt oss se hur det fungerar i den "verkliga vÀrlden".
Strid
För att efterlikna den verkliga vÀrlden anvÀnds iperf3. NÀr det gÀller hur nÀra verkligheten det Àr, Àr det ungefÀr som att efterlikna den verkliga vÀrlden i Minecraft, men för nu fÄr det duga.
I tÀvlingen deltar:
- referens huvudkanal
- huvudpersonen i denna artikel ipipou
- OpenVPN med autentisering, men utan kryptering
- OpenVPN i "alla inkluderat" lÀge
- WireGuard utan PresharedKey, med MTU=1440 (eftersom endast IPv4)
Teknisk information för nördar
MÀtvÀrden tas med hjÀlp av följande kommandon
pÄ klienten:
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"
# DÀr "-b 12M" Àr bandbredden för huvudkanalen, delad med antal strömmar "-P", för att inte skapa onödiga paket och försÀmra prestanda.
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-latens
ping -c 10 SERVER_IP | tail -1
pÄ servern (startas samtidigt som klienten):
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"
Tunnelkonfiguration
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
klient
/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 (utan kryptering, med autentisering)
server
openvpn --genkey --secret ovpn.key # Sedan mÄste ovpn.key skickas till klienten
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
klient
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 (med kryptering, autentisering, via UDP, precis som det ska vara)
InstÀllt med hjÀlp av
wireguard
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
klient
/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
Resultat
RĂ„ ful tabell
CPU-belastningen pÄ servern Àr inte sÀrskilt representativ, eftersom det körs mÄnga andra tjÀnster som ibland anvÀnder resurser:
proto bandbredd[Mbps] CPU_idle_client[%] CPU_idle_server[%]
# 20 Mbps-kanal frÄn mikrodator (4 kÀrnor) till VPS (1 kÀrna) över Atlanten
# ren
UDP 20.4 99.80 93.34
TCP 19.2 99.67 96.68
ICMP latens min/med/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 latens min/med/max/mdev = 199.562/208.919/220.222/7.905 ms
# openvpn0 (endast autentisering, ingen kryptering)
UDP 19.3 99.89 72.90
TCP 16.1 95.95 88.46
ICMP latens min/med/max/mdev = 191.631/193.538/198.724/2.520 ms
# openvpn (full kryptering, autentisering etc)
UDP 19.6 99.75 72.35
TCP 17.0 94.47 87.99
ICMP latens min/med/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 latens min/med/max/mdev = 217.925/223.601/230.696/3.266 ms
## cirka-1Gbps kanal mellan VPS Europa och USA (1 kÀrna)
# ren
UDP 729 73.40 39.93
TCP 363 96.95 90.40
ICMP latens min/med/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 latens min/med/max/mdev = 107.444/107.523/107.648/0.058 ms
# openvpn0 (endast autentisering, ingen kryptering)
UDP 193 17.51 1.62
TCP 12 95.45 92.80
ICMP latens min/med/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 latens min/med/max/mdev = 107.616/107.788/108.038/0.128 ms
kanal pÄ 20 Mbps


kanal pÄ 1 optimistisk Gbps


I alla fall Àr ipipou ganska nÀra baslinjen i prestanda, och det Àr fantastiskt!
Den okrypterade openvpn-tunneln upptrÀdde ganska konstigt i bÄda fallen.
Om nÄgon vill testa, skulle det vara intressant att höra feedback.
MĂ„ IPv6 och NetPrickle vara med oss!
KĂ€lla: habr.com
