ipipou: vairāk nekā tikai nešifrēts tunelis

Ko mēs sakām IPv6 Dievam?

ipipou: vairāk nekā tikai nešifrēts tunelis
Tieši tā, mēs šodien teiksim to pašu šifrēšanas dievam.

Šeit mēs runāsim par nešifrētu IPv4 tuneli, bet ne par "silto lampu", bet gan par modernu "LED". Un šeit mirgo arī neapstrādātas ligzdas, un notiek darbs ar paketēm lietotāja telpā.

Katrai gaumei un krāsai ir N tunelēšanas protokoli:

  • stilīgs, moderns, jaunība WireGuard
  • daudzfunkcionāli, piemēram, Šveices naži, OpenVPN un SSH
  • vecs un ne ļauns GRE
  • visvienkāršākais, ātrākais, pilnīgi nešifrētais IPIP
  • aktīvi attīstās ŽENĒVE
  • daudzi citi.

Bet es esmu programmētājs, tāpēc N palielināšu tikai par daļu, bet reālu protokolu izstrādi atstāšu Kommersant izstrādātāju ziņā.

Vienā nedzimušajā projektuTas, ko es daru tagad, ir sasniegt saimniekus aiz NAT no ārpuses. Šim nolūkam izmantojot protokolus ar pieaugušo kriptogrāfiju, es nevarēju atbrīvoties no sajūtas, ka tas ir kā izšaut zvirbuļus no lielgabala. Jo tunelis lielākoties tiek izmantots tikai caurumu izduršanai NAT-e, iekšējā trafika parasti arī tiek šifrēta, bet viņi tik un tā slīkst HTTPS.

Pētot dažādus tunelēšanas protokolus, mana iekšējā perfekcionista uzmanība atkal un atkal tika pievērsta IPIP, pateicoties tā minimālajām izmaksām. Bet tai ir pusotrs būtisks trūkums maniem uzdevumiem:

  • tam ir nepieciešamas publiskas IP abās pusēs,
  • un jums nav autentifikācijas.

Tāpēc perfekcionists tika iedzīts atpakaļ galvaskausa tumšajā stūrī vai visur, kur viņš tur sēž.

Un tad kādu dienu, lasot rakstus par sākotnēji atbalstīti tuneļi Linuxā uzgāju FOU (Foo-over-UDP), t.i. vienalga, ietīts UDP. Līdz šim tiek atbalstīti tikai IPIP un GUE (vispārējā UDP iekapsulēšana).

“Šeit ir sudraba lode! Man pietiek ar vienkāršu IPIP. - ES domāju.

Patiesībā lode izrādījās ne pilnībā sudraba. Iekapsulēšana UDP atrisina pirmo problēmu - jūs varat izveidot savienojumu ar klientiem aiz NAT no ārpuses, izmantojot iepriekš izveidotu savienojumu, bet šeit puse no nākamā IPIP mīnusa uzzied jaunā gaismā - ikviens no privātā tīkla var paslēpties aiz redzamā. publisks IP un klienta ports (tīrā IPIP gadījumā šī problēma nepastāv).

Lai atrisinātu šo pusotru problēmu, radās utilīta ipipou. Tas ievieš mājās izveidotu mehānismu attālā resursdatora autentifikācijai, netraucējot kodola FOU darbību, kas ātri un efektīvi apstrādās paketes kodola telpā.

Mums nav vajadzīgs jūsu scenārijs!

Labi, ja zināt klienta publisko portu un IP (piemēram, visi aiz tā nekur nedodas, NAT mēģina kartēt portus 1-in-1), varat izveidot IPIP-over-FOU tuneli ar šādas komandas, bez skriptiem.

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

par klientu:

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

kur

  • ipipou* — vietējā tuneļa tīkla saskarnes nosaukums
  • 203.0.113.1 — publiskais IP serveris
  • 198.51.100.2 — klienta publiskais IP
  • 192.168.0.2 — klienta IP, kas piešķirts saskarnei eth0
  • 10001 — FOU vietējā klienta osta
  • 20001 — publiskā klienta ports FOU
  • 10000 — publiskā servera ports FOU
  • encap-csum — iespēja pievienot UDP kontrolsummu iekapsulētajām UDP paketēm; var aizstāt ar noencap-csum, nemaz nerunājot, integritāti jau kontrolē ārējais iekapsulēšanas slānis (kamēr pakete atrodas tunelī)
  • eth0 — lokālais interfeiss, ar kuru tiks saistīts ipip tunelis
  • 172.28.0.1 — klienta tuneļa saskarnes IP (privāts)
  • 172.28.0.0 — IP tuneļa servera saskarne (privāts)

