iipipou: 単なる暗号化されおいないトンネルではありたせん

IPv6 の神に䜕を蚀いたいのでしょうか?

iipipou: 単なる暗号化されおいないトンネルではありたせん
そう、今日は暗号の神様にも同じこずを蚀っおみよう。

ここでは、暗号化されおいない IPv4 トンネルに぀いお説明したすが、「りォヌム ランプ」トンネルではなく、最新の「LED」トンネルに぀いお説明したす。 たた、ここでは生の゜ケットがフラッシュされおおり、ナヌザヌ空間でパケットの䜜業が進行䞭です。

あらゆる奜みず色に察しお N 個のトンネリング プロトコルがありたす。

  • スタむリッシュ、ファッショナブル、若者 ワむダガヌド
  • スむスナむフ、OpenVPN、SSH などの倚機胜
  • 叀くお悪くないGRE
  • 最もシンプル、高速、完党に暗号化されおいない IPIP
  • 積極的に開発䞭 GENEVE
  • 他の倚く。

ただし、私はプログラマヌなので、N をほんの䞀郚だけ増やし、実際のプロトコルの開発はコメルサントの開発者に任せたす。

䞀人の胎児の䞭で プロゞェクト私が今やっおいるこずは、倖郚から NAT の背埌にあるホストにアクセスするこずです。 これに成人向け暗号を䜿甚したプロトコルを䜿甚するず、倧砲からスズメを撃ち出すようなものであるずいう感芚がぬぐえたせんでした。 なぜならトンネルは、ほずんどの堎合、NAT-e に穎を開けるためだけに䜿甚され、内郚トラフィックも通垞は暗号化されたすが、それでも HTTPS に溺れたす。

さたざたなトンネリング プロトコルを研究しおいるずきに、私の内なる完璧䞻矩者の泚意は、オヌバヌヘッドが最小限に抑えられおいる IPIP に䜕床も匕き寄せられたした。 しかし、私のタスクには XNUMX ぀の重倧な欠点がありたす。

  • 䞡偎にパブリック IP が必芁です。
  • そしおあなたに察する認蚌はありたせん。

したがっお、完璧䞻矩者は頭蓋骚の暗い隅、たたはそこに座っおいる堎所のどこにでも远いやられたした。

そしおある日、次のような蚘事を読んでいるず、 ネむティブにサポヌトされるトンネル Linux で FOU (Foo-over-UDP) に遭遇したした。 UDP でラップされたものは䜕でも。 これたでのずころ、IPIP ず GUE (Generic UDP Encapsulation) のみがサポヌトされおいたす。

「これが特効薬だ 私にずっおは単玔な IPIP で十分です。」 -私は思いたした。

実際、匟䞞は完党に銀ではないこずが刀明した。 UDP でのカプセル化により、最初の問題が解決されたす。事前に確立された接続を䜿甚しお、倖郚から NAT の背埌にあるクラむアントに接続できたすが、ここで、IPIP の次の欠点の半分が新たな光を圓おたす。プラむベヌト ネットワヌクの誰でも、目に芋えるネットワヌクの背埌に隠れるこずができたす。パブリック IP ずクラむアント ポヌト (玔粋な IPIP ではこの問題は存圚したせん)。

この XNUMX ぀半の問題を解決するために、ナヌティリティが誕生したした むピポり。 これは、カヌネル FOU の動䜜を䞭断するこずなく、リモヌト ホストを認蚌するための独自のメカニズムを実装しおおり、カヌネル空間でパケットを迅速か぀効率的に凊理したす。

あなたのスクリプトは必芁ありたせん!

わかりたした。クラむアントのパブリック ポヌトず IP がわかっおいる堎合 (たずえば、その背埌にいる党員はどこにも行かず、NAT はポヌトを 1-in-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 サヌバヌ偎では、トンネルは機胜せず、リモヌト接続ポヌトを取埗するほど賢くありたせん。 この堎合、ipipu も圹立ちたす。たたは、WireGuard やその他の同様のツヌルも圹立ちたす。

それはどのように動䜜したすか

クラむアント (通垞は NAT の背埌にありたす) は、(䞊の䟋のように) トンネルを開き、サヌバヌ偎でトンネルを構成するために認蚌パケットをサヌバヌに送信したす。 蚭定に応じお、これは空のパケット (サヌバヌがパブリック IP: 接続ポヌトを認識できるようにするため) であるこずも、サヌバヌがクラむアントを識別できるデヌタを含むこずもできたす。 デヌタは、クリア テキストの単玔なパスフレヌズ (HTTP 基本認蚌ずの類䌌が思い浮かびたす) たたは秘密キヌで眲名された特別に蚭蚈されたデヌタ (HTTP ダむゞェスト認蚌に䌌おいたすが、より匷力であるだけです。関数を参照) にするこずができたす。 client_auth コヌド内)。

サヌバヌ (パブリック IP を持぀偎) では、ipipou が開始されるず、nfqueue キュヌ ハンドラヌが䜜成され、必芁なパケットが送信されるべき堎所に送信されるように netfilter が蚭定されたす。nfqueue キュヌぞの接続を初期化するパケット、および [ほが] 残りはすべおリスナヌの FOU に盎接送信されたす。

詳しくない人のために説明するず、nfqueue (たたは NetfilterQueue) は、カヌネル モゞュヌルの開発方法を知らないアマチュアにずっお特別なものであり、netfilter (nftables/iptables) を䜿甚するず、ネットワヌク パケットをナヌザヌ空間にリダむレクトし、そこで次のコマンドを䜿甚しお凊理できたす。プリミティブずは、手元にあるものを意味したす: 倉曎 (オプション) しおカヌネルに戻すか、砎棄したす。

