ipipou: zifratu gabeko tunel bat baino gehiago

Zer esaten diogu IPv6ren Jainkoari?

ipipou: zifratu gabeko tunel bat baino gehiago
Hori bai, gauza bera esango diogu gaur zifraketaren jainkoari.

Hemen zifratu gabeko IPv4 tunel bati buruz hitz egingo dugu, baina ez "lanpara bero" bati buruz, "LED" moderno bati buruz baizik. Eta entxufe gordinak ere badaude hemen keinuka, eta lanean ari dira erabiltzaileen espazioan paketeekin.

N tunel-protokolo daude zapore eta kolore guztietarako:

  • dotorea, modan, gaztea WireGuard
  • funtzio anitzekoa, Suitzako labanak, OpenVPN eta SSH bezalakoak
  • zaharra eta ez gaiztoa GRE
  • IPIP sinpleena, azkarrena eta guztiz zifratu gabea
  • aktiboki garatzen Geneve
  • beste asko.

Baina programatzailea naiz, beraz, N zati batean bakarrik handituko dut eta benetako protokoloen garapena Kommersant-eko garatzaileen esku utziko dut.

Jaio gabeko batean proiektuaOrain egiten ari naizena da kanpotik NAT atzean dauden ostalarietara iristea. Helduen kriptografia duten protokoloak erabiliz, ezin izan nuen kanoi batetik txolarreak jaurtitzea bezalakoa zelako sentsazioa kendu. Zeren tunela gehienetan NAT-e-n zuloak egiteko bakarrik erabiltzen da, barne-trafikoa ere enkriptatu ohi da, baina hala ere HTTPS-n itotzen dira.

Hainbat tunel-protokolo ikertzen ari nintzela, nire barne perfekzionistaren arreta IPIPra erakarri zen behin eta berriz, bere gainkostu minimoagatik. Baina eragozpen esanguratsu bat eta erdi ditu nire zereginetarako:

  • IP publikoak behar ditu bi aldeetan,
  • eta zuretzako autentifikaziorik ez.

Hori dela eta, perfekzionista garezurraren izkina ilunera eraman zuten, edo bertan eserita dagoen tokira.

Eta gero egun batean, artikuluak irakurtzen ari zaren bitartean berez onartzen diren tunelak Linuxen FOU (Foo-over-UDP) topatu nuen, hau da. dena dela, UDPn bilduta. Orain arte, IPIP eta GUE (Generic UDP Encapsulation) bakarrik onartzen dira.

«Hona hemen zilarrezko bala! IPIP soil bat nahikoa da niretzat». - Uste nuen.

Izan ere, bala ez zen guztiz zilarrezkoa izan. UDP-n kapsulatzeak lehen arazoa konpontzen du - NAT atzean dauden bezeroekin konekta zaitezke kanpotik aurrez ezarritako konexio bat erabiliz, baina hemen IPIPren hurrengo eragozpenaren erdia argi berri batean loratzen da - sare pribatuko edonor ezkuta daiteke ikusgaiaren atzean. IP publikoa eta bezeroaren ataka (IPIP hutsean arazo hau ez da existitzen).

Arazo eta erdi hau konpontzeko, utilitatea sortu zen ipipou. Etxean egindako mekanismo bat ezartzen du urruneko ostalari bat autentifikatzeko, nukleoaren FOUaren funtzionamendua eten gabe, zeinak kernel espazioan dauden paketeak azkar eta eraginkortasunez prozesatuko dituena.

Ez dugu zure gidoia behar!

Ados, bezeroaren ataka publikoa eta IP ezagutzen badituzu (adibidez, haren atzean dauden guztiak ez doaz inora, NAT 1-en-1eko portuak mapatzen saiatzen da), IPIP-over-FOU tunel bat sor dezakezu. ondorengo komandoak, inolako scriptik gabe.

zerbitzarian:

# Подгрузить модуль ядра 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

bezeroarengan:

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

non

  • ipipou* — tunel lokaleko sareko interfazearen izena
  • 203.0.113.1 — IP zerbitzari publikoa
  • 198.51.100.2 — bezeroaren IP publikoa
  • 192.168.0.2 — eth0 interfazeari esleitutako bezeroaren IP
  • 10001 — FOUren tokiko bezero portua
  • 20001 — FOUren bezero-portu publikoa
  • 10000 — FOUren zerbitzari publikoko ataka
  • encap-csum — kapsulatutako UDP paketeei UDP checksum bat gehitzeko aukera; ordezkatu daiteke noencap-csum, zer esanik ez, osotasuna kanpoko kapsulazio geruzak kontrolatzen du jada (paketea tunelaren barruan dagoen bitartean)
  • eth0 — ipip tunela lotuko den interfaze lokala
  • 172.28.0.1 — Bezeroaren tunelaren interfazearen IP (pribatua)
  • 172.28.0.0 - IP tunelaren zerbitzariaren interfazea (pribatua)

