ipipou: зүгээр л шифрлэгдээгүй хонгилоос илүү

Бид IPv6-н бурханд юу гэж хэлэх вэ?

ipipou: зүгээр л шифрлэгдээгүй хонгилоос илүү
Тийм ээ, бид өнөөдөр шифрлэлтийн бурханд ижил зүйлийг хэлэх болно.

Энд бид шифрлэгдээгүй IPv4 хонгилын тухай ярих болно, гэхдээ "дулаан" чийдэнгийн тухай биш, харин орчин үеийн "LED"-ийн тухай. Мөн энд түүхий залгуурууд анивчсан бөгөөд хэрэглэгчийн орон зайд пакетуудтай ажиллах ажил хийгдэж байна.

Амт, өнгө бүрт N туннелийн протокол байдаг:

  • загварлаг, загварлаг, залуучууд WireGuard
  • Швейцарийн хутга, OpenVPN, SSH гэх мэт олон үйлдэлт
  • хуучин, муу биш GRE
  • хамгийн энгийн, хурдан, бүрэн шифрлэгдээгүй IPIP
  • идэвхтэй хөгжиж байна ЖЕНЕВ
  • бусад олон.

Гэхдээ би програмист хүн учраас N-ийг бага багаар нэмэгдүүлж, жинхэнэ протокол боловсруулах ажлыг Коммерсант-ын хөгжүүлэгчдэд даатгана.

Төрөөгүй нэгд төсөлМиний одоо хийж байгаа зүйл бол гаднаас NAT-ийн ард байгаа хостуудтай холбогдох явдал юм. Үүний тулд насанд хүрэгчдийн криптограф бүхий протоколуудыг ашигласнаар энэ нь их буунаас бор шувуу буудаж байгаатай адил мэдрэмжээс салж чадсангүй. Учир нь хонгилыг ихэнх тохиолдолд зөвхөн NAT-e-д нүх гаргахад ашигладаг, дотоод урсгалыг ихэвчлэн шифрлэдэг боловч HTTPS-д живсэн хэвээр байна.

Төрөл бүрийн хонгилын протоколуудыг судалж байх үед миний дотоод төгс төгөлдөрч сэтгэлгээний анхаарлыг IPIP хамгийн бага зардалтай тул дахин дахин татсан. Гэхдээ энэ нь миний даалгаварт нэг ба хагас чухал сул талуудтай:

  • Энэ нь хоёр талдаа нийтийн IP шаарддаг,
  • мөн танд баталгаажуулалт байхгүй.

Тиймээс төгс төгөлдөрчийг гавлын ясны харанхуй буланд эсвэл хаана ч суусан газар руу нь эргүүлж авав.

Тэгээд нэг өдөр нийтлэл уншиж байхдаа эхээс дэмжигдсэн хонгилууд Линукс дээр би FOU (Foo-over-UDP)-тэй таарсан, i.e. ямар ч байсан, UDP-д ороосон. Одоогоор зөвхөн IPIP болон GUE (Generic UDP Encapsulation) дэмжигдсэн.

"Энд мөнгөн сум байна! Энгийн IPIP надад хангалттай." - Би бодсон.

Үнэн хэрэгтээ сум нь бүрэн мөнгө биш байсан. UDP дахь капсулжуулалт нь эхний асуудлыг шийддэг - та NAT-ийн ард байгаа үйлчлүүлэгчидтэй урьдчилан тогтоосон холболтыг ашиглан гаднаас холбогдож болно, гэхдээ энд IPIP-ийн дараагийн сул тал нь шинэ гэрэлд цэцэглэдэг - хувийн сүлжээний хэн ч харагдахуйц ард нуугдаж болно. нийтийн IP болон клиент порт (цэвэр IPIP-д энэ асуудал байхгүй).

Энэ нэг ба хагас асуудлыг шийдэхийн тулд хэрэгсэл гарч ирэв ipipou. Энэ нь цөмийн FOU-ийн ажиллагааг тасалдуулахгүйгээр алсын хостыг баталгаажуулах гэрийн хийсэн механизмыг хэрэгжүүлдэг бөгөөд энэ нь цөмийн зай дахь пакетуудыг хурдан бөгөөд үр дүнтэй боловсруулах болно.

Бидэнд таны скрипт хэрэггүй!