䞀郚のプログラミング蚀語では、nfqueue を操䜜するためのバむンディングがありたすが、bash ではバむンディングがありたせんでした (ぞヌ、驚くべきこずではありたせん)。Python を䜿甚する必芁がありたした。 ネットフィルタヌキュヌ.

パフォヌマンスが重芁でない堎合は、これを䜿甚するず、かなり䜎いレベルでパケットを凊理するための独自のロゞックを比范的迅速か぀簡単に䜜成できたす。たずえば、実隓的なデヌタ転送プロトコルを䜜成したり、非暙準の動䜜でロヌカルおよびリモヌトのサヌビスを荒らしたりするこずができたす。

Raw ゜ケットは nfqueue ず連携しお動䜜したす。たずえば、トンネルがすでに構成されおおり、FOU が目的のポヌトでリッスンしおいる堎合、通垞の方法では同じポヌトからパケットを送信できたせん。ビゞヌ状態ですが、 raw ゜ケットを䜿甚しお、ランダムに生成されたパケットを受け取っおネットワヌク むンタヌフェむスに盎接送信するこずもできたすが、そのようなパケットを生成するにはもう少し工倫が必芁になりたす。 これは、iipou で認蚌付きのパケットが䜜成される方法です。

iipipou は接続からの最初のパケット (および接続が確立される前にキュヌに挏れたパケット) のみを凊理するため、パフォヌマンスはほずんど䜎䞋したせん。

ipipou サヌバヌが認蚌されたパケットを受信するずすぐにトンネルが䜜成され、接続内のすべおの埌続のパケットは nfqueue をバむパスしおカヌネルによっおすでに凊理されおいたす。 接続が倱敗した堎合、蚭定に応じお、次のパケットの最初のパケットが nfqueue キュヌに送信されたす。認蚌付きのパケットではなく、最埌に蚘憶された IP およびクラむアント ポヌトからのものであれば、送信するこずができたす。オンたたは砎棄されたす。 認蚌されたパケットが新しい IP およびポヌトから送信された堎合、トンネルはそれらを䜿甚するように再構成されたす。

通垞の IPIP-over-FOU には、NAT を䜿甚する堎合にもう XNUMX ぀問題がありたす。FOU ず IPIP モゞュヌルは互いに完党に分離されおいるため、同じ IP を持぀ UDP にカプセル化された XNUMX ぀の IPIP トンネルを䜜成するこずは䞍可胜です。 それらの。 同じパブリック IP の背埌にある XNUMX 組のクラむアントは、この方法で同時に同じサヌバヌに接続できたせん。 将来は、 倚分、それはカヌネルレベルで解決されたすが、これは確実ではありたせん。 それたでの間、NAT の問題は NAT によっお解決できたす。IP アドレスのペアがすでに別のトンネルによっお占有されおいる堎合、ipipou はパブリック IP から代替プラむベヌト IP ぞの NAT を実行したす。 - ポヌトがなくなるたでトンネルを䜜成できたす。

なぜなら接続内のすべおのパケットが眲名されおいるわけではないため、この単玔な保護は MITM に察しお脆匱であるため、クラむアントずサヌバヌの間のパスにトラフィックをリッスンしお操䜜できる悪者が朜んでいる堎合、圌は認蚌されたパケットを別のアドレスを䜿甚しお、信頌できないホストからトンネルを䜜成したす。

トラフィックの倧郚分をコアに残したたたこ​​の問題を解決する方法に぀いおアむデアをお持ちの方がいらっしゃいたしたら、遠慮なく声を䞊げおください。

ずころで、UDP でのカプセル化は非垞にうたく蚌明されおいたす。 IP 䞊のカプセル化ず比范するず、UDP ヘッダヌの远加オヌバヌヘッドにもかかわらず、はるかに安定しおおり、倚くの堎合高速です。 これは、むンタヌネット䞊のほずんどのホストが、TCP、UDP、ICMP ずいう XNUMX ぀の最も䞀般的なプロトコルでのみ正垞に動䜜するずいう事実によるものです。 有圢郚分は、これら XNUMX ぀に察しおのみ最適化されおいるため、他のすべおを完党に砎棄するか、凊理が遅くなりたす。

たずえば、HTTP/3 のベヌスずなる QUICK が IP の䞊ではなく UDP の䞊に䜜成されたのはこのためです。

さお、蚀葉は十分にありたすが、今床はそれが「珟実の䞖界」でどのように機胜するかを芋おみたしょう。

戊い

珟実䞖界を゚ミュレヌトするために䜿甚されたす iperf3。 珟実ぞの近さずいう点では、Minecraft で珟実䞖界を゚ミュレヌトするのずほが同じですが、今のずころはこれで十分です。

コンテストの参加者:

  • リファレンスメむンチャンネル
  • この蚘事の䞻人公はむピポりです
  • OpenVPN 認蚌あり、暗号化なし
  • 包括的モヌドの OpenVPN
  • PresharedKey なしの WireGuard、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

結果

湿った醜い看板
サヌバヌの 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

20Mbpsチャンネル

iipipou: 単なる暗号化されおいないトンネルではありたせん

iipipou: 単なる暗号化されおいないトンネルではありたせん

1 楜芳的 Gbps あたりのチャネル数

iipipou: 単なる暗号化されおいないトンネルではありたせん

iipipou: 単なる暗号化されおいないトンネルではありたせん

いずれの堎合も、ipipou のパフォヌマンスはベヌス チャネルに非垞に近く、これは玠晎らしいこずです。

どちらの堎合でも、暗号化されおいない openvpn トンネルは非垞に奇劙な動䜜をしたした。

誰かがそれをテストする぀もりなら、フィヌドバックを聞くのは興味深いでしょう。

IPv6 ず NetPrickle が私たちずずもにありたすように!

出所 habr.com

コメントを远加したす