Kamēr UDP savienojums būs dzīvs, tunelis būs darba kārtībā, bet ja plīsīs, tad paveiksies - ja klienta IP: ports paliks tas pats - dzīvos, ja mainīsies - plīsīs.

Vienkāršākais veids, kā visu pagriezt atpakaļ, ir izlādēt kodola moduļus: modprobe -r fou ipip

Pat ja autentifikācija nav nepieciešama, klienta publiskais IP un ports ne vienmēr ir zināmi un bieži vien ir neparedzami vai mainīgi (atkarībā no NAT veida). Ja jūs izlaižat encap-dport servera pusē tunelis nedarbosies, nav tik gudrs, lai ņemtu attālā savienojuma portu. Šajā gadījumā var palīdzēt arī ipipou vai arī WireGuard un citi tamlīdzīgi.

Kā tas strādā?

Klients (kas parasti atrodas aiz NAT) atver tuneli (kā iepriekš minētajā piemērā) un nosūta serverim autentifikācijas paketi, lai tas konfigurētu tuneli savā pusē. Atkarībā no iestatījumiem tā var būt tukša pakete (lai serveris varētu redzēt publisko IP: savienojuma portu) vai ar datiem, pēc kuriem serveris var identificēt klientu. Dati var būt vienkārša ieejas frāze skaidrā tekstā (nāk prātā analoģija ar HTTP pamata autentifikāciju) vai īpaši izstrādāti dati, kas parakstīti ar privāto atslēgu (līdzīgi HTTP Digest Auth tikai spēcīgāka, skatiet funkciju client_auth kodā).

Serverī (puse ar publisko IP), kad ipipou sākas, tas izveido nfqueue rindas apstrādātāju un konfigurē netfilter tā, lai nepieciešamās paketes tiktu nosūtītas tur, kur tām jābūt: paketes, kas inicializē savienojumu ar nfqueue rindu, un [gandrīz] viss pārējais iet tieši pie klausītāja FOU.

Tiem, kas nezina, nfqueue (vai NetfilterQueue) ir īpaša lieta amatieriem, kas nezina, kā izstrādāt kodola moduļus, kas, izmantojot netfilter (nftables/iptables), ļauj novirzīt tīkla paketes uz lietotāja vietu un apstrādāt tās, izmantojot primitīvie līdzekļi ir pieejami: modificējiet (neobligāti) un atdodiet to kodolam vai izmetiet to.

Dažām programmēšanas valodām ir saistījumi darbam ar nfqueue, bash tādu nebija (he, tas nav pārsteidzoši), man bija jāizmanto python: ipipou uses NetfilterQueue.

Ja veiktspēja nav kritiska, izmantojot šo lietu, jūs varat salīdzinoši ātri un viegli izdomāt savu loģiku darbam ar paketēm diezgan zemā līmenī, piemēram, izveidot eksperimentālus datu pārraides protokolus vai trollēt lokālos un attālos pakalpojumus ar nestandarta uzvedību.

Raw sockets strādā roku rokā ar nfqueue, piemēram, kad tunelis jau ir konfigurēts un FOU klausās vēlamajā portā, jūs nevarēsit nosūtīt paketi no tā paša porta parastajā veidā - tas ir aizņemts, bet Jūs varat paņemt un nosūtīt nejauši ģenerētu paketi tieši uz tīkla interfeisu, izmantojot neapstrādātu ligzdu, lai gan šādas paketes ģenerēšana prasīs nedaudz vairāk piepūles. Tādā veidā ipipou tiek izveidotas paketes ar autentifikāciju.

Tā kā ipipou apstrādā tikai pirmās savienojuma paketes (un tās, kurām izdevās noplūst rindā pirms savienojuma izveidošanas), veiktspēja gandrīz necieš.

Tiklīdz ipipou serveris saņem autentificētu paketi, tiek izveidots tunelis, un visas nākamās savienojuma paketes jau apstrādā kodols, apejot nfqueue. Ja savienojums neizdodas, tad nākamā nākamā pirmā pakete tiks nosūtīta uz rindu nfqueue, atkarībā no iestatījumiem, ja tā nav pakete ar autentifikāciju, bet no pēdējā atcerētā IP un klienta porta, to var vai nu nodot ieslēgts vai izmests. Ja autentificēta pakete nāk no jauna IP un porta, tunelis tiek pārkonfigurēts, lai tos izmantotu.

