ipipou: sadəcə şifrələnməmiş tuneldən daha çox

IPv6 Tanrısına nə deyirik?

ipipou: sadəcə şifrələnməmiş tuneldən daha çox
Düzdür, biz bu gün şifrələmə tanrısına eyni şeyi deyəcəyik.

Burada şifrələnməmiş IPv4 tuneli haqqında danışacağıq, lakin "isti lampa" haqqında deyil, müasir "LED" haqqında. Həm də burada yanıb-sönən xam rozetkalar var və istifadəçi məkanında paketlərlə iş gedir.

Hər zövq və rəng üçün N tunel protokolu var:

  • şık, dəbli, gənclik WireGuard
  • İsveçrə bıçaqları, OpenVPN və SSH kimi çoxfunksiyalı
  • köhnə və pis deyil GRE
  • ən sadə, sürətli, tamamilə şifrələnməmiş IPIP
  • fəal inkişaf edir GENVE
  • bir çox başqaları.

Ancaq mən bir proqramçıyam, buna görə də N-ni yalnız bir hissə artıracağam və real protokolların işlənməsini Kommersant tərtibatçılarına buraxacağam.

Doğulmamış birində layihəİndi etdiyim şey kənardan NAT-ın arxasındakı hostlara çatmaqdır. Bunun üçün böyüklər üçün kriptoqrafiya ilə protokollardan istifadə edərək, bunun topdan sərçə atmağa bənzədiyi hissini sarsıda bilmədim. Çünki tunel çox hissəsi üçün yalnız NAT-e-də deşiklər açmaq üçün istifadə olunur, daxili trafik adətən şifrələnir, lakin onlar hələ də HTTPS-də boğulurlar.

Müxtəlif tunel protokollarını tədqiq edərkən, mənim daxili mükəmməllikçimin diqqəti minimal yükə görə IPIP-ə təkrar-təkrar cəlb edildi. Ancaq mənim vəzifələrim üçün bir yarım əhəmiyyətli çatışmazlıq var:

  • hər iki tərəfdən ictimai IP tələb edir,
  • və sizin üçün identifikasiya yoxdur.

Buna görə də, mükəmməllikçi yenidən kəllənin qaranlıq küncünə və ya orada oturduğu yerə sürükləndi.

Və sonra bir gün məqalələri oxuyarkən yerli olaraq dəstəklənən tunellər Linux-da mən FOU (Foo-over-UDP) ilə qarşılaşdım, yəni. nə olursa olsun, UDP-yə bükülmüşdür. İndiyə qədər yalnız IPIP və GUE (Ümumi UDP Encapsulation) dəstəklənir.

“Budur gümüş güllə! Mənim üçün sadə bir IPIP kifayətdir”. - düşündüm.

Əslində, güllənin tamamilə gümüş olmadığı ortaya çıxdı. UDP-də inkapsulyasiya ilk problemi həll edir - əvvəlcədən qurulmuş əlaqədən istifadə edərək kənardan NAT arxasındakı müştərilərə qoşula bilərsiniz, lakin burada IPIP-in növbəti çatışmazlığının yarısı yeni işıqda çiçəklənir - özəl şəbəkədən hər kəs görünən şəbəkənin arxasında gizlənə bilər. ictimai IP və müştəri portu (saf IPIP-də bu problem mövcud deyil).

Bu bir yarım problemi həll etmək üçün kommunal doğuldu ipipou. O, nüvə məkanında paketləri tez və səmərəli şəkildə emal edəcək nüvə FOU-nun işini pozmadan uzaq hostun autentifikasiyası üçün evdə hazırlanmış mexanizm tətbiq edir.

Sizin skriptinizə ehtiyacımız yoxdur!

Yaxşı, əgər siz müştərinin ictimai portunu və İP-ni bilirsinizsə (məsələn, onun arxasında olan hər kəs heç yerə getmir, NAT 1-in-1-də portları xəritələməyə çalışır), siz FOU üzərində IPIP tuneli yarada bilərsiniz. heç bir skript olmadan aşağıdakı əmrləri.

serverdə:

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

müştəri haqqında:

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

hara

  • ipipou* — yerli tunel şəbəkə interfeysinin adı
  • 203.0.113.1 — ictimai IP server
  • 198.51.100.2 — müştərinin ictimai IP ünvanı
  • 192.168.0.2 — eth0 interfeysinə təyin edilmiş müştəri IP
  • 10001 — FOU üçün yerli müştəri portu
  • 20001 — FOU üçün ictimai müştəri portu
  • 10000 — FOU üçün ictimai server portu
  • encap-csum — kapsullaşdırılmış UDP paketlərinə UDP yoxlama məbləği əlavə etmək seçimi; ilə əvəz edilə bilər noencap-csum, qeyd etməmək lazımdır ki, bütövlük artıq xarici enkapsulyasiya təbəqəsi tərəfindən idarə olunur (paket tunelin içərisində olduğu halda)
  • eth0 — ipip tunelinin bağlanacağı yerli interfeys
  • 172.28.0.1 — Müştəri tunel interfeysinin IP-si (özəl)
  • 172.28.0.0 — IP tunel server interfeysi (özəl)

