curlでは、接続先の名前解決をプロキシに任せるなら socks5h:// を選びます。curlがローカルで名前解決し、そのアドレスをプロキシに渡すなら socks5:// です。どちらもSOCKS5を使います。末尾の h はクライアント側のURL表記上の取り決めです。

ローカルの待受アドレスを利用するSOCKS5エンドポイントに置き換え、両方のモードを比較します。

curl --noproxy '' --proxy socks5://127.0.0.1:1080 --connect-timeout 5 --max-time 15 --verbose https://example.com/
curl --noproxy '' --proxy socks5h://127.0.0.1:1080 --connect-timeout 5 --max-time 15 --verbose https://example.com/

変わるのは名前解決のモードだけです。--noproxy '' はこの呼び出しでのプロキシ除外ルールを解除し、時間制限は比較にかかる時間を抑えます。同等の専用オプションは --socks5 と --socks5-hostname です。接続先にはホスト名を指定してください。IPアドレスを直接書くと接続先の名前解決が不要になり、この違いを確認できません。

片側でしか解決できない名前もある

プロキシが開発用ネットワーク内で動き、そのDNSが内部サービスの名前を知っているとします。手元のノートパソコンでは socks5 モードでその名前を解決できなくても、socks5h ならプロキシに解決を任せられます。逆に、その名前がノートパソコンのhostsファイルにしか定義されていなければ、リモート側での名前解決が失敗することがあります。

公開DNSも、問い合わせるネットワークによって異なるアドレスを返す場合があります。結果が違うときは、すぐにプロキシを交換するのではなく、選ばれたアドレスと到達性を比較してください。

  • プロキシのホスト名を解決できない:どちらのモードも開始できません。proxy.example は、socks5h://proxy.example:1080 でもクライアントが名前解決します。
  • 接続先のローカル名前解決に失敗する:クライアントのリゾルバーを確認するか、プロキシにホスト名を渡すモードと比較します。
  • SOCKSサーバーが接続先を拒否する:応答とポリシーを確認します。ローカルで名前解決できても、リモートから到達できるとは限りません。
  • トンネルは使えるが証明書検証に失敗する:接続先のTLSを調べます。DNSモードを変えることは、信頼の問題を一律に解決する方法ではありません。

管理下のプロキシなら、制御できるテスト用の名前とサーバー側ログで、どのアドレス形式がプロキシに届いたかを確認できます。出口IPを表示するページでは確認できません。分かるのは外向き接続の情報であり、DNSの名前解決が行われた場所ではないからです。

プライバシー上の効果には範囲がある

プロキシ側で名前解決すると、このリクエストについては接続先のローカル名前解決を避けられます。SOCKSを暗号化するわけでも、プロキシが暗号化DNSを使う証明になるわけでもありません。他のアプリやブラウザーのプリフェッチ通信までプロキシ経由になるわけでもありません。SOCKS対応のRequestsにも同じローカル側・プロキシ側の区別があります。他のクライアントでは、curlのURL表記ではなく設定項目で切り替える場合があります。SOCKS5プロキシ一覧から接続先をコピーする前に、アプリが対応するプロトコルを選んでください。

関連記事