Parastajam IPIP-over-FOU ir vēl viena problēma, strādājot ar NAT - nav iespējams izveidot divus IPIP tuneļus, kas iekapsulēti UDP ar vienu un to pašu IP, jo FOU un IPIP moduļi ir diezgan izolēti viens no otra. Tie. Klientu pāris, kas atrodas aiz viena un tā paša publiskā IP, nevarēs vienlaicīgi izveidot savienojumu ar vienu un to pašu serveri šādā veidā. Nākotnē, varbūt, tas tiks atrisināts kodola līmenī, taču tas nav droši. Tikmēr NAT problēmas var atrisināt ar NAT - ja gadās, ka IP adrešu pāris jau ir aizņemts ar citu tuneli, ipipou veiks NAT no publiskā uz alternatīvu privāto IP, voila! - jūs varat izveidot tuneļus, līdz beidzas porti.

Jo Ne visas savienojumā esošās paketes ir parakstītas, tad šī vienkāršā aizsardzība ir neaizsargāta pret MITM, tādēļ, ja ceļā starp klientu un serveri slēpjas nelietis, kurš var klausīties trafiku un manipulēt ar to, viņš var novirzīt autentificētās paketes caur citu adresi un izveidojiet tuneli no neuzticama resursdatora .

Ja kādam ir idejas, kā to novērst, vienlaikus atstājot lielāko daļu satiksmes, nevilcinieties runāt.

Starp citu, iekapsulēšana UDP ir sevi ļoti labi pierādījusi. Salīdzinot ar iekapsulēšanu, izmantojot IP, tā ir daudz stabilāka un bieži vien ātrāka, neskatoties uz UDP galvenes papildu pieskaitāmajām izmaksām. Tas ir saistīts ar faktu, ka lielākā daļa interneta resursdatoru labi darbojas tikai ar trim populārākajiem protokoliem: TCP, UDP, ICMP. Taustāmā daļa var pilnībā atmest visu pārējo vai apstrādāt to lēnāk, jo tā ir optimizēta tikai šiem trim.

Piemēram, tāpēc QUICK, uz kura ir balstīts HTTP/3, tika izveidots virs UDP, nevis uz IP.

Nu, pietiekami daudz vārdu, ir pienācis laiks redzēt, kā tas darbojas "reālajā pasaulē".

Cīņa

Izmanto, lai līdzinātos reālajai pasaulei iperf3. Runājot par tuvības pakāpi realitātei, tas ir aptuveni tāds pats kā Minecraft reālās pasaules atdarināšana, taču pagaidām tā derēs.

Sacensību dalībnieki:

  • atsauces galvenais kanāls
  • šī raksta varonis ir ipipou
  • OpenVPN ar autentifikāciju, bet bez šifrēšanas
  • OpenVPN viss iekļauts režīmā
  • WireGuard bez PresharedKey, ar MTU=1440 (kopš tikai IPv4)

Tehniskie dati gīkiem
Metrika tiek ņemta ar šādām komandām:

par klientu:

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 latentums

ping -c 10 SERVER_IP | tail -1

serverī (darbojas vienlaikus ar klientu):

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"

Tuneļa konfigurācija

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

klients
/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 (bez šifrēšanas, ar autentifikāciju)
serveri

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

klients

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 (ar šifrēšanu, autentifikāciju, izmantojot UDP, viss, kā paredzēts)
Konfigurēts, izmantojot openvpn-manage

stiepļu sargs
serveri
/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

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

rezultātus

Mitra neglīta zīme
Servera CPU slodze nav īpaši indikatīva, jo... Tur darbojas daudzi citi pakalpojumi, dažreiz tie patērē resursus:

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 kanāls

ipipou: vairāk nekā tikai nešifrēts tunelis

ipipou: vairāk nekā tikai nešifrēts tunelis

kanālu uz 1 optimistisko Gbps

ipipou: vairāk nekā tikai nešifrēts tunelis

ipipou: vairāk nekā tikai nešifrēts tunelis

Visos gadījumos ipipou veiktspēja ir diezgan tuvu bāzes kanālam, kas ir lieliski!

Nešifrētais openvpn tunelis abos gadījumos izturējās diezgan dīvaini.

Ja kāds grasās testēt, būs interesanti dzirdēt atsauksmes.

Lai IPv6 un NetPrickle ir ar mums!

Avots: www.habr.com

Pievieno komentāru