プロジェクトのアドレス#
注:開発者の発言は個人の意見を代表するものであり、コードはオープンソースであり、プロトコルに関する追加の説明は提供されません。
プロジェクトの特性#
-
利点
- 既存の TCP プロキシツールとシームレスに統合可能
- 検出、通報、スニッフィングに耐性がある
- 平文モードでは中継デバイスのパフォーマンスにほとんど負荷がかからない
- コードはオープンソースであり、DPDK、eBPF などの技術を使用して大規模なスループットを実現するために自分で変更できる。
- 現在のすべてのファイアウォールの弱点に対応しています(つまり、TCP の 3/4 タプルを使用して接続を追跡する)
-
欠点
- 暗号化されていない場合、バイナリマッチングに対して無力です
- 暗号化されたストリームはファイアウォールがトラフィックに対する関心を高め、遅延やパケットの損失が発生する可能性がありますが、5TB の単方向ではポートブロッキングは発生しません。
- DDoS 緩和メカニズムの誤判定を引き起こし、トラフィックをブロックしたり既存の接続をリセットしたりする可能性があります。
-
おもちゃ
このプロジェクトは、作者のおもちゃであり、概念の検証であり、継続的なメンテナンスを意図していません。
オープンの理由は、現在の環境に新しいアイデアを提供することだけを意図しています。
実装#
イントロダクション#
現在、インターネット上には多くのフリーゲートウェイプロトコルがありますが、実装のレベルはまちまちですが、それぞれに問題があります。Shadowsocks をはじめとする完全な暗号化ストリームは、アクティブなスニッフィングと完全なランダムトラフィックの正確な識別の問題を解決した後でも、まだ多くの人々の選択肢です。R 氏が開発したさまざまな TLS ベースのトリックも、個人のトラフィックが森の中の木を隠すのに成功しています。
しかし、これらのプロトコルは実際のアプリケーションでまだ自分自身の脆弱性を持っています:ファイアウォールが審査、監視などの機能をエッジデバイスにオフロードするようになった今日、個人のユーザーデバイスからの完全な暗号化トラフィックは、コミュニティエリアネットワークの中の明るい光のようなものです。一般ユーザーは、R 氏が提供する証明書の盗聴機能を使用する際に、信管局からのスニッフィングと監視を忘れがちであり、最終的には通報と退去の対象になります。
そして、これらの 2 つの設計アイデアには、重大な問題があります:暗号化のオーバーヘッド。ほとんどのプロキシツールのクライアントデバイスは、5 年前に製造された CPU と完全な物理デバイスパフォーマンスを使用しており、OpenSSL の暗号化スイートの実行に必要なパフォーマンスを簡単に提供できます。一方、サーバーサイドは、パフォーマンスが厳密に制限されている仮想ホストです。より高いスループット帯域幅を実現するために、主流の 1 コア 512MB の構成は既に限界に達しています。一般的な開発言語である Golang は、メモリのオーバーヘッドにより、サーバーサイドでのパフォーマンスにさらなる悪影響を与えます。
目的#
ファイアウォールがトラフィックを監視する原理に基づいてプロトコルを設計し、サーバーサイドの暗号化強度を低下させることが、プロジェクトの主な目標となりました。過去のさまざまなオープンソースプロジェクトを振り返った後、痛ましい事実が浮かび上がりました - 過去に提案された西厢計画は、現在、ファイアウォールをバイパスし、外部ネットワークにアクセスする唯一の原理ベースのプロジェクトです。
現在の状況では、このような脆弱性を見つけることはほとんど不可能であり、ファイアウォールがトラフィックを認識する原理に基づいて処理する必要があります。現代のファイアウォールおよび市販のファイアウォールは、すべてのトラフィックスニッフィングが 3 タプルまたはより詳細な 4 タプルに基づいているため、次のようになります:
(source IP, destination IP, destination PORT)
(source IP, source PORT, destination IP, destination PORT )
ひとつのアイデアが私たちの心に浮かび上がりました:元々の 3 タプルを 2 つの異なる 3 タプルに分割した後、ファイアウォールはまだ内部データパケットを関連付けたり監視したりする能力を持っているのでしょうか?
設計思想#
内部では、usenix23 で列挙されたファイアウォールトラフィックの免除ルールを事前にまとめており、ほぼすべてのルールに合致するハンドシェイク応答を設計しました。すべての印刷可能なバイトで構成され、文字レベルではランダムであり、バイナリレベルでは低エントロピーです。
パブリック IP がない場合を考慮して、この設計ではすべての接続がクライアント側でアクティブに確立され、データがサーバーに転送されます。
一部の省市および特定のシナリオで使用されるファイアウォールおよびルールにはバイナリマッチングの能力があるため、このプロトコルにはオプションの暗号化スイートも組み込まれています。
欠点#
-
平文のハンドシェイクパケットを使用してファイアウォールがこの TCP 接続を初期段階で無視するようにするが、この 3 タプルの遅延増加度合いとパケットロスの状況を継続的に検出できず、現在発見されていない探査メカニズムが存在する可能性があるかどうかを確認できません。
-
平文のハンドシェイクパケットを使用してファイアウォールがこの TCP 接続を初期段階で無視するようにするが、この 3 タプルの遅延増加度合いとパケットロスの状況を継続的に検出できず、現在発見されていない探査メカニズムが存在する可能性があるかどうかを確認できません。
-
48 時間程度の連続稼働後、モバイルは直接リンクをブロックしますが、どのメカニズムがトリガーされたのかはわかりません。電信ユニオンには異常は見られませんでした。
-
平文のハンドシェイクパケットが機能しているのか、3 タプルの分割が機能しているのかを確認できません。(AES の特徴爆破の可能性を考慮して... 個人的には両方が機能していると思います)
設定ファイル#
サンプル#
[app]
alignment=4096
mode=client
ip=::
port=30000
inbound-ip=localhost
inbound-port=10000
outbound-ip=localhost
outbound-port=20000
turbo=true
backlog=511
fast-open=true
keep-alived=true
connect.timeout=10
handshake.timeout=5
protocol=tcp
その他の設定については、samples ディレクトリを参照してください。
パラメータの説明#
-
alignment
alignment_malloc メモリアライメントパラメータ
-
mode
実行モード、[client, server]
-
ip
クライアントモードの場合、リッスンする IP を示します。サーバーモードの場合、元の宛先 IP を示します。
-
port
クライアントモードの場合、リッスンするポートを示します。サーバーモードの場合、元の宛先ポートを示します。
-
inbound-ip
上りリンクの TCP 接続に使用する IP を設定します。
-
inbound-port
上りリンクの TCP 接続に使用するポートを設定します。
-
outbound-ip
下りリンクの TCP 接続に使用する IP を設定します。
-
outbound-port
下りリンクの TCP 接続に使用するポートを設定します。
-
turbo
TCP 接続の高速化
-
backlog
TCP 接続のバックログパラメータ
-
fast-open
TCP-Fast-Open を有効にする
-
keep-alived
TCP Keep-alive を有効にする
-
connect.timeout
TCP タイムアウト時間を設定します
-
handshake.timeout
プロトコルのハンドシェイクタイムアウト時間を設定します
-
protocol
トランスポートプロトコル、TCP はハンドシェイクパケット以外を暗号化しないことを示します。
使用例#
warp+uds#
Cloudflare が提供する warp は、国際ルーティングの改善と送信の可能性を減らすために、ネットワーク品質が一般的に低いいくつかの仮想ホストにデプロイされるツールとしてよく使用されます。Cloudflare は、ほとんどの Linux ディストリビューションに対してパッケージマネージャーを介したインストール方法を提供しています。
-
WARP のインストール
ここでは、Cloudflare 公式チュートリアルを参照してください。 -
モードの切り替え
WARP を正常にインストールし、クライアントを登録した後、クライアントの実行モードをプロキシモードに切り替えます。warp-cli set-mode proxy
-
WARP が使用するポートの変更(オプション)
WARP はプロキシモードでデフォルトでポート 1080 でリッスンします。warp-cli set-proxy-port [PORT]
WARP はデフォルトで 127.0.0.1 上のポートのみをリッスンするため、この socks5 ポートがスキャンされる心配はありません。
-
UDS サーバーの起動
次のような設定ファイルを使用します。
[app]
alignment=4096
mode=server
ip=127.0.0.1
port=1080
inbound-ip=::
inbound-port=10000
outbound-ip=::
outbound-port=20000
turbo=true
backlog=511
fast-open=true
keep-alived=true
connect.timeout=10
handshake.timeout=5
protocol=tcp
UDS サーバーを起動します。
./udss --config=config.ini
- UDS クライアントの起動
[app]
alignment=4096
mode=client
ip=127.0.0.1
port=1080
inbound-ip=[remote IP]
inbound-port=10000
outbound-ip=[remote IP]
outbound-port=20000
turbo=true
backlog=511
fast-open=true
keep-alived=true
connect.timeout=10
handshake.timeout=5
protocol=tcp
- 接続
好きなツールで socks5://127.0.0.1:1080 に接続してください
Dante + UDS#
Cloudflare のように、国際ルーティングを改善し、送信の可能性を減らすために使用されるツールではなく、私は個人的に軽量な Dante を使用して socks5 接続を作成することを好みます。
手順は warp と非常に似ていますので、ここでは詳細を省略します。
既存の中継接続への UDS の組み込み#
テスト中は、純粋な vless データストリームを暗号化せずに中継できます。
-
ディスクトップデバイスで udss をダウンロードします。
-
サーバーターゲットポートを元のプロキシのリッスンポートに設定します。
-
中継機で udsc をダウンロードします。
-
クライアントの上りリンクと下りリンクをサーバーに対応させます。
-
クライアントのリッスンアドレスとポートを設定します。
スムーズな移行が必要な場合は、元のポートを使用しないでください。UDS を起動する前に元のサービスを停止することをお勧めします。
-
uds クライアントを起動します。
結論#
uds は概念実装に過ぎず、本番環境での大規模な使用はお勧めしません。また、UDP over TCP の転送シナリオには適していません。UDP トラフィックが必要な場合は、コードを変更して実装してください。
uds のすべてのコードは MIT ライセンスに従っています。