Nə qədər ki, UDP bağlantısı canlıdır, tunel işlək vəziyyətdə olacaq, lakin pozulsa, bəxtiniz gətirəcək - müştərinin IP: portu eyni qalsa - yaşayacaq, dəyişsələr - pozulacaq.

Hər şeyi geri qaytarmağın ən asan yolu nüvə modullarını boşaltmaqdır: modprobe -r fou ipip

Doğrulama tələb olunmasa belə, müştərinin ictimai IP və portu həmişə məlum olmur və çox vaxt gözlənilməz və ya dəyişən olur (NAT növündən asılı olaraq). Əgər buraxsanız encap-dport server tərəfində tunel işləməyəcək, uzaqdan əlaqə portunu götürmək üçün kifayət qədər ağıllı deyil. Bu halda ipipou da kömək edə bilər və ya WireGuard və onun kimi başqaları sizə kömək edə bilər.

Necə işləyir?

Müştəri (adətən NAT-ın arxasındadır) tunel açır (yuxarıdakı nümunədə olduğu kimi) və serverə autentifikasiya paketini göndərir ki, tuneli öz tərəfində konfiqurasiya etsin. Parametrlərdən asılı olaraq, bu boş paket ola bilər (sadəcə server ictimai IP-ni görsün: əlaqə portu) və ya serverin müştərini müəyyən edə biləcəyi məlumatlarla. Məlumat aydın mətndə sadə parol ifadəsi ola bilər (HTTP Basic Auth ilə bənzətmə ağla gəlir) və ya xüsusi açarla imzalanmış xüsusi hazırlanmış məlumat (HTTP Digest Auth-a bənzər, yalnız daha güclüdür, funksiyaya baxın) client_auth kodda).

Serverdə (ictimai IP olan tərəf) ipipou işə salındıqda, o, nfqueue növbə idarəçisi yaradır və lazımi paketlərin olması lazım olan yerə göndərilməsi üçün şəbəkə filtrini konfiqurasiya edir: nfqueue növbəsi ilə əlaqəni işə salan paketlər və [demək olar ki,] bütün qalan dinləyici FOU birbaşa getmək.

Bilməyənlər üçün nfqueue (və ya NetfilterQueue) kernel modullarını necə inkişaf etdirməyi bilməyən həvəskarlar üçün xüsusi bir şeydir, netfilterdən (nftables/iptables) istifadə edərək şəbəkə paketlərini istifadəçi sahəsinə yönləndirməyə və orada onları emal etməyə imkan verir. ibtidai vasitələr: dəyişdirin (isteğe bağlı) və onu nüvəyə qaytarın və ya atın.

Bəzi proqramlaşdırma dilləri üçün nfqueue ilə işləmək üçün bağlamalar var, bash üçün heç biri yox idi (heh, təəccüblü deyil), python istifadə etməli oldum: ipipou istifadə edir. NetfilterQueue.

Performans kritik deyilsə, bu şeydən istifadə edərək, kifayət qədər aşağı səviyyədə paketlərlə işləmək üçün öz məntiqinizi nisbətən tez və asanlıqla düzəldə bilərsiniz, məsələn, eksperimental məlumat ötürmə protokolları yarada və ya qeyri-standart davranışla yerli və uzaq xidmətləri trolləyə bilərsiniz.

Raw rozetkalar nfqueue ilə əl-ələ verir, məsələn, tunel artıq konfiqurasiya edildikdə və FOU istədiyiniz porta qulaq asdıqda, siz eyni portdan adi şəkildə paket göndərə bilməyəcəksiniz - məşğuldur, lakin siz təsadüfi yaradılmış paketi xam rozetkadan istifadə edərək birbaşa şəbəkə interfeysinə götürə və göndərə bilərsiniz, baxmayaraq ki, belə bir paketin yaradılması bir az daha çox səy tələb edəcək. İpipouda identifikasiyası olan paketlər belə yaradılır.

İpipou yalnız bağlantıdan ilk paketləri (və əlaqə qurulmazdan əvvəl növbəyə sızmağı bacaranları) emal etdiyi üçün performans demək olar ki, əziyyət çəkmir.

İpipou serveri təsdiqlənmiş paketi qəbul edən kimi tunel yaradılır və əlaqədəki bütün sonrakı paketlər nfqueue-dən yan keçərək nüvə tərəfindən artıq işlənir. Bağlantı uğursuz olarsa, növbəti paketin ilk paketi parametrlərdən asılı olaraq nfqueue növbəsinə göndəriləcək, əgər bu autentifikasiyası olan paket deyil, sonuncu yadda qalan IP və müştəri portundandırsa, ya ötürülə bilər. üzərində və ya atılır. Əgər təsdiqlənmiş paket yeni IP və portdan gəlirsə, tunel onlardan istifadə etmək üçün yenidən konfiqurasiya edilir.