За, хэрэв та үйлчлүүлэгчийн нийтийн порт болон IP-г мэддэг бол (жишээлбэл, түүний ард байгаа бүх хүн хаашаа ч явахгүй, NAT 1-д-1 портыг зураглахыг оролддог) бол та IPIP-over-FOU туннель үүсгэж болно. ямар ч скриптгүйгээр дараах тушаалуудыг гүйцэтгэх.

сервер дээр:

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

үйлчлүүлэгч дээр:

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

хаана

  • ipipou* — дотоод туннелийн сүлжээний интерфейсийн нэр
  • 203.0.113.1 - нийтийн IP сервер
  • 198.51.100.2 - үйлчлүүлэгчийн нийтийн IP
  • 192.168.0.2 — eth0 интерфэйсэд өгсөн үйлчлүүлэгчийн IP
  • 10001 — FOU-д зориулсан орон нутгийн үйлчлүүлэгчийн порт
  • 20001 — FOU-д зориулсан нийтийн үйлчлүүлэгчийн порт
  • 10000 - FOU-д зориулсан нийтийн серверийн порт
  • encap-csum — капсуллагдсан UDP пакетуудад UDP шалгах нийлбэр нэмэх сонголт; -ээр сольж болно noencap-csum, дурдахгүй байх, бүрэн бүтэн байдлыг гаднах бүрхүүлийн давхарга аль хэдийн хянадаг (багц хонгил дотор байх үед)
  • eth0 — ipip туннель холбогдох орон нутгийн интерфейс
  • 172.28.0.1 - Үйлчлүүлэгчийн туннелийн интерфейсийн IP (хувийн)
  • 172.28.0.0 — IP туннелийн серверийн интерфейс (хувийн)

UDP холболт амьд байгаа цагт туннель хэвийн ажиллах болно, гэхдээ хэрэв энэ нь эвдэрвэл та азтай байх болно - хэрэв үйлчлүүлэгчийн IP: порт хэвээр байвал - энэ нь амьдрах болно, хэрэв тэд өөрчлөгдвөл - энэ нь эвдэрнэ.

Бүх зүйлийг буцаах хамгийн хялбар арга бол цөмийн модулиудыг буулгах явдал юм. modprobe -r fou ipip

Баталгаажуулалт шаардлагагүй байсан ч үйлчлүүлэгчийн нийтийн IP болон порт нь үргэлж мэдэгддэггүй бөгөөд ихэвчлэн урьдчилан таамаглах боломжгүй эсвэл хувьсах (NAT төрлөөс хамаарч) байдаг. Хэрэв та орхих юм бол encap-dport сервер тал дээр хонгил ажиллахгүй, алсын холболтын портыг авахад хангалттай ухаалаг биш байна. Энэ тохиолдолд ipipou бас туслах болно, эсвэл WireGuard болон бусад хүмүүс танд тусалж чадна.

энэ нь хэрхэн ажилладаг вэ?

Үйлчлүүлэгч (ихэвчлэн NAT-ийн ард байдаг) хонгил нээж (дээрх жишээн дээрх шиг) нэвтрэлт танилтын багцыг сервер рүү илгээж, хонгилыг хажуу талд нь тохируулдаг. Тохиргооноос хамааран энэ нь хоосон пакет байж болно (зөвхөн сервер нийтийн IP: холболтын портыг харах боломжтой) эсвэл сервер нь үйлчлүүлэгчийг таних боломжтой өгөгдөлтэй. Өгөгдөл нь тодорхой текстэн доторх энгийн нууц үг байж болно (HTTP Basic Auth-ийн аналоги санаанд орж ирдэг) эсвэл хувийн түлхүүрээр гарын үсэг зурсан тусгайлан боловсруулсан өгөгдөл (HTTP Digest Auth-тай төстэй, зөвхөн илүү хүчтэй, функцийг харна уу) client_auth код дотор).

Сервер дээр (нийтийн IP хаягтай тал) ipipou ажиллаж эхлэх үед nfqueue дараалал зохицуулагчийг үүсгэж, шаардлагатай пакетуудыг байх ёстой газар нь илгээхийн тулд сүлжээ шүүлтүүрийг тохируулдаг: nfqueue дараалалтай холболтыг эхлүүлэх пакетууд болон [бараг] бусад нь шууд сонсогч FOU руу явдаг.