UDP konexioa bizirik dagoen bitartean, tunela funtzionamenduan egongo da, baina hausten bada, zortea izango duzu - bezeroaren IP: ataka berdina izaten jarraitzen badu - biziko da, aldatzen badira - hautsi egingo da.

Dena itzultzeko modurik errazena nukleoaren moduluak deskargatzea da: modprobe -r fou ipip

Autentifikazioa beharrezkoa ez bada ere, bezeroaren IP publikoa eta ataka ez dira beti ezagutzen eta askotan ezustekoak edo aldagarriak dira (NAT motaren arabera). Baztertzen baduzu encap-dport zerbitzariaren aldean, tunelak ez du funtzionatuko, ez da nahikoa adimentsua urruneko konexio ataka hartzeko. Kasu honetan, ipipouk ere lagun zaitzake, edo WireGuard eta antzeko beste batzuek lagundu diezazukete.

Nola funtzionatzen du?

Bezeroak (normalean NAT atzean dagoena) tunel bat irekitzen du (goiko adibidean bezala), eta autentifikazio-pakete bat bidaltzen dio zerbitzariari, tunela bere alboan konfigura dezan. Ezarpenen arabera, pakete huts bat izan daiteke (zerbitzariak IP publikoa ikus dezan: konexio ataka), edo zerbitzariak bezeroa identifikatzeko datuekin. Datuak pasaesaldi soil bat izan daitezke testu argian (HTTP Basic Auth-ekin analogia datorkit burura) edo bereziki diseinatutako datuak gako pribatu batekin sinatutakoak (HTTP Digest Auth-en antzekoa soilik sendoagoa, ikusi funtzioa). client_auth kodean).

Zerbitzarian (IP publikoa duen aldean), ipipou abiaraztean, nfqueue ilararen kudeatzailea sortzen du eta netfilter konfiguratzen du beharrezko paketeak behar diren tokira bidaltzeko: paketeak nfqueue ilararako konexioa hasieratzen duten eta [ia] gainontzeko guztiak zuzenean entzulearengana doaz FOU.

Ezagutzen ez dutenentzat, nfqueue (edo NetfilterQueue) gauza berezia da nukleoaren moduluak garatzen ez dakiten afizionatuentzat, netfilter erabiliz (nftables/iptables) sare-paketeak erabiltzailearen espaziora birbideratzeko eta bertan prozesatzeko aukera ematen baitu. primitiboak eskura esan nahi du: aldatu (aukerakoa) eta itzuli nukleoari, edo baztertu.

Programazio-lengoaia batzuentzat nfqueue-rekin lan egiteko loturak daude, bash-erako ez zegoen bat ere (je, ez da harritzekoa), python erabili behar izan nuen: ipipou-k erabiltzen du NetfilterQueue.

Errendimendua ez bada kritikoa, gauza hau erabiliz zure logika nahiko azkar eta erraz asma dezakezu paketeekin lan egiteko maila nahiko baxuan, adibidez, datuak transferitzeko protokolo esperimentalak sortu edo tokiko eta urruneko zerbitzuak troll jokabide ez-estandarra duten.

Raw-entxufeek nfqueue-rekin batera funtzionatzen dute, adibidez, tunela dagoeneko konfiguratuta dagoenean eta FOU nahi duzun portuan entzuten ari denean, ezin izango duzu paketerik bidali ataka beretik ohiko moduan - okupatuta dago, baina ausaz sortutako pakete bat zuzenean sareko interfazera hartu eta bidali dezakezu socket gordina erabiliz, nahiz eta pakete hori sortzeak apur bat gehiago egin beharko duen. Horrela sortzen dira autentifikazioa duten paketeak ipipou-n.

Ipipou-k konexioko lehen paketeak soilik prozesatzen dituenez (eta konexioa ezarri aurretik ilaran filtratzea lortu zutenak), errendimenduak ez du ia kalterik egiten.

Ipipou zerbitzariak autentifikatu pakete bat jaso bezain laster, tunel bat sortzen da eta konexioan hurrengo pakete guztiak jada prozesatzen ditu nukleoak nfqueue saihestuz. Konexioak huts egiten badu, hurrengoaren lehen paketea nfqueue ilara bidaliko da, ezarpenen arabera, autentifikaziodun pakete bat ez bada, baina gogoratutako azken IP eta bezero portutik, pasa daiteke. gainean edo baztertu. Autentifikatutako pakete bat IP eta ataka berri batetik badator, tunela berriro konfiguratuko da haiek erabiltzeko.

