ipipou: méi wéi nëmmen en onverschlësselten Tunnel

Wat soen mir zum Gott vun IPv6?

ipipou: méi wéi nëmmen en onverschlësselten Tunnel
Dat ass richteg, mir soen haut datselwecht zum Gott vun der Verschlësselung.

Hei wäerte mir iwwer en onverschlësselte IPv4-Tunnel schwätzen, awer net iwwer eng "waarm Lampe", awer iwwer eng modern "LED". An et sinn och raw Sockets déi hei blénken, an et gëtt geschafft mat Päckchen am Benotzerraum.

Et gi N Tunnelprotokoller fir all Goût a Faarf:

  • stylesch, moudesch, Jugend WireGuard
  • multifunktionell, wéi Schwäizer Messer, OpenVPN an SSH
  • al an net Béisen GRE
  • déi einfach, séier, komplett onverschlësselte IPIP
  • aktiv entwéckelen GENEVE
  • vill anerer.

Mee ech sinn e Programméierer, also wäert ech N nëmmen duerch eng Fraktioun erhéijen, an d'Entwécklung vun echte Protokoller fir Kommersant Entwéckler verloossen.

An engem ongebuerene ProjetWat ech elo maachen ass Hosten hannert NAT vu baussen z'erreechen. Mat Protokoller mat Erwuessener Kryptografie fir dëst ze benotzen, konnt ech d'Gefill net rëselen datt et wier wéi Spatzen aus enger Kanoun ze schéissen. Well den Tunnel gëtt zum gréissten Deel nëmme benotzt fir Lächer an NAT-e ze stéieren, intern Traffic ass normalerweis och verschlësselt, awer se erdrénken nach ëmmer an HTTPS.

Wärend der Recherche vun verschiddenen Tunnelprotokoller gouf d'Opmierksamkeet vu mengem bannenzege Perfektionist ëmmer erëm op IPIP gezunn wéinst senger minimaler Overhead. Awer et huet een an en halleft bedeitend Nodeeler fir meng Aufgaben:

  • et erfuerdert ëffentlech IPs op béide Säiten,
  • a keng Authentifikatioun fir Iech.

Dofir gouf de Perfektionist zréck an déi däischter Ecke vum Schädel gedriwwen, oder wou en och ëmmer do sëtzt.

An dann enges Daags, iwwerdeems liesen Artikelen op gebierteg ënnerstëtzt Tunnel am Linux koum ech op FOU (Foo-over-UDP), d.h. egal, an UDP gewéckelt. Bis elo ginn nëmmen IPIP a GUE (Generic UDP Encapsulation) ënnerstëtzt.

„Hei ass d'Sëlwerkugel! Eng einfach IPIP ass genuch fir mech. - Ech duecht.

Tatsächlech huet sech d'Kugel net ganz sëlwer erausgestallt. Encapsulation an UDP léist den éischte Problem - Dir kënnt mat Clienten hannert NAT vu baussen mat enger pre-etabléierter Verbindung verbannen, awer hei d'Halschent vun den nächsten Nodeeler vun IPIP bléien an engem neie Liicht - jidderee vun engem privaten Netzwierk kann sech hannert dem sichtbare verstoppen ëffentlech IP a Client Hafen (an reng IPIP gëtt dëse Problem net).

Fir dëst een an en halleft Problem ze léisen, gouf d'Utility gebuer ipipou. Et implementéiert en hausgemaachte Mechanismus fir e Fernhost ze authentifizéieren, ouni d'Operatioun vum Kernel FOU ze stéieren, wat séier an effizient Päckchen am Kernelraum veraarbecht.

Mir brauchen Äre Skript net!

