プロキシをアプリケーションコードに組み込む前に、まずは検証可能なツールから動作を確認しておく価値がある。cURLとPostmanは多くの開発者が最初に手を伸ばす2つのツールで、どちらも設定さえ済ませればプロキシをうまく扱えるが、見落とすと分かりにくい挙動を生む設定がそれぞれにある。ここでは両方の動作する設定、重要なデバッグフラグ、そして落とし穴を紹介する。
接続情報はどこでも同じだ。ホストは p.shifter.io、ポートは 443、そしてターゲティング情報を運ぶユーザー名を使う。フォーマットのリファレンスはレジデンシャルプロキシへの接続方法にある。
cURL
設定全体はフラグ1つで済む。
curl -x customer-USERNAME:PASSWORD@p.shifter.io:443 https://ipinfo.io/json
-x と --proxy は同じものだ。これを2回実行すればアドレスが変わるはずで、これによって認証情報とローテーションの両方が一度に確認できる。
ターゲティングはユーザー名の中に入るため、コマンドの他の部分は変わらない。
# ドイツからの出口
curl -x customer-USERNAME-country-de:PASSWORD@p.shifter.io:443 https://ipinfo.io/json
# 10分間のスティッキーセッション
curl -x customer-USERNAME-country-de-sid-abc123-ttl-600:PASSWORD@p.shifter.io:443 https://ipinfo.io/json
認証情報をシェル履歴に残さない
パスワードをURLに埋め込むと、シェル履歴やプロセス一覧に残ってしまう。より良い方法が2つある。
# 認証情報を別に渡す
curl -x p.shifter.io:443 -U customer-USERNAME-country-de:PASSWORD https://ipinfo.io/json
# または環境変数から渡す
export PROXY_USER="customer-USERNAME-country-de"
export PROXY_PASS="..."
curl -x p.shifter.io:443 -U "$PROXY_USER:$PROXY_PASS" https://ipinfo.io/json
-U はプロキシの認証情報で、-u はターゲットサイトの認証情報である点に注意してほしい。この2つを混同することは、パスワード自体は正しいのに407が返る典型的な原因だ。
知っておくべきデバッグフラグ
# プロキシのハンドシェイクと認証が成功したかを確認する
curl -v -x customer-USERNAME:PASSWORD@p.shifter.io:443 https://ipinfo.io/json
# タイミングの内訳: レイテンシがどこで発生しているか
curl -o /dev/null -s -w "connect: %{time_connect}s ttfb: %{time_starttransfer}s total: %{time_total}s\n" \
-x customer-USERNAME:PASSWORD@p.shifter.io:443 https://example.com
2つ目のコマンドは、プロキシ接続が遅いのかターゲットが遅いのかを切り分ける最も速い方法であり、これはリクエストがタイムアウトする理由における最初の分岐点であり、レイテンシの削減の出発点でもある。
cURLでのSOCKS5と落とし穴
HTTPではなくSOCKS5を使う場合、スキームの違いは見た目以上に重要になる。
# DNSがリークする: 自分のマシンがホスト名を解決してしまう
curl -x socks5://customer-USERNAME:PASSWORD@p.shifter.io:443 https://example.com
# 正しい: プロキシ側が解決する
curl -x socks5h://customer-USERNAME:PASSWORD@p.shifter.io:443 https://example.com
h の有無がすべての違いであり、これを間違えるとDNSクエリが自分の所在地から発信されてしまい、地域的に誤った結果が返ってくることがある。詳細はDNSリークの防止を参照してほしい。
決して本番に出してはいけないフラグ
--proxy-insecure はプロキシ区間の証明書検証を無効にする。TLSエラーが証明書の問題なのか他の問題なのかを確認する際にたまに役立つことはあるが、恒久的な設定として残してはならない。
Postman
Postmanのプロキシサポートはしっかりしているが、リクエスト単位ではなくアプリケーション設定で構成する仕組みになっており、リクエスト側にあると思っている人を驚かせる。
設定方法
Settings を開き、次に Proxy タブを開く。システムプロキシのオプションをオフにし、カスタムプロキシ設定を有効にする。プロキシサーバーを p.shifter.io、ポートを 443 に設定し、HTTPとHTTPSの両方にチェックを入れ、その後プロキシ認証を有効にして、ターゲティングフラグを含むユーザー名とパスワードを入力する。
この設定はPostmanアプリ全体に適用されるという点に注意が必要だ。一度設定すると、オフにするまですべてのコレクションのすべてのリクエストがこのプロキシを経由する。内部サービスのテストも同時に行っている場合、それらもルーティングされてしまい、通常は望ましくない結果になる。
挙動を壊す設定
Settings の General の中に SSL certificate verification という項目がある。プロキシ経由で証明書エラーに遭遇してこれをオフにした場合、プロキシ経由のリクエストだけでなく、Postmanが行うすべての処理で検証が無効になっていることを忘れないでほしい。作業後は必ず元に戻すこと。そもそも証明書エラーが出ている場合、それは無効化するのではなく原因を理解すべき事象だ。
ターゲティングを打ち直さずに切り替える
ターゲティング情報はユーザー名の中にあるため、国を変えるにはフィールド1つを編集するだけで済む。Postmanの変数を使えばこれがさらに楽になる。プロキシのユーザー名用の変数を持つ環境を定義し、環境を切り替えることで市場を切り替えられる。プロキシ設定ダイアログは変数構文を受け付けるため、customer-USERNAME-country-{{market}} のように書いておけば、設定を毎回開くのではなくアクティブな環境を切り替えるだけで国を変更できる。
動作確認
GET を https://ipinfo.io/json に送って応答を確認する。ターゲティングした国のアドレスが返るべきで、自分自身のアドレスであってはならない。ユーザー名に sid を含めずに2回送信すれば、アドレスが変わるはずだ。
自分自身のアドレスが返る場合、プロキシがまったく適用されていない。カスタムプロキシ設定が実際に有効になっているか、HTTPとHTTPSの両方にチェックが入っているかを確認してほしい。
Collection Runner
もう少し大きな量でテストするには、Collection Runnerで同じプロキシ設定のもとコレクションを繰り返し実行できる。全力で回すのではなく、繰り返しの間に遅延を入れること。同一のリクエストのバーストは、ターゲットが応答を止める最も速い原因になる。レート制限とスロットリングを参照してほしい。
何かが失敗したとき
ほぼすべてのケースは4種類のレスポンスでカバーでき、それぞれが特定の原因を指し示す。
407 は認証情報が拒否されたか、ユーザー名内のフラグが不正な形式であることを意味する。認識されない値があるとユーザー名全体がパースできなくなるためだ。まずフラグなしの素のユーザー名でテストし、それが動作するならフラグを1つずつ追加していく。詳しい手順は407エラーの修正にある。
502 は認証情報自体は問題ないが、その時点でフィルタに一致するものがなかったことを意味する。フィルタを広げるか、市区町村レベルから国レベルに落とすとよい。
509 はプランの帯域幅が使い切られており、超過オプションが無効になっていることを意味する。
接続拒否またはハング はゲートウェイにそもそも到達できていないことを意味する。プロキシの問題だと決めつける前に nc -vz p.shifter.io 443 を確認し、古いホストを指定していないかも確認してほしい。
より広範な索引はレジデンシャルプロキシの一般的なエラーにある。
ツールからコードへ
両方のツールで動作が確認できれば、同じ4つの値をそのまま構築中のものに移すことができる。クライアント側のパターンはPythonでのレジデンシャルプロキシSの使用にある。1つだけ移らないものがある。アプリケーションコードでは、コネクションの再利用によって、既存のトンネルを通じて送られたリクエストは同じ出口アドレスを保持し続け、これがローテーションが失敗しているように見えることがある。この驚きについてはIPがローテーションしないで扱っている。
結論
cURLでは、すべては -x に集約され、認証情報をURLに含めないための -U、ハンドシェイクを確認するための -v、遅さの原因がプロキシ側かターゲット側かを調べるための -w がある。SOCKS5を使う場合は socks5h を使い、DNS解決がプロキシ側で行われるようにすること。Postmanでは、設定はリクエストではなくアプリケーション設定にあるため、無効化するまでグローバルに適用され続け、SSL検証の切り替えはリクエスト単位ではなくアプリ全体に及ぶ。どちらの場合も、ターゲティング情報はユーザー名の中にあるため、国を切り替える際にホストやポートなど他の何かを変更する必要は一切ない。コードに組み込む前に検証可能なツールで動作を確認し、失敗はステータスコードから読み解くこと。
このすべての背後にあるゲートウェイはレジデンシャルプロキシであり、すべての国とセッションモードにわたって1つのホストと1組の認証情報で利用でき、GB単位で課金されるため、テストには使用した帯域幅分のコストしかかからない。