Ohiko IPIP-over-FOU-k arazo bat gehiago du NAT-ekin lan egiten denean - ezinezkoa da IPIP berarekin UDPn kapsulatutako bi IPIP tunel sortzea, FOU eta IPIP moduluak elkarrengandik nahiko isolatuta daudelako. Horiek. IP publiko beraren atzean dagoen bezero pare bat ezin izango da aldi berean zerbitzari berdinera konektatu modu honetan. Etorkizunean, agian, nukleo mailan konponduko da, baina hori ez da ziurra. Bitartean, NAT-en arazoak NAT bidez konpondu daitezke - IP helbide pare bat dagoeneko beste tunel batek okupatuta dagoela gertatzen bada, ipipou-k NAT egingo du IP publiko alternatibo batera, voila! - tunelak sor ditzakezu portuak agortu arte.

Zeren Konexioko pakete guztiak ez daude sinatuta, orduan babes sinple hau MITMrentzat zaurgarria da, beraz, trafikoa entzun eta manipulatu dezakeen bezeroaren eta zerbitzariaren arteko bidean zital bat badago, autentifikatutako paketeak birbideratu ditzake. beste helbide bat eta sortu tunel bat fidagarria ez den ostalari batetik .

Inork hau konpontzeko ideiak baditu trafikoaren zatirik handiena muinean utzita, ez izan zalantzarik hitz egiteko.

Bide batez, UDPn kapsulatzea oso ondo frogatu da. IP bidezko kapsulatzearekin alderatuta, askoz egonkorragoa eta askotan azkarragoa da UDP goiburuaren gainkostua izan arren. Hau da, Interneteko ostalari gehienek ondo funtzionatzen dutelako hiru protokolo ezagunenekin soilik: TCP, UDP, ICMP. Zati ukigarriak beste guztia guztiz baztertu dezake, edo polikiago prozesatu, hiru hauetarako soilik optimizatuta baitago.

Esate baterako, horregatik sortu da QUICK, HTTP/3-n oinarritzen dena, UDPren gainean, eta ez IParen gainean.

Beno, nahikoa hitz, "mundu errealean" nola funtzionatzen duen ikusteko garaia da.

Borroka

Mundu erreala imitatzeko erabiltzen da iperf3. Errealitatearekiko hurbiltasun mailari dagokionez, gutxi gorabehera Minecraft-en mundu erreala emulatzea bezalakoa da, baina oraingoz hala izango da.

Lehiaketan parte hartzaileak:

  • erreferentziazko kanal nagusia
  • artikulu honen heroia ipipou da
  • OpenVPN autentifikazioarekin baina enkriptaziorik gabe
  • OpenVPN modu osoa barnean
  • WireGuard PresharedKey gabe, MTU=1440 (IPv4-tik soilik)

Geekentzako datu teknikoak
Metrikoak komando hauekin hartzen dira:

bezeroarengan:

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 latentzia

ping -c 10 SERVER_IP | tail -1

zerbitzarian (bezeroarekin batera exekutatzen da):

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"

Tunelaren konfigurazioa

ipipou
zerbitzaria
/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

bezeroa
/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 (zifratzerik gabe, autentifikazioarekin)
zerbitzaria

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

bezeroa

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 (enkriptatzearekin, autentifikazioarekin, UDP bidez, dena espero bezala)
Erabiliz konfiguratuta openvpn-kudeatu

harilaguna
zerbitzaria
/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

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

Findings

Seinale itsusi hezea
Zerbitzariaren CPU karga ez da oso adierazgarria, zeren... Beste zerbitzu asko daude martxan, batzuetan baliabideak jaten dituzte:

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 kanala

ipipou: zifratu gabeko tunel bat baino gehiago

ipipou: zifratu gabeko tunel bat baino gehiago

kanal 1 Gbps baikor bakoitzeko

ipipou: zifratu gabeko tunel bat baino gehiago

ipipou: zifratu gabeko tunel bat baino gehiago

Kasu guztietan, ipipou errendimenduan nahiko gertu dago oinarrizko kanaletik, eta hori bikaina da!

Zifratu gabeko openvpn tunelak nahiko arraro jokatu zuen bi kasuetan.

Norbaitek proba egingo badu, interesgarria izango da iritzia entzutea.

IPv6 eta NetPrickle gurekin izan daitezela!

Iturria: www.habr.com

Gehitu iruzkin berria