WindowsのプロキシはなぜGUIだけでは足りない? — WinINET・WinHTTP・環境変数を図解
「プロキシをGUIで設定したのに、Windows Updateが失敗する」「ブラウザは繋がるのにライセンス認証や証明書チェックがタイムアウトする」——プロキシ環境のサーバーやVDIで頻発する定番トラブルです。原因は、Windowsのプロキシ設定が“3系統”に分かれていて、プロセスごとに見る場所が違うこと。この記事で、その全体像と切り分け方を整理します。プロキシそのものの動きは リバースプロキシの可視化 もどうぞ。
Windowsのプロキシ設定は「3系統」ある
同じ「プロキシ設定」でも、Windowsには独立した3つの置き場所(スタック)があります。重要なのは、どのプロセスがどれを読むかが決まっていることと、1つを設定しても他には反映されないことです。
① WinINET(GUIで設定するプロキシ)
設定アプリの「ネットワークとインターネット → プロキシ」や、inetcpl.cpl の「接続 → LAN の設定」で行う設定がWinINETです。ブラウザ(Edge・Chrome)や多くのGUIアプリが参照します。特徴は次のとおり。
- ユーザーごとの設定(
HKCU\Software\Microsoft\Windows\CurrentVersion\Internet Settings)。 - ログオンセッションが前提。対話ユーザーがいないと読まれない。
- 自動検出(WPAD)・自動構成スクリプト(PAC)・手動プロキシすべてに対応。
つまり「人が使うブラウザ向け」の設定です。サービスやSYSTEMで動く処理には効きません。
② WinHTTP(サービス・システム向け)
WinHTTPは、サービスやSYSTEM/サービスアカウントで動く非対話の処理のためのHTTPスタックです。設定は netsh winhttp で行い、マシン全体(HKLM\…\Connections\WinHttpSettings)に保存されます。ログオンユーザーがいなくても機能します。
これを読む代表例が実務でハマりやすい処理です:Windows Update・証明書の失効確認(CRL/OCSP)・Microsoft Defenderの定義更新・WSUSクライアント・各種サービス。特に「証明書の失効確認」がプロキシを通れないと、HTTPS接続や署名検証が遅い・失敗するという分かりにくい障害になります。
注意点として、netsh winhttp で設定できるのは静的プロキシのみで、PAC(自動構成スクリプト)は扱えません。
③ 環境変数(モダンなCLI/ランタイム)
近年のクロスプラットフォーム系ツールは、WinINETでもWinHTTPでもなく環境変数を見ます。代表は HTTP_PROXY / HTTPS_PROXY / NO_PROXY(大文字小文字の両方が使われる)。.NET 5以降の既定のHttpClient・Git・curl・多くのコンテナやCLIツールがこれに該当します。「GUIもWinHTTPも入れたのに、このツールだけ繋がらない」ときの犯人はたいていこれです。
まとめ比較
| ① WinINET(GUI) | ② WinHTTP | ③ 環境変数 | |
|---|---|---|---|
| 設定方法 | 設定アプリ / inetcpl.cpl | netsh winhttp | setx / システム環境変数 |
| 保存場所 | HKCU(ユーザー別) | HKLM(マシン全体) | 環境変数 |
| 主な利用者 | ブラウザ・GUIアプリ | サービス・SYSTEM系 | .NET5+/Git/curl/コンテナ |
| ログオン | 必要 | 不要 | プロセス起動時に参照 |
| PAC対応 | あり | なし(静的のみ) | なし |
よくある障害と原因
| 症状 | 足りていない設定 |
|---|---|
| ブラウザは繋がるがWindows Updateが失敗(0x8024… 等) | ② WinHTTP |
| HTTPS接続や署名付きアプリの起動が遅い/失敗 | ② WinHTTP(証明書失効確認が通らない) |
| ライセンス認証・製品のアクティベーションが通らない | ② WinHTTP(サービスが担うため) |
| 特定のCLI・Git・dotnetツールだけ繋がらない | ③ 環境変数 |
| ログオン直後は不安定/SYSTEMタスクだけ失敗 | ① だけで② が未設定 |
設定コマンド早見
WinHTTP(②)——管理者コマンドプロンプトで:
:: 現在のWinHTTPプロキシを確認 netsh winhttp show proxy :: 明示的に設定(bypassにローカルを入れる) netsh winhttp set proxy proxy-server="http=proxy.example.com:8080;https=proxy.example.com:8080" bypass-list="*.example.local;<local>" :: 今のIE(WinINET)の静的設定をWinHTTPへコピー(PACは非対応・スナップショット) netsh winhttp import proxy source=ie :: 直結に戻す netsh winhttp reset proxy
環境変数(③)——システム全体に効かせるなら管理者で setx /M(新規プロセスから有効):
setx /M HTTP_PROXY "http://proxy.example.com:8080" setx /M HTTPS_PROXY "http://proxy.example.com:8080" setx /M NO_PROXY "localhost,127.0.0.1,.example.local"
WinINET(①)はGUIのほか、ユーザーのレジストリ(ProxyEnable / ProxyServer / AutoConfigURL / ProxyOverride)やグループポリシーで配布します。
PAC / WPAD の注意点
PAC(自動構成スクリプト)やWPAD(自動検出)はWinINETは扱えますが、WinHTTPはnetshでは扱えません(静的プロキシのみ)。そのため「社内はPACだけ」という環境だと、ブラウザは動くのにサービス系(WinHTTP)が経路を解決できず詰まります。この場合はWinHTTPに静的プロキシを明示設定して回避します。import proxy source=ie はPACをコピーしない点に注意(静的設定のスナップショットのみ)。
切り分けの手順
1. どのプロセスが失敗しているかを特定(ブラウザか/サービスか/特定CLIか)。
2. netsh winhttp show proxy でWinHTTP側が設定済みか確認。
3. サービス系が失敗なら② WinHTTP、特定CLIが失敗なら③ 環境変数を疑う。
4. PACのみ環境なら、WinHTTPに静的プロキシを明示。
5. VDI/非永続イメージでは、これらをマスターイメージやGPO/起動スクリプトに組み込む(ユーザー任せにしない)。
よくある質問
Q. なぜMicrosoftは3つも系統を分けているの?
A. 用途が違うためです。WinINETは「対話ユーザーのブラウジング」、WinHTTPは「ユーザー不在でも動くサービス/サーバー処理」向けに設計されました。環境変数はLinux由来の慣習で、クロスプラットフォームなツールがWindows・Linux共通で扱えるように採用しています。
Q. GUIの設定をサービスにも使わせる簡単な方法は?
A. まず netsh winhttp import proxy source=ie で現在のGUI(静的)設定をWinHTTPへコピーするのが手軽です。ただしPACは取り込まれず、以後の変更も自動同期しないので、変更のたびに再実行するか、静的プロキシを直接管理してください。
Q. グループポリシーの「プロキシ設定をコンピューター単位にする」は何を変える?
A. WinINETの設定をユーザー別(HKCU)からマシン単位(HKLM)へ切り替えるものです。これはあくまでWinINETの話で、WinHTTPとは別物です。混同しないよう注意してください。
まとめ
WindowsのプロキシはWinINET(GUI・ブラウザ向け)/WinHTTP(サービス・システム向け)/環境変数(モダンCLI向け)の3系統があり、プロセスごとに読む場所が違い、独立しているのが要点。プロキシ環境のサーバーやVDIでは「GUIだけ」では不十分で、WinHTTP(netsh winhttp)と環境変数もセットで設定するのが定石です。障害時は「どのプロセスが失敗しているか」から系統を切り分けましょう。
関連ページ: リバースプロキシの可視化 / ネットワークセキュリティの基礎(プロキシ) / 通信プロトコルとは / ディジタル証明書(失効・CRL/OCSP) / 記事一覧