NAT ilə işləyərkən adi IPIP-over-FOU-nun daha bir problemi var - eyni IP ilə UDP-də kapsullaşdırılmış iki IPIP tuneli yaratmaq mümkün deyil, çünki FOU və IPIP modulları bir-birindən kifayət qədər təcrid olunublar. Bunlar. eyni ictimai IP-nin arxasında olan bir cüt müştəri eyni vaxtda eyni serverə bu şəkildə qoşula bilməyəcək. Gələcəkdə, bəlkə, kernel səviyyəsində həll ediləcək, lakin bu dəqiq deyil. Bu vaxt, NAT problemləri NAT tərəfindən həll edilə bilər - əgər bir cüt IP ünvanı artıq başqa bir tunel tərəfindən işğal edilərsə, ipipou NAT-ı ictimaidən alternativ şəxsi IP-yə edəcək, voila! - limanlar tükənənə qədər tunellər yarada bilərsiniz.

Çünki Bağlantıdakı bütün paketlər imzalanmır, onda bu sadə qorunma MITM-ə qarşı həssasdır, buna görə də müştəri ilə server arasında trafikə qulaq asa və manipulyasiya edə bilən bir cani varsa, o, təsdiqlənmiş paketləri yenidən yönləndirə bilər. başqa ünvan və etibarsız hostdan tunel yaradın.

Əgər kiminsə trafikin böyük hissəsini əsasda qoyaraq bunu necə düzəltmək barədə fikirləri varsa, danışmaqdan çəkinməyin.

Yeri gəlmişkən, UDP-də inkapsulyasiya özünü çox yaxşı sübut etdi. IP üzərindən inkapsulyasiya ilə müqayisədə, UDP başlığının əlavə yükünə baxmayaraq, daha sabit və tez-tez daha sürətlidir. Bu, İnternetdəki əksər hostların yalnız üç ən populyar protokolla yaxşı işləməsi ilə bağlıdır: TCP, UDP, ICMP. Maddi hissə qalan hər şeyi tamamilə tərk edə bilər və ya daha yavaş emal edə bilər, çünki o, yalnız bu üçü üçün optimallaşdırılmışdır.

Məsələn, buna görə HTTP/3-ün əsaslandığı QUICK IP-nin üstündə deyil, UDP üzərində yaradılmışdır.

Yaxşı, kifayət qədər sözlər, bunun "real dünyada" necə işlədiyini görməyin vaxtı gəldi.

Döyüş

Real dünyanı təqlid etmək üçün istifadə olunur iperf3. Gerçəkliyə yaxınlıq dərəcəsi baxımından bu, Minecraft-da real dünyanı təqlid etməklə təxminən eynidir, lakin hələlik bunu edəcək.

Müsabiqədə iştirak edənlər:

  • istinad əsas kanal
  • bu məqalənin qəhrəmanı ipipoudur
  • Doğrulama ilə OpenVPN, lakin şifrələmə yoxdur
  • Hər şey daxil rejimində OpenVPN
  • MTU=1440 ilə PresharedKey olmadan WireGuard (yalnız IPv4-dən bəri)

Geeks üçün texniki məlumatlar
Metriklər aşağıdakı əmrlərlə alınır:

müştəri haqqında:

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 gecikməsi

ping -c 10 SERVER_IP | tail -1

serverdə (müştəri ilə eyni vaxtda işləyir):

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"

Tunel konfiqurasiyası

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

müştəri
/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 (şifrləmə yoxdur, autentifikasiya ilə)
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

müştəri

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 (şifrələmə, autentifikasiya, UDP vasitəsilə, hər şey gözlənildiyi kimi)
istifadə edərək konfiqurasiya edilmişdir openvpn-idarə

tel qoruma
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

müştəri
/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

Tapıntılar

Nəm çirkin işarəsi
Server CPU yükü çox göstərici deyil, çünki... Orada çalışan bir çox başqa xidmətlər var, bəzən onlar resursları yeyirlər:

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: sadəcə şifrələnməmiş tuneldən daha çox

ipipou: sadəcə şifrələnməmiş tuneldən daha çox

1 optimist Gbps üçün kanal

ipipou: sadəcə şifrələnməmiş tuneldən daha çox

ipipou: sadəcə şifrələnməmiş tuneldən daha çox

Bütün hallarda ipipou performans baxımından əsas kanala olduqca yaxındır, bu əladır!

Şifrələnməmiş openvpn tuneli hər iki halda olduqca qəribə davrandı.

Kimsə bunu sınaqdan keçirəcəksə, rəy eşitmək maraqlı olacaq.

IPv6 və NetPrickle bizimlə olsun!

Mənbə: www.habr.com

Добавить комментарий