407 プロキシ認証が必要: 原因とその解決方法

HTTP 407 の意味は一つだけです: あなたの前にあるプロキシがあなたの認証情報を拒否しました。この事実により、多くの誤った方向を排除できます — ここに残りの地図があります。

HTTP 407 プロキシ認証が必要の意味は一つだけで、多くの人が想定するよりも狭いものです: インターネットとあなたの間にあるプロキシが、プロキシ自体の有効な認証情報がないためにリクエストを拒否しました。ターゲットウェブサイトには一度も接触していません。リクエストを見たことも、判断を下したこともなく、原因にはなり得ません。したがって、407 を修正するということは常にプロキシの設定を修正することを意味します — そしてそれに関する問題のリストは短く、完全に列挙可能です。このガイドはそのリスト全体を歩き、人々を最もつまずかせるツール固有の修正を提供します。

まず Proxy-Authenticate ヘッダーを読む

HTTP 仕様書 (RFC 9110) によれば、407 は Proxy-Authenticate ヘッダーを伴い、認証方法を説明する必要があります — 通常は Proxy-Authenticate: Basic realm="Access to internal site" のようなものです。その後、クライアントは Proxy-Authorization ヘッダーを付けてリクエストを再送信することが期待されます。このペアリングは覚えておく価値があります、なぜならそれが 407 をその隣の 401 と区別するものだからです: 401 はオリジンサーバーから来て WWW-AuthenticateAuthorization をペアリングし、407 は中間者から来て Proxy- プレフィックス付きのバージョンを使用します。もし WWW-Authenticate ヘッダーを見ているなら、間違ったホップをデバッグしています。

# See exactly which hop is refusing you, and what scheme it wants
curl -v -x http://USER:PASS@gate.quantumproxies.io:8000 https://httpbin.org/ip

# Response you are looking for on failure:
#   HTTP/1.1 407 Proxy Authentication Required
#   Proxy-Authenticate: Basic realm="..."
#
# Response you want on success: your exit IP, not your own
#   {"origin": "203.0.113.45"}

curl -x で認証情報を使用してあなたの出口 IP が返ってくる場合、プロキシと認証情報の両方が問題ないことを示しています — そしてアプリケーションでまだ 407 が表示される場合、それはアプリケーション自身の設定であり、プロキシのものではありません。この単一のテストは問題を約 10 秒で半分に分割します。

原因1: 認証情報が欠落している、間違っている、または間違った場所にある

最も一般的な原因はまた最も退屈なものです。認証情報はプロキシ URL に属し、ホストの前に user:pass@host:port 形式で配置されます — そしてクライアントライブラリはそれらから Proxy-Authorization ヘッダーを構築します。ダッシュボードから認証情報なしでエンドポイントをコピーしたり、プロキシパスワードの代わりにアカウントパスワードを貼り付けたりすると、すべてのリクエストで即座に、永続的に 407 が発生します。

import requests

proxy = "http://USER:PASS@gate.quantumproxies.io:8000"
proxies = {"http": proxy, "https": proxy}

r = requests.get("https://httpbin.org/ip", proxies=proxies, timeout=15)
print(r.status_code, r.json())   # 200 and the exit IP = auth is correct

ポートも確認してください。プロバイダーは、回転エンドポイントとスティッキーエンドポイント、HTTP と SOCKS5 のために異なるポートを公開しています。有効な認証情報を持っていても間違ったポートにアクセスすると、リスナーが異なるアイデンティティ形式を期待しているため、407 が返されることがあります。どのプロトコルを使用しているかわからない場合は、SOCKS5 と HTTP プロキシの違いに関する説明をご覧ください。

原因2: パーセントエンコードされていない特殊文字

これにより人々は丸一日を費やすことになります。プロキシ URL は URL であるため、ユーザー名やパスワードに含まれる予約文字はすべてパーセントエンコードされなければならず、さもなければパーサーは文字列を間違った場所で分割します。@ を含むパスワードは、userinfo セクションを早期に終了させ、クライアントは存在しないホストに接続しようとします。: はユーザー名とパスワードを間違った場所で分割します。

from urllib.parse import quote

user = quote("team@example.com", safe="")   # team%40example.com
pwd  = quote("p@ss:w#rd", safe="")          # p%40ss%3Aw%23rd