Ok, wann Dir den ëffentlechen Hafen an den IP vum Client kennt (zum Beispill jiddereen hannendrun geet néierens, NAT probéiert d'Ports 1-an-1 ze kartéieren), kënnt Dir en IPIP-iwwer-FOU-Tunnel erstellen mat dem folgend Kommandoen, ouni Scripten.

um 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

op de Client:

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

wou

  • ipipou* - Numm vun der lokaler Tunnel Netzwierk Interface
  • 203.0.113.1 - ëffentlechen IP Server
  • 198.51.100.2 - ëffentlech IP vum Client
  • 192.168.0.2 - Client IP zougewisen Interface eth0
  • 10001 - lokal Client port fir FOU
  • 20001 - ëffentleche Client port fir FOU
  • 10000 - ëffentleche Serverport fir FOU
  • encap-csum - Optioun fir en UDP Checksum op verschlësselte UDP Päck ze addéieren; kann duerch ersat ginn noencap-csum, net ze ernimmen, d'Integritéit gëtt scho vun der baussenzeger Enkapselschicht kontrolléiert (während de Paket am Tunnel ass)
  • eth0 - lokal Interface un déi den ipip Tunnel gebonnen ass
  • 172.28.0.1 - IP vum Client Tunnel Interface (privat)
  • 172.28.0.0 - IP Tunnel Server Interface (privat)

Soulaang wéi d'UDP Verbindung lieweg ass, wäert den Tunnel an der Aarbecht sinn, awer wann et brécht, hutt Dir Gléck - wann d'IP vum Client d'selwecht bleift - et wäert liewen, wa se änneren - et brécht.

Deen einfachste Wee fir alles zréckzekréien ass d'Kernelmoduler z'entloossen: modprobe -r fou ipip

Och wann d'Authentifikatioun net erfuerderlech ass, sinn d'ëffentlech IP an den Hafen vum Client net ëmmer bekannt a sinn dacks onberechenbar oder variabel (je no NAT-Typ). Wann Dir loosst encap-dport op der Server Säit funktionnéiert den Tunnel net, et ass net intelligent genuch fir den Fernverbindungshafen ze huelen. An dësem Fall kann ipipou och hëllefen, oder WireGuard an anerer wéi et Iech hëllefen.

Wéi heescht et schaffen?

De Client (deen normalerweis hannert NAT ass) mécht en Tunnel op (wéi am Beispill hei uewen), a schéckt en Authentifikatiounspaket un de Server sou datt en den Tunnel op senger Säit konfiguréiert. Ofhängeg vun den Astellungen, kann dëst en eidele Paket sinn (just sou datt de Server den ëffentleche IP: Verbindungsport kann gesinn), oder mat Daten, duerch déi de Server de Client identifizéieren kann. D'Donnéeë kënnen eng einfach Passphrase am Kloertext sinn (d'Analogie mat HTTP Basic Auth kënnt am Kapp) oder speziell entworf Daten ënnerschriwwen mat engem private Schlëssel (ähnlech wéi HTTP Digest Auth nëmme méi staark, kuckt Funktioun client_auth am Code).

Um Server (déi Säit mat der ëffentlecher IP), wann ipipou ufänkt, erstellt en nfqueue Queue Handler a konfiguréiert Netfilter sou datt déi néideg Päck geschéckt ginn wou se solle sinn: Pakete initialiséieren d'Verbindung mat der nfqueue Schlaang, an [bal] de Rescht geet direkt un den Nolauschterer FOU.

Fir déi, déi net wëssen, nfqueue (oder NetfilterQueue) ass eng speziell Saach fir Amateuren, déi net wëssen wéi Kernel Moduler z'entwéckelen, déi mat Netfilter (nftables / iptables) Iech erlaabt Netzpäck op d'Benotzerraum ze redirectéieren an se do ze veraarbechten primitiv Mëttel bei der Hand: änneren (fakultativ) a gitt et zréck an de Kär, oder entlooss.

Fir e puer Programméierungssprooche ginn et Bindungen fir mat nfqueue ze schaffen, fir Bash war et keng (heh, net iwwerraschend), ech hu Python missen benotzen: ipipou benotzt NetfilterQueue.

Wann d'Performance net kritesch ass, andeems Dir dës Saach benotzt, kënnt Dir relativ séier a liicht Är eege Logik erstellen fir mat Päckchen op engem zimlech nidderegen Niveau ze schaffen, zum Beispill experimentell Datenübertragungsprotokoller erstellen oder lokal a Fernservicer mat net-Standard Verhalen trolléieren.

Raw Sockets funktionnéieren Hand an Hand mat nfqueue, zum Beispill, wann den Tunnel scho konfiguréiert ass an de FOU op de gewënschten Hafen lauschtert, kënnt Dir net e Paket vum selwechten Hafen op déi üblech Manéier schécken - et ass beschäftegt, awer Dir kënnt e zoufälleg generéierte Paket direkt an d'Netzwierkschnëtt huelen a schécken mat engem roude Socket, obwuel d'Generatioun vun esou engem Paket e bësse méi e bësse méi manipuléiere wäert. Dëst ass wéi Pakete mat Authentifikatioun an ipipou erstallt ginn.

Zënter ipipou veraarbecht nëmmen déi éischt Pakete vun der Verbindung (an déi, déi et fäerdeg bruecht hunn an d'Schlaang ze lecken ier d'Verbindung opgestallt gouf), gëtt d'Leeschtung bal net leiden.

Soubal den ipipou-Server en authentifizéierte Paket kritt, gëtt en Tunnel erstallt an all spéider Pakete an der Verbindung si scho veraarbecht vum Kernel, deen nfqueue ëmgeet. Wann d'Verbindung feelt, da gëtt den éischte Paket vum nächsten an d'nfqueue Schlaang geschéckt, ofhängeg vun den Astellungen, wann et net e Paket mat Authentifikatioun ass, awer aus dem leschte erënnert IP a Client Hafen, kann et entweder iwwerginn ginn op oder verworf. Wann en authentifizéierte Paket vun engem neien IP an engem Port kënnt, gëtt den Tunnel nei konfiguréiert fir se ze benotzen.