Мэдэхгүй хүмүүсийн хувьд nfqueue (эсвэл NetfilterQueue) нь сүлжээний пакетуудыг хэрэглэгчийн орон зайд дахин чиглүүлж, тэнд боловсруулах боломжийг олгодог цөмийн модулиудыг хэрхэн хөгжүүлэхийг мэддэггүй сонирхогчдод зориулсан онцгой зүйл юм. гарт байгаа анхдагч хэрэгсэл: өөрчлөх (заавал биш) ба цөмд буцааж өгөх, эсвэл хаях.

Зарим програмчлалын хэлнүүдийн хувьд nfqueue-тэй ажиллах холбоосууд байдаг, bash-ийн хувьд ямар ч байсангүй (хэхэ, гайхмаар зүйл биш), би python ашиглах шаардлагатай болсон: ipipou ашигладаг. NetfilterQueue.

Хэрэв гүйцэтгэл чухал биш бол энэ зүйлийг ашигласнаар та харьцангуй бага түвшинд пакетуудтай ажиллах өөрийн логикийг харьцангуй хурдан бөгөөд хялбархан зохиож болно, жишээлбэл, туршилтын өгөгдөл дамжуулах протокол үүсгэх, эсвэл стандарт бус үйлдэлтэй орон нутгийн болон алсын үйлчилгээг тролль хийх боломжтой.

Түүхий залгуурууд нь nfqueue-тэй хамт ажилладаг, жишээлбэл, туннель аль хэдийн тохируулагдсан бөгөөд FOU нь хүссэн портоо сонсож байх үед та ердийн аргаар нэг портоос пакет илгээх боломжгүй - энэ нь завгүй, гэхдээ Та санамсаргүй байдлаар үүсгэсэн пакетыг түүхий залгуур ашиглан сүлжээний интерфэйс рүү шууд авч, илгээж болно, гэхдээ ийм пакет үүсгэхийн тулд бага зэрэг нарийн ажиллагаа шаардагдана. Ипипу хотод баталгаажуулалт бүхий пакетуудыг ингэж үүсгэдэг.

IPipou нь холболтоос зөвхөн эхний пакетуудыг боловсруулдаг тул (болон холболт үүсэхээс өмнө дараалалд нэвтэрч чадсан) гүйцэтгэл нь бараг мууддаггүй.

Ipipou сервер баталгаажсан пакет хүлээн авмагц туннель үүсгэгдэх ба холболтын дараагийн бүх пакетуудыг цөм nfqueue-г алгасаж боловсруулдаг. Хэрэв холболт амжилтгүй болвол дараагийнх нь эхний багцыг тохиргооноос хамааран nfqueue дараалалд илгээх бөгөөд хэрэв энэ нь баталгаажуулалттай пакет биш, харин хамгийн сүүлд санаж байгаа IP болон клиент портоос дамжуулж болно. дээр эсвэл хаясан. Хэрэв баталгаажсан пакет шинэ IP болон портоос ирвэл туннель нь тэдгээрийг ашиглахаар дахин тохируулагдана.

Ердийн IPIP-over-FOU нь NAT-тай ажиллахад бас нэг асуудалтай байдаг - FOU болон IPIP модулиуд нь бие биенээсээ нэлээд тусгаарлагдсан тул UDP-д ижил IP-тэй хоёр IPIP хонгил үүсгэх боломжгүй юм. Тэдгээр. Нэг нийтийн IP-ийн ард байгаа хос үйлчлүүлэгч ийм байдлаар нэг серверт нэгэн зэрэг холбогдох боломжгүй. Ирээдүйд, магадгүй, энэ нь цөмийн түвшинд шийдэгдэх боловч энэ нь тодорхой биш юм. Энэ хооронд NAT-ийн асуудлуудыг NAT-аар шийдэж болно - хэрэв хос IP хаягийг өөр хонгилд аль хэдийн эзэлсэн бол ipipou NAT-ыг олон нийтийнхээс өөр хувийн IP руу хийх болно, voila! - портууд дуусах хүртэл та хонгил үүсгэж болно.