proxy = f"http://{user}:{pwd}@gate.quantumproxies.io:8000"
407 プロキシ認証が必要な症状をトンネルの失敗、ホワイトリストの変更、ツールごとのプロキシ設定などの実際の原因にマッピングするチェックリスト
同じステータスコード、6 つの異なる故障。何かを変更する前に左側の症状に一致させてください。

原因3: ホワイトリスト認証と移動した IP

ほとんどのプロバイダーは 2 つの認証モードをサポートしています: URL 内の認証情報、または IP ホワイトリストで、ダッシュボードでサーバーのパブリックアドレスを承認し、認証情報を一切送信しません。QuantumProxies は両方をサポートしています。故障モードは特定で非常に認識しやすいです: 数週間うまく動作していたのに、コードを変更せずにすべてのリクエストが 407 を返し始めました。それはあなたのパブリック IP が変わったことを意味しています — オフィスでの DHCP リース更新、クラウド再デプロイ後の新しい NAT ゲートウェイ、モバイルテザリング、またはジョブごとに新しいアドレスを取得する CI ランナーです。

他のデバッグをする前にそれを確認してください: curl -sS https://api.ipify.org で現在のパブリックアドレスを取得し、ホワイトリストと比較し、異なる場合は再追加してください。出口 IP が安定していない場合 — CI ランナーやオートスケーリンググループはほとんどそうです — その環境をネットワークではなく設定と共に移動する user:pass 認証に切り替えてください。このトラップのもう一つの半分はモードの混在です: 一部のゲートウェイはホワイトリスト専用エンドポイントで認証情報を拒否するため、両方を送信すると何も送信しない場合に成功するところで失敗することがあります。

原因4: HTTPS が CONNECT トンネルを通過する

https:// URL でのみ表示される 407 は、Python エラー OSError: Tunnel connection failed: 407 Proxy Authentication Required としてよく現れ、構造的な原因があります。プレーンな HTTP リクエストはプロキシによって転送されますが、HTTPS リクエストは CONNECT リクエストで最初にトンネルを開きます — そしてその CONNECT は独自の Proxy-Authorization ヘッダーを持ちます。設定が HTTP プロキシのみを設定している場合、または一方のスキームにのみ認証情報を設定している場合、トンネルは匿名で試みられ、TLS が開始される前に拒否されます。

ルールは簡単です: 常に両方のスキームを同じ認証情報で設定してください。Python では proxies 辞書の両方のキーを意味し、シェルでは HTTP_PROXYHTTPS_PROXY を意味し、npm では proxyhttps-proxy を意味します。HTTPS_PROXY はほとんど常に http:// スキームを取ります — スキームはプロキシとどのように通信するかを説明し、それを通して何を取得するかではありません。

// Node 18+ with undici: one dispatcher covers http and https targets
import { ProxyAgent, fetch } from "undici";

const dispatcher = new ProxyAgent(
  "http://USER:PASS@gate.quantumproxies.io:8000"
);

const res = await fetch("https://httpbin.org/ip", { dispatcher });
console.log(res.status, await res.json());

原因5: ツールが独自のプロキシ設定を持っている

環境変数は普遍的ではありません。多くのツールは独自の設定ファイルを読み込み、シェルを完全に無視します。これにより、curl が動作し、ビルドが動作しないという苛立たしい状態が生じます。長期にわたる GitHub Desktop の問題は教科書的な例です: コーポレートプロキシの背後にいる開発者が .gitconfig と環境にプロキシを設定していたにもかかわらず、サインインが 407 と net::ERR_TUNNEL_CONNECTION_FAILED で失敗し続けました — なぜなら git 設定は git のみを認証し、OAuth フローを行う埋め込みブラウザには独自のプロキシ認証情報がなかったからです。すべてのサブシステムは別々に指示が必要です。

# shell-wide (respected by curl, wget, pip, most SDKs)
export HTTP_PROXY="http://USER:PASS@gate.quantumproxies.io:8000"
export HTTPS_PROXY="$HTTP_PROXY"
export NO_PROXY="localhost,127.0.0.1,.internal"

# npm - both keys, or https installs will 407
npm config set proxy       "$HTTP_PROXY"
npm config set https-proxy  "$HTTPS_PROXY"

# git
git config --global http.proxy  "$HTTP_PROXY"
git config --global https.proxy "$HTTPS_PROXY"