Déi üblech IPIP-iwwer-FOU huet ee méi Problem wann Dir mat NAT schafft - et ass onméiglech zwee IPIP-Tunnelen ze kreéieren, déi an UDP mat der selwechter IP verschlësselt sinn, well d'FOU- an IPIP-Modulen zimlech vuneneen isoléiert sinn. Déi. e Paar Clienten hannert der selwechter ëffentlecher IP kënnen net gläichzäiteg mam selwechte Server op dës Manéier verbannen. An Zukunft, eventuell, et gëtt um Kernelniveau geléist, awer dëst ass net sécher. An der Tëschenzäit kënnen NAT-Problemer duerch NAT geléist ginn - wann et geschitt datt e Paar IP Adressen scho vun engem aneren Tunnel besat ass, wäert ipipou NAT vun ëffentlecher op eng alternativ privat IP maachen, voila! - Dir kënnt Tunnel erstellen bis d'Ports auslafen.

Well Net all Pakete an der Verbindung sinn ënnerschriwwen, dann ass dësen einfache Schutz vulnérabel fir MITM, also wann et e Béisen um Wee tëscht dem Client an dem Server lauert, deen de Traffic lauschtere kann an et manipuléiere kann, kann hien authentifizéiert Pakete redirectéieren duerch eng aner Adress a erstellt en Tunnel vun engem net zouverléissege Host.

Wann iergendeen Iddien huet wéi dëst ze fixéieren wärend de gréissten Deel vum Traffic am Kär léisst, zéckt net ze schwätzen.

Iwwregens, d'Verkapselung an der UDP huet sech ganz gutt bewisen. Am Verglach mat Verkapselung iwwer IP ass et vill méi stabil an dacks méi séier trotz der zousätzlecher Overhead vum UDP Header. Dëst ass wéinst der Tatsaach datt déi meescht Hosten um Internet nëmme mat den dräi populärste Protokoller funktionnéieren: TCP, UDP, ICMP. Dee konkreten Deel kann alles anescht komplett ofleeën, oder et méi lues veraarbecht, well et nëmme fir dës dräi optimiséiert ass.

Zum Beispill, dofir ass QUICK, op deem HTTP/3 baséiert, uewen op UDP erstallt gouf, an net uewen op IP.

Gutt, genuch Wierder, et ass Zäit ze kucken wéi et an der "realer Welt" funktionnéiert.

Schluecht

Benotzt fir d'real Welt ze emuléieren iperf3. Wat de Grad vun der Proximitéit zu der Realitéit ugeet, ass dëst ongeféier d'selwecht wéi d'Emuléierung vun der realer Welt am Minecraft, awer fir de Moment wäert et maachen.

Participanten am Concours:

  • Referenz Haaptkanal
  • den Held vun dësem Artikel ass ipipou
  • OpenVPN mat Authentifikatioun awer keng Verschlësselung
  • OpenVPN am All-inclusive Modus
  • WireGuard ouni PresharedKey, mat MTU = 1440 (zënter IPv4-nëmmen)

Technesch Donnéeën fir Geeks
Metriken gi mat de folgende Kommandoen geholl:

op de Client:

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", чтобы лишние пакеты не плодить и не портить производительность.

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 latency

ping -c 10 SERVER_IP | tail -1

um Server (läuft gläichzäiteg mam Client):

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"

Tunnel Configuratioun

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

Client
/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 (keng Verschlësselung, mat Authentifikatioun)
Server

openvpn --genkey --secret ovpn.key  # Затем надо передать ovpn.key клиенту
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

Client

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 (mat Verschlësselung, Authentifikatioun, iwwer UDP, alles wéi erwaart)
Konfiguréiert benotzt openvpn-verwalten

Drot Gard
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

Client
/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

Resultater

Fiichteg ellen Zeechen
Server CPU Belaaschtung ass net ganz indikativ, well ... Et gi vill aner Servicer do lafen, heiansdo iessen se Ressourcen:

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

20 Mbps Kanal

ipipou: méi wéi nëmmen en onverschlësselten Tunnel

ipipou: méi wéi nëmmen en onverschlësselten Tunnel

Kanal pro 1 optimistesch Gbps

ipipou: méi wéi nëmmen en onverschlësselten Tunnel

ipipou: méi wéi nëmmen en onverschlësselten Tunnel

An alle Fäll ass ipipou zimmlech no bei der Leeschtung vum Basiskanal, wat super ass!

Den onverschlësselte openvpn Tunnel huet sech a béide Fäll zimlech komesch behuelen.

Wann iergendeen et wäert testen, wäert et interessant sinn Feedback ze héieren.

Mee IPv6 an NetPrickle bei eis sinn!

Source: will.com

Setzt e Commentaire