Учир нь Холболтын бүх пакетууд гарын үсэг зураагүй байгаа тул энэхүү энгийн хамгаалалт нь MITM-д өртөмтгий байдаг тул хэрэв үйлчлүүлэгч болон серверийн хоорондох замд траффикийг сонсож, удирдаж чадах муу санаатан байгаа бол тэрээр баталгаажуулсан пакетуудыг дахин чиглүүлэх боломжтой. өөр хаяг болон найдваргүй хостоос туннель үүсгэнэ үү.

Хэрэв хэн нэгэнд замын хөдөлгөөний дийлэнхийг гол хэсэгт үлдээж, үүнийг хэрхэн засах талаар санаа байгаа бол эргэлзэх хэрэггүй.

Дашрамд хэлэхэд, UDP дахь капсулжуулалт нь маш сайн батлагдсан. IP дээрх капсулжуулалттай харьцуулахад UDP толгойн нэмэлт ачааллыг үл харгалзан илүү тогтвортой бөгөөд ихэвчлэн хурдан байдаг. Энэ нь Интернет дэх ихэнх хостууд зөвхөн TCP, UDP, ICMP гэсэн хамгийн алдартай гурван протоколтой сайн ажилладагтай холбоотой юм. Материаллаг хэсэг нь бусад бүх зүйлийг бүрэн хаях эсвэл илүү удаан боловсруулах боломжтой, учир нь энэ нь зөвхөн эдгээр гурвын хувьд оновчтой байдаг.

Жишээлбэл, ийм учраас HTTP/3 дээр суурилсан QUICK нь IP дээр биш, харин UDP дээр бүтээгдсэн.

За, хангалттай үг, энэ нь "бодит ертөнцөд" хэрхэн ажилладагийг харах цаг болжээ.

Тулаан

Бодит ертөнцийг дуурайхад ашигладаг iperf3. Бодит байдалд ойртсон байдлын хувьд энэ нь Minecraft дахь бодит ертөнцийг дуурайхтай ижил төстэй боловч одоохондоо үүнийг хийх болно.

Тэмцээнд оролцогчид:

  • лавлах үндсэн суваг
  • Энэ нийтлэлийн баатар бол ipipou юм
  • Баталгаажуулалттай боловч шифрлэлтгүй OpenVPN
  • OpenVPN бүгдийг багтаасан горимд
  • PresharedKey-гүй WireGuard, MTU=1440 (зөвхөн IPv4-с хойш)

Geeks-д зориулсан техникийн өгөгдөл
Хэмжилтийг дараах тушаалаар авна.

үйлчлүүлэгч дээр:

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 хоцролт

ping -c 10 SERVER_IP | tail -1

сервер дээр (үйлчлүүлэгчтэй нэгэн зэрэг ажилладаг):

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"

Тунелийн тохиргоо

ipipou
сервер
/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

үйлчлүүлэгч
/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 (шифрлэлт байхгүй, баталгаажуулалттай)
сервер

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

үйлчлүүлэгч

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 (шифрлэлт, нэвтрэлт танилт, UDP-ээр дамжуулан, хүлээгдэж буй бүх зүйл)
ашиглан тохируулсан openvpn-удирдах

угаалгын газар
сервер
/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

үйлчлүүлэгч
/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

Результаты

Нойтон муухай тэмдэг
Серверийн CPU-ийн ачаалал тийм ч их үзүүлэлт биш, учир нь... Тэнд өөр олон үйлчилгээ байдаг, заримдаа тэд нөөцийг иддэг:

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 суваг

ipipou: зүгээр л шифрлэгдээгүй хонгилоос илүү

ipipou: зүгээр л шифрлэгдээгүй хонгилоос илүү

1 өөдрөг Gbps тутамд суваг

ipipou: зүгээр л шифрлэгдээгүй хонгилоос илүү

ipipou: зүгээр л шифрлэгдээгүй хонгилоос илүү

Бүх тохиолдолд ipipou нь гүйцэтгэлийн хувьд үндсэн сувагтай ойролцоо байдаг бөгөөд энэ нь гайхалтай юм!

Шифрлэгдээгүй openvpn туннель хоёр тохиолдолд нэлээд хачирхалтай ажилласан.

Хэрэв хэн нэгэн үүнийг туршиж үзэх гэж байгаа бол санал хүсэлтийг сонсох нь сонирхолтой байх болно.

IPv6 болон NetPrickle бидэнтэй хамт байх болтугай!

Эх сурвалж: www.habr.com

сэтгэгдэл нэмэх