# apt - /etc/apt/apt.conf.d/95proxies
# Acquire::http::Proxy  "http://USER:PASS@gate.quantumproxies.io:8000";
# Acquire::https::Proxy "http://USER:PASS@gate.quantumproxies.io:8000";

これらのファイルを編集している間のセキュリティノート: グローバルな git または npm 設定にある認証情報はプレーンテキストで終わり、埋め込まれたパスワードを持つプロキシ URL はシェル履歴、CI ログ、エラートレースに漏れます。安定したアドレスを持つマシンでは、IP ホワイトリストを使用することで秘密を完全に回避できます。

ユーザー:pass プロキシ認証と IP ホワイトリスト認証の比較、移植性と秘密管理のトレードオフを示す
認証情報は設定と共に移動し、ホワイトリストはネットワークと共に移動します。環境ごとに選択し、一度に両方を使用しないでください。

407 はターゲットサイトのせいではありません

再確認する価値があります、なぜならそれは幽霊を追いかけることからあなたを救うからです。407 を受け取っている場合、ユーザーエージェントを回転させたり、ヘッダーを追加したり、出口国を変更したりしても役に立ちません — リクエストはまだプロキシを離れていません。ターゲットからのブロックは異なって見えます: 403 Forbidden はサイトがあなたを拒否したことを意味し、429 Too Many Requests はあなたが速すぎたことを意味します。コードを書く前にどの 3 つのうちのどれを実際に持っているかを診断してください。そして Python が ProxyError または SSLError を投げている場合は、クリーンな 407 ではなく、Requests の ProxyError のデバッグ に関するガイドがトランスポートレベルの障害をカバーしています。

よくある質問

407 プロキシ認証が必要をどのように解決しますか?

予約文字をパーセントエンコードし、HTTP と HTTPS の両方のプロキシ設定を構成して、http://user:pass@host:port としてプロキシ URL に有効な認証情報を入力します。プロバイダーが代わりに IP ホワイトリストを使用している場合は、現在のパブリック IP を承認し、認証情報を送信しないでください。アプリケーションコードに触れる前に、IP エコーサービスに対して curl -x で確認してください。

407 プロキシ認証が必要とは何を意味しますか?

それは中間のプロキシが有効なプロキシ認証情報の不足のためにリクエストを拒否したことを意味します。応答にはスキームを示す Proxy-Authenticate ヘッダーが含まれ、クライアントは Proxy-Authorization で再試行することが期待されます。それは 401 とは異なり、401 はプロキシの間ではなく、宛先サーバーから来ます。

npm エラー 407 をどのように修正しますか?

両方のキーを設定します: npm config set proxynpm config set https-proxy、それぞれ完全な http://user:pass@host:port URL で。レジストリトラフィックは HTTPS であるため、HTTP のみの設定は CONNECT トンネルで失敗します。パスワードの特殊文字をパーセントエンコードし、プロジェクトレベルの .npmrc がグローバルなものを上書きしているか確認してください。

なぜ Python は Tunnel connection failed: 407 を発生させるのですか?

それは HTTPS リクエストがプロキシ認証情報を持たない CONNECT トンネルを開いたためです。proxies 辞書の httphttps の両方のキーを同じ認証済み URL に設定してください。また、環境内の HTTP_PROXY または HTTPS_PROXY が辞書を上書きしているかどうかを確認してください — session.trust_env = False を設定してそれを除外してください。

Postman でプロキシ認証をどのように設定しますか?

設定を開き、プロキシタブに移動し、カスタムプロキシ設定を有効にし、ホストとポートを入力し、プロキシ認証ボックスをチェックしてユーザー名とパスワードを追加します。システムプロキシトグルに頼るのが通常の間違いです — それはプロキシを通じてトラフィックをルーティングしますが、認証情報を一切提供しないため、すべてのリクエストが 407 を返します。

5 つの原因が、実際に存在するほぼすべての 407 をカバーしています: 認証情報の欠落、エンコードされていない特殊文字、変更されたホワイトリスト IP、認証されていない CONNECT トンネル、独自の設定を持つツールです。それらをその順序で処理すると、ステータスコードは消えます — その後、ターゲットサイトがあなたをどう思っているかを心配し始めることができます。

ユーザー:pass または IP ホワイトリスト認証を使用した住宅プロキシを取得