Socket.Connect() を SOCKS サーバーに向けると、そのサーバーへの TCP 接続が開きます。続くバイトは依然として SOCKS を話す必要があります。アプリケーションのプロトコルをすぐに送ると、サーバーは別の会話を待ったままになります。

SOCKS5 では、接続の確立に方式のネゴシエーション、選択された認証のやり取り、宛先を指定する要求が含まれます。成功した応答だけがアプリケーションのバイトの経路を開きます。これらの段階は RFC 1928 で定義されています。

ネゴシエーションは接続層に置く

独自の TCP プロトコルを持つアプリケーションは、確立済みのストリームを返すプロキシ対応コネクタを使えます。その後、アプリケーションの残りの部分はそのストリームを通じて読み書きします。コネクタは部分読み取り、可変長アドレス、認証失敗、ネゴシエーションの期限を考慮する必要があります。

固定サイズのバッファを 1 つ読んで成功とみなす手書きの実装は脆いものです。TCP は SOCKS メッセージの境界を保持しません。アプリケーションのプロトコルを開始する前に、アドレスの種類で示される完全な応答を読み取ってください。.NET 7+ の CONNECT 応答リーダーがその手順を示しています。

保守されているライブラリがすでにこの接続層を提供している場合は、対応する SOCKS のバージョン、認証方式、対象フレームワークを確認してください。10 年前のフォーラムのリンクは調査の出発点であり、現在の互換性の証拠ではありません。

HTTP クライアントの構成は別の範囲

HTTP クライアントのプロキシ設定はその HTTP クライアントを構成します。プロセス内のすべての生ソケットを変更するわけではありません。Socket API はネットワークエンドポイントを受け取り、上位層のネゴシエーションを呼び出し元に任せます。

暗号化されたアプリケーションのプロトコルでは、プロキシトンネルが確立した後に TLS ハンドシェイクを行います。その段階で意図した宛先の身元を検証してください。プロキシ認証と宛先認証は、同じ基盤ストリームを使うものの別々のままです。

関連記事