SOCKS5・SOCKS4プロキシ
SOCKSプロキシでは、アプリが中間サーバーに接続先への接続を依頼します。プロキシは要求された接続を開き、双方向にデータを渡します。アプリ自身のプロトコルを使い続けられるため、ウェブ要求、APIクライアント、ファイル転送などのSOCKS対応ソフトウェアで使えます。
新規構成では通常、より多くのアドレス形式、認証方式の選択、UDP対応を備えるSOCKS5が有用です。古いバージョンを要求するソフトウェアでは、SOCKS4にも用途があります。HTTPも含めた選択はSOCKSとHTTPプロキシで説明しています。
アプリがSOCKS経由で接続する方法
SOCKS5プロキシでhttps://example.com/を開く例です。まずプロキシに到達し、サイトへの接続を要求してから、サイトのデータをやり取りします。4段階あります。
- アプリがTCPでプロキシのホスト名またはIPと、待ち受けポートへ接続します。
- アプリとプロキシがアクセス方式を選びます。認証情報が必要なら、アプリが提供し、プロキシが確認します。
- アプリが接続先アドレスとポートを指定した
SOCKS CONNECTを送ります。プロキシはアクセス規則を確認して接続を試み、結果を返します。 - 成功応答後、アプリはプロキシ経由で通信します。HTTPSサイトでは、サイトとTLSを確立して証明書を検証してから、要求を送ります。
2つのポートは別サーバーのものです。例のプロキシがproxy.example:1080で待ち受け、サイトがexample.com:443の場合があります。1080はSOCKSの慣用ポートですが、別番号も使えます。指定の待ち受けポートを使ってください。接続先ポートの代わりにはなりません。
通常のTCP転送では、各HTTP要求やファイル操作命令を解釈せず、アプリのバイトストリームを渡します。アプリは自身のプロトコルで接続先と話し続けます。そのため、同じSOCKSの接続機構をウェブクライアントやほかのソフトウェアに使えます。
CONNECTはSOCKS内のコマンドで、固有の形式を持ち、HTTPのCONNECTメソッドとは異なります。アクティブFTPなど、サーバーからプロキシ経由で戻り接続が必要なアプリ向けに、BINDも定義されています。BINDには個別対応が必要で、通常のサイトやAPI要求には使いません。
SOCKS4・SOCKS4a・SOCKS5の違い
SOCKS4はIPv4アドレスへのTCP接続を作ります。SOCKS4aはホスト名を送る選択肢を加え、プロキシがDNSでIPを調べられます。SOCKS5は認証方式の選択を追加し、IPv4、IPv6、ホスト名を受け付け、UDP転送を定義します。
| 機能 | SOCKS4 | SOCKS4a | SOCKS5 |
|---|---|---|---|
| 外向きTCP接続 | 対応 | 対応 | 対応 |
| 要求内の接続先 | IPv4アドレス | IPv4アドレスまたはドメイン名 | IPv4アドレス、IPv6アドレス、ドメイン名 |
| プロキシでのホスト名解決 | 非対応 | 対応 | 対応 |
| 標準のユーザー名・パスワード方式 | 非対応 | 非対応 | 対応 |
| UDP中継の仕組み | 非対応 | 非対応 | 対応 |
これらはプロトコルの機能です。使いたい機能を、クライアントとサービスが実装している必要があります。たとえばSOCKS5サービスでも、TCP接続だけで、使えるUDP中継がない場合があります。
SOCKS5は要求にIPv6接続先を含められますが、プロキシがそのIPv6サーバーへ到達できる必要もあります。アプリはIPv4でプロキシへ、プロキシはIPv6で接続先へと、2つの接続で別バージョンを使えます。
SOCKS4aはSOCKS4の拡張で、あらゆるSOCKS4接続の別名ではありません。IPv4しか送れない古いクライアントは、SOCKS4を選んでもリモートDNSを使えません。4aは両端対応が必要です。両端が対応すれば通常SOCKS5が簡単です。4を選ぶだけで、出口IPの評判や速度は良くなりません。
接続先の名前を誰が解決するか
名前のあるサーバーへ到達する前に、IPへの変換が必要です。SOCKS5は照会結果と名前自体のどちらも受けられます。何を送るかはクライアントのDNS設定が決めます。
ローカルDNSでは、アプリが設定済みリゾルバーにreports.exampleを照会します。結果が203.0.113.27なら、203.0.113.27:443へのSOCKS接続を要求します。その後サイト接続がプロキシ経由でも、照会はクライアント側で完了しています。
プロキシ側DNSでは、ローカルで先に照会せずreports.example:443を送ります。プロキシがDNSでIPを取得し、接続を開きます。ホスト名はSOCKS要求の一部として届きます。
クライアントで解決できず、プロキシで解決できる名前に役立つ場合があります。リゾルバーで異なるアドレスを返すサービスもあるため、照会場所で接続先サーバーが変わることがあります。出口の国を設定したり、サイトの受け入れを保証したりはしません。
curlでは、次の2つのコマンドでDNS方式を選べます。
curl --proxy socks5://proxy.example:1080 https://example.com/
curl --proxy socks5h://proxy.example:1080 https://example.com/
socks5://はcurlでローカル解決し、socks5h://は名前をプロキシへ渡します。どちらもSOCKS5です。hは、このクライアントのURL構文で、プロキシによる名前解決を表します。HTTPSへの変更や暗号化追加ではありません。ほかのアプリはチェック欄や自動選択を使う場合があります。例のホスト名とポートを実サービスに置き換え、必要な認証を指定します。
SOCKS5のTCP要求でドメインを渡すのにUDP中継は不要です。プロキシが独自のDNS設定で照会します。クライアントのUDPパケットをSOCKS5で運ぶ要求とは別です。
接続先DNSを任せる設定なのにローカル照会すれば、予定経路の外で要求名が明らかになります。これがDNSリークです。暗号化DNSはリゾルバーとの通信を守りますが、リゾルバーには名前が届きます。プロキシ自体の名前解決は別で、ほかのアプリのDNSも独立です。1プログラムのリモートDNSが、端末の全照会を移すわけではありません。
認証と暗号化
SOCKS5では、クライアントが対応方式を提示し、プロキシが選びます。ユーザー名とパスワードのほか、SOCKSのログイン通信をしない接続もあります。サービスが送信元IPを許可リストと照合してから許可する場合があります。パスワード欄がなくても、アクセスを制限できます。
方式の合意失敗とパスワード拒否は別です。前者では、まだパスワード交換をしていません。SOCKS5設定があっても、その認証に対応しなければパスワード専用接続先は使えません。SOCKS4にはユーザーID欄がありますが、同等の標準パスワード交換はありません。それでもサーバーはアクセス規則を適用できます。
通常のSOCKS5ユーザー名・パスワード交換は、認証情報を暗号化しません。接続先とのHTTPS確立より前なので、後のHTTPSは先のログインを守りません。クライアントからプロキシまでの暗号化には、別の保護された接続か、明示的に対応する安全機構が必要です。
通常のSOCKS転送では、証明書検証が有効でTLS傍受がなければ、HTTPSがアプリとサイト間を守ります。暗号化しないアプリプロトコルは、中継でも平文のままです。SOCKS5対応やパスワード認証だけでは、暗号化通信は約束されません。
プロキシには、クライアントの接続IP、要求先、時刻が分かります。接続先には出口IPと自分宛てのアプリデータが届きます。Cookie、ログイン、アプリ識別子で利用者を識別でき、SOCKSバージョンを変えても消えません。
SOCKS5でのTCPとUDPの転送
TCPは順序を保ったバイトストリームを提供します。クライアントが経路に対応し、プロキシが接続先を許せば、ブラウザー要求、API、SSHで使えます。サイトの443番で成功しても、他アプリのポートが使える証明ではありません。
UDPは独立したデータグラムを送ります。SOCKS5クライアントは先にTCP制御接続を開き、UDP ASSOCIATEで中継を要求します。プロキシは中継アドレスとUDPポートを返します。クライアントは接続先を記したSOCKSヘッダー付きでそこへ送ります。TCP制御接続を閉じるとUDP関連付けも終わります。データグラムは制御接続とは別に流れ、通常のSOCKS CONNECTストリーム内を通るわけではありません。
アプリとサービスが対応し、ネットワークがUDP経路を許可する必要があります。TCPログインが成功しても、音声、ゲームなどのUDP機能は失敗する場合があります。SOCKS CONNECTのHTTPS成功はTCP転送の証明で、UDPの証明ではありません。QUICはUDPを使いますが、実際の利用にはクライアントと全経路が関係し、SOCKS5だけでは分かりません。
SOCKSが役立つ用途
独自のアプリプロトコルを保ったまま中間接続が必要なときに有用です。スクリプトで指定出口IPからAPIを要求する、ファイル転送で許可経路からリモートサーバーへつなぐ、ブラウザーでない対応デスクトップアプリでプロキシを使う、といった例です。いずれもクライアントのSOCKS対応とサービスの許可ポート次第です。
同じアカウントやサーバーを繰り返し使うなら固定出口、独立タスクならローテーションが適する場合があります。この動作をSOCKS4・5は決めません。出口IP、ネットワーク種類、共有、変更時点はサービスが決めます。バージョンに速度の順位もなく、経路長、負荷、帯域幅が影響します。
クライアントの対応範囲はプロトコルより狭い場合があります。Chrome内蔵SOCKS5はプロキシで名前解決しますが、ユーザー名・パスワード認証やUDP中継はしません。パスワード専用接続先がcurlでは動き、内蔵ブラウザー設定では失敗する場合があります。外部アダプターは独自の機能を持つ別の接続要素です。
アプリ内の設定は、そのアプリが対応する接続に適用され、別のダウンローダーやスクリプトを設定しません。システム設定も、それを使うソフトウェアだけに作用します。ネイティブSOCKS未対応アプリをアダプターで転送する場合、TCP・UDP・DNSの範囲が重要です。通常のICMP転送はないため、pingはこの経路のテストになりません。
接続設定と有用なテスト
提供されたアドレス、待ち受けポート、SOCKSバージョン、アクセス方法から始めます。1080などの数字だけではプロトコルは特定できません。HTTP専用欄に同じ値を入れず、クライアントでSOCKSを選びます。
プロキシ認証情報は中間サービス、サイトログインはサイトの利用を認可し、別々の設定です。curlでは--proxy-userがプロキシ、--userが接続先の認証情報です。IP方式では、プロキシが見る送信元IPと許可リストを合わせます。ネットワーク変更で変わる場合があります。
DNS方式を選び、迂回規則を確認します。除外リストの接続先では、プロキシを使わない場合があります。curlのNO_PROXYが原因となり得ます。意図的にプロキシ経路をテストする際は、--noproxy ""で1回の実行の除外を消せます。
実際に作業するプログラムでテストします。IP確認先や管理する接続先のログから送信元IPを確認し、直結の要求と比べます。プロキシ接続用のアドレスと、接続先が見る出口は同一とは限りません。
その後、実タスクを試します。IP変更はその要求の経路を示しますが、全転送方式の測定や他サイトの応答の証明にはなりません。必要ならUDPやIPv6を別に試し、代表的負荷で応答時間と安定性を評価します。
接続段階でエラーを特定する
プロキシへの到達、アクセス取得、接続先の接続、アプリの応答を区別します。原因が異なります。
| 失敗するもの | 確認項目 |
|---|---|
| プロキシ接続のタイムアウトや拒否 | ホスト名、待ち受けポート、到達性、アクセス制限です。まだ接続先への接続は開いていません。 |
| 受け入れられる認証方式がない | この接続先が受ける方式にクライアントが対応するかです。まだパスワードの正誤判断ではありません。 |
| ユーザー名・パスワードが拒否される | パスワード方式が選ばれたことを確認したうえで、認証情報とアカウント権限を調べます。 |
| 接続先名を解決できない | どちらが照会するかを確認します。ローカルDNSエラーは、SOCKSに接続を頼む前に起き得ます。リモートDNSでは、プロキシがIPを得る必要があります。 |
| プロキシが接続先や操作を拒否する | アクセス規則、接続先ポート、要求コマンド・アドレス型への対応です。規則による拒否と、UDPコマンドやIPv6の非対応は別です。 |
| プロキシから接続先に届かない | プロキシのネットワークから見たアドレス、ポート、可用性です。接続先が到達不能か拒否している場合があります。 |
検証済みHTTPSが成功してログインページ、CAPTCHA、拒否が返るなら、SOCKSはその通信を運んでいます。サイトの応答とアプリ動作を調べます。いつものパブリックIPが見えるなら、そのプログラムのプロキシ選択と迂回規則を確認します。
