ipipou. ավելին, քան պարզապես չգաղտնագրված թունել

Ի՞նչ ենք մենք ասում IPv6-ի Աստծուն:

ipipou. ավելին, քան պարզապես չգաղտնագրված թունել
Ճիշտ է, մենք այսօր նույնը կասենք գաղտնագրման աստծուն:

Այստեղ մենք կխոսենք չգաղտնագրված IPv4 թունելի մասին, բայց ոչ թե «տաք լամպի», այլ ժամանակակից «LED» թունելի մասին։ Եվ այստեղ կան նաև չմշակված վարդակներ, և աշխատանքներ են տարվում օգտատերերի տարածքում փաթեթների հետ:

Յուրաքանչյուր ճաշակի և գույնի համար կան N թունելային արձանագրություններ.

  • ոճային, նորաձև, երիտասարդական WireGuard- ը
  • բազմաֆունկցիոնալ, ինչպես շվեյցարական դանակներ, OpenVPN և SSH
  • հին ու ոչ չար GRE
  • ամենապարզ, արագ, ամբողջովին չգաղտնագրված IPIP-ը
  • ակտիվորեն զարգանում է ԺԵՆԵՎ
  • շատ ուրիշներ:

Բայց ես ծրագրավորող եմ, ուստի N-ը միայն մի կոտորակով կավելացնեմ, իսկ իրական պրոտոկոլների մշակումը կթողնեմ Կոմերսանտի ծրագրավորողներին։

Մեկ չծնված նախագիծըԱյն, ինչ ես հիմա անում եմ, արտաքինից NAT-ի հետևում գտնվող տանտերերին հասնելն է: Դրա համար օգտագործելով մեծահասակների գաղտնագրման արձանագրություններ, ես չէի կարող զսպել այն զգացումը, որ դա նման է թնդանոթից ճնճղուկներին կրակելուն: Որովհետեւ թունելը մեծ մասամբ օգտագործվում է միայն NAT-e-ում անցքեր բացելու համար, ներքին երթևեկությունը սովորաբար նույնպես կոդավորված է, բայց դրանք դեռ խեղդվում են HTTPS-ում:

Տարբեր թունելային արձանագրություններ ուսումնասիրելիս, իմ ներքին պերֆեկցիոնիստի ուշադրությունը կրկին ու կրկին հրավիրվում էր IPIP-ի վրա՝ դրա նվազագույն ծախսերի պատճառով: Բայց այն ունի մեկ ու կես նշանակալի թերություններ իմ առաջադրանքների համար.

  • այն պահանջում է երկու կողմերի հանրային IP-ներ,
  • և ձեզ համար նույնականացում չկա:

Հետևաբար, պերֆեկցիոնիստը հետ մղվեց գանգի մութ անկյունը կամ որտեղ էլ որ նա նստի այնտեղ։

Եվ հետո մի օր, երբ կարդում էի հոդվածները բնիկ աջակցվող թունելներ Linux-ում ես հանդիպեցի FOU (Foo-over-UDP), այսինքն. ինչ էլ որ լինի, UDP-ով փաթաթված: Առայժմ աջակցվում են միայն IPIP և GUE (Generic UDP Encapsulation):

«Ահա արծաթե փամփուշտը: Պարզ IPIP-ն ինձ բավական է»։ - Ես մտածեցի.

Փաստորեն, փամփուշտը, պարզվեց, ամբողջովին արծաթագույն չէր։ UDP-ում ընդգրկումը լուծում է առաջին խնդիրը. դուք կարող եք արտաքինից միանալ NAT-ի հետևում գտնվող հաճախորդներին՝ օգտագործելով նախապես հաստատված կապը, բայց այստեղ IPIP-ի հաջորդ թերության կեսը ծաղկում է նոր լույսի ներքո. մասնավոր ցանցից յուրաքանչյուրը կարող է թաքնվել տեսանելիի հետևում: հանրային IP և հաճախորդի պորտ (մաքուր IPIP-ում այս խնդիրը գոյություն չունի):

Այս մեկուկես խնդիրը լուծելու համար ծնվեց կոմունալը իպիպու. Այն իրականացնում է հեռակա հոսթի նույնականացման տնային մեխանիզմ՝ առանց միջուկի 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 - հաճախորդի IP-ն նշանակված է ինտերֆեյսի eth0-ին
  • 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 queue handler և կարգավորում է ցանցի ֆիլտրը, որպեսզի անհրաժեշտ փաթեթներն ուղարկվեն այնտեղ, որտեղ պետք է լինեն. մնացած բոլորը գնում են ուղիղ FOU լսողին:

Նրանց համար, ովքեր չգիտեն, nfqueue (կամ NetfilterQueue) հատուկ բան է այն սիրողականների համար, ովքեր չգիտեն, թե ինչպես մշակել միջուկի մոդուլներ, որոնք օգտագործելով netfilter (nftables/iptables) թույլ են տալիս վերահղել ցանցային փաթեթները դեպի օգտվողի տարածք և մշակել դրանք այնտեղ՝ օգտագործելով: պրիմիտիվ նշանակում է ձեռքի տակ. փոփոխել (ըստ ցանկության) և վերադարձնել այն միջուկին կամ հեռացնել այն:

Ծրագրավորման որոշ լեզուների համար կան nfqueue-ի հետ աշխատելու կապեր, bash-ի համար չկա (հե, զարմանալի չէ), ես ստիպված էի օգտագործել python. ipipou-ն օգտագործում է NetfilterQueue.

Եթե ​​կատարումը կարևոր չէ, ապա օգտագործելով այս բանը, դուք կարող եք համեմատաբար արագ և հեշտությամբ հորինել ձեր սեփական տրամաբանությունը փաթեթների հետ բավականին ցածր մակարդակի վրա աշխատելու համար, օրինակ՝ ստեղծել փորձնական տվյալների փոխանցման արձանագրություններ, կամ թրոլել տեղական և հեռավոր ծառայությունները ոչ ստանդարտ վարքագծով:

Raw sockets-ը աշխատում է ձեռք ձեռքի տված nfqueue-ի հետ, օրինակ, երբ թունելն արդեն կազմաձևված է, և FOU-ը լսում է ցանկալի պորտը, դուք չեք կարողանա փաթեթ ուղարկել նույն նավահանգստից սովորական ձևով. այն զբաղված է, բայց Դուք կարող եք վերցնել և ուղարկել պատահականորեն ստեղծված փաթեթը անմիջապես ցանցի ինտերֆեյսի մեջ՝ օգտագործելով հումքային վարդակից, թեև այդպիսի փաթեթ ստեղծելու համար մի փոքր ավելի շատ կպահանջվի: Ահա թե ինչպես են ստեղծվում վավերացումով փաթեթները ipipou-ում:

Քանի որ ipipou-ն մշակում է կապից միայն առաջին փաթեթները (և նրանք, որոնց հաջողվել է արտահոսել հերթում մինչև կապի հաստատումը), կատարումը գրեթե չի տուժում:

Հենց որ ipipou սերվերը ստանում է վավերացված փաթեթ, ստեղծվում է թունել, և կապի բոլոր հետագա փաթեթներն արդեն մշակվում են միջուկի կողմից՝ շրջանցելով nfqueue-ը: Եթե ​​կապը ձախողվի, ապա հաջորդի առաջին փաթեթը կուղարկվի nfqueue հերթ՝ կախված կարգավորումներից, եթե դա նույնականացումով փաթեթ չէ, այլ վերջին հիշված IP-ից և հաճախորդի պորտից, այն կարող է փոխանցվել կամ վրա կամ դեն նետված: Եթե ​​վավերացված փաթեթը գալիս է նոր IP-ից և նավահանգստից, թունելը վերակազմավորվում է դրանք օգտագործելու համար:

Սովորական IPIP-over-FOU-ն ունի ևս մեկ խնդիր NAT-ի հետ աշխատելիս. անհնար է ստեղծել երկու IPIP թունելներ, որոնք պարփակված են UDP-ով նույն IP-ով, քանի որ FOU և IPIP մոդուլները բավականին մեկուսացված են միմյանցից: Նրանք. նույն հանրային IP-ի հետևում գտնվող զույգ հաճախորդները չեն կարողանա միաժամանակ միանալ նույն սերվերին այս ձևով: Ապագայում, գուցե, այն կլուծվի միջուկի մակարդակով, բայց դա հաստատ չէ։ Միևնույն ժամանակ, NAT-ի խնդիրները կարող են լուծվել NAT-ի միջոցով. եթե պատահի, որ IP հասցեների մի զույգ արդեն զբաղված է մեկ այլ թունելով, ipipou-ն NAT-ը կանի հանրայինից մինչև այլընտրանքային մասնավոր IP, voila: - Դուք կարող եք թունելներ ստեղծել մինչև նավահանգիստները սպառվեն:

Որովհետեւ Կապի մեջ ոչ բոլոր փաթեթներն են ստորագրված, ապա այս պարզ պաշտպանությունը խոցելի է MITM-ի համար, այնպես որ, եթե հաճախորդի և սերվերի միջև թաքնված է չարագործ, որը կարող է լսել տրաֆիկը և շահարկել այն, նա կարող է վերահղել վավերացված փաթեթները: մեկ այլ հասցե և ստեղծեք թունել անվստահելի հյուրընկալողից:

Եթե ​​ինչ-որ մեկը գաղափարներ ունի, թե ինչպես շտկել դա՝ միաժամանակ թողնելով երթևեկի հիմնական մասը միջուկում, մի հապաղեք բարձրաձայնել:

Ի դեպ, encapsulation-ը UDP-ում իրեն շատ լավ է ապացուցել: IP-ով ինկապսուլյացիայի համեմատ, այն շատ ավելի կայուն է և հաճախ ավելի արագ, չնայած UDP վերնագրի լրացուցիչ ծախսերին: Դա պայմանավորված է նրանով, որ ինտերնետում հոսթինգների մեծ մասը լավ է աշխատում միայն երեք ամենահայտնի արձանագրություններով՝ TCP, UDP, ICMP: Շոշափելի մասը կարող է ամբողջությամբ հրաժարվել մնացած ամեն ինչից կամ ավելի դանդաղ մշակել, քանի որ այն օպտիմիզացված է միայն այս երեքի համար։

Օրինակ, սա է պատճառը, որ QUICK-ը, որի վրա հիմնված է HTTP/3-ը, ստեղծվել է UDP-ի, այլ ոչ թե IP-ի վերևում:

Դե, բավական բառեր, ժամանակն է տեսնելու, թե ինչպես է այն աշխատում «իրական աշխարհում»:

Ճակատամարտ

Օգտագործվում է իրական աշխարհը ընդօրինակելու համար iperf3. Իրականությանը մոտ լինելու աստիճանի առումով սա մոտավորապես նույնն է, ինչ իրական աշխարհը ընդօրինակելը Minecraft-ում, բայց առայժմ դա տեղի կունենա:

Մրցույթի մասնակիցներ.

  • հղում գլխավոր ալիք
  • այս հոդվածի հերոսը ipipou-ն է
  • OpenVPN նույնականացումով, բայց առանց կոդավորման
  • OpenVPN բոլոր ներառական ռեժիմով
  • WireGuard առանց PresharedKey, MTU=1440-ով (միայն IPv4-ից)

Տեխնիկական տվյալներ գիքերի համար
Չափումները վերցվում են հետևյալ հրամաններով.

հաճախորդի վրա.

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"

Թունելի կոնֆիգուրացիա

իպիպու
սերվեր
/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

Արդյունքները

Խոնավ տգեղ նշան
Սերվերի պրոցեսորի բեռնվածությունը այնքան էլ ցուցիչ չէ, քանի որ... Այնտեղ շատ այլ ծառայություններ կան, որոնք երբեմն խլում են ռեսուրսները.

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 Մբիթ/վրկ ալիք

ipipou. ավելին, քան պարզապես չգաղտնագրված թունել

ipipou. ավելին, քան պարզապես չգաղտնագրված թունել

ալիք 1 լավատեսական Գբիտ/վրկ-ի դիմաց

ipipou. ավելին, քան պարզապես չգաղտնագրված թունել

ipipou. ավելին, քան պարզապես չգաղտնագրված թունել

Բոլոր դեպքերում, ipipou-ն իր կատարողականությամբ բավականին մոտ է բազային ալիքին, ինչը հիանալի է:

Չկոդավորված openvpn թունելն իրեն բավականին տարօրինակ էր պահում երկու դեպքում էլ։

Եթե ​​որեւէ մեկը պատրաստվում է փորձարկել այն, հետաքրքիր կլինի լսել արձագանքները:

Թող IPv6-ը և NetPrickle-ը մեզ հետ լինեն:

Source: www.habr.com

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