こんにちは、やまぱんです。
昔から「Windows のプロキシってどこに何があるか分かりにくいよね…」と思っていたので、現場でハマりがちなところを備忘録としてまとめておきます。社内プロキシ環境で開発ツールが急に動かなくなった、とか、Windows Update だけ通らない、みたいなときに引いてください。
TL;DR
Windows のプロキシは「1 箇所にまとまっていない」のがハマりどころです。最低限おさえると次の系統になります。
- WinINet 系(ブラウザ・OS 設定アプリ): ユーザーごと。設定アプリ/IE のインターネットオプション/レジストリで設定。
- WinHTTP 系(Windows Update やサービス): マシン全体。
netsh winhttpで設定。 - 環境変数系(CLI・開発ツール):
HTTP_PROXY/HTTPS_PROXY/NO_PROXY。シェル単位で効く。 - アプリ独自設定: git / npm / pip / curl / Docker など、ツールごとに別途。
- WPAD / PAC: 上記いずれでも参照できる「自動構成」。
- WSL2: Windows 側の設定は そのままでは入ってこない(Windows 11 22H2 以降の
autoProxyで改善あり)。
「設定したのに反映されない」は、たいてい どの系統に書いたかが間違っている のが原因です。
Windows のプロキシ系統を整理する
まず登場人物を整理しておきます。
WinHTTP プロキシ
主に Windows Update やバックグラウンドサービス が使う HTTP スタックです。netsh winhttp で設定し、対象はマシン全体(コンピューター単位)。
WinINet プロキシ
ブラウザ(旧 IE / Edge レガシー)や Windows の「プロキシ設定」アプリ が使う HTTP スタックです。アカウント単位で持つのが特徴で、レジストリ上は次の場所に値があります。
- ユーザーアカウント:
HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Internet Settings - システムアカウント:
HKEY_USERS\S-1-5-18\Software\Microsoft\Windows\CurrentVersion\Internet Settings - サービスアカウント: そのサービスの SID 配下(アプリ次第)
「設定アプリでプロキシを入れたのにサービスが拾わない」のは、設定したのが カレントユーザーの WinINet で、サービスは WinHTTP かサービスアカウントの WinINet を見ているからです。
WinINet ↔ WinHTTP の関係は公式の Setting WinINet Proxy Configurations in WinHTTP | Microsoft Learn が詳しいです。
環境変数 (HTTP_PROXY 等)
curl / git / pip / npm / PowerShell 7 / .NET HttpClient など、Unix 文化由来のツールは基本的に環境変数を見にいきます。Windows GUI のプロキシ設定とは別世界です。
アプリケーション独自のプロキシ
git, npm, pip, Docker など、ツールが固有の設定ファイルやコマンドでプロキシを持つパターンです。後ろのセクションでまとめます。
システム全体(設定アプリ)
Windows 11 では「設定 → ネットワークとインターネット → プロキシ」から設定します。実体は カレントユーザーの WinINet に書かれます。

ここで設定しても、Windows Update やシステムサービスには反映されません。それは次の WinHTTP 側の仕事です。
カレントユーザーの WinINet を確認する
PowerShell でレジストリから直接読むと確実です。
$ie = Get-Item -Path 'Registry::HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Internet Settings'
Write-Host "ProxyEnable :" $ie.GetValue('ProxyEnable')
Write-Host "ProxyServer :" $ie.GetValue('ProxyServer')
Write-Host "ProxyOverride:" $ie.GetValue('ProxyOverride')
ProxyEnable: 0 なら無効、1 なら有効です。

システムアカウント(SYSTEM)の WinINet を確認する
$sys = Get-Item -Path 'Registry::HKEY_USERS\S-1-5-18\Software\Microsoft\Windows\CurrentVersion\Internet Settings'
Write-Host "ProxyEnable :" $sys.GetValue('ProxyEnable')
Write-Host "ProxyServer :" $sys.GetValue('ProxyServer')
Write-Host "ProxyOverride:" $sys.GetValue('ProxyOverride')

経験浅いときに「設定アプリからプロキシ入れたのに直らない!」となるやつ、だいたいこれです。設定したのはカレントユーザーで、見にいってるのは SYSTEM、というすれ違いです。
プロセスがどのアカウントで動いているか確認する
サービスやアプリがどのアカウントで動いているかは、タスクマネージャーの「詳細」タブで確認できます。

CLI で見たいときは次のコマンドです。
tasklist /v

ユーザー名 N/A のものはたいてい SYSTEM で動いています。

レガシー(IE / インターネットオプション)
「インターネットオプション」(inetcpl.cpl)の 接続 → LAN の設定 から開くやつです。これも実体はカレントユーザーの WinINet で、設定アプリと同じ場所を触ります。
古いツールはここしか見ないことがあるので、互換目的でいまだに使われます。
netsh winhttp(システムサービス用)
Windows Update や、ユーザーセッションを持たないサービスにプロキシを通したいときは netsh winhttp を使います。設定はマシン全体に効きます。
現在の設定を確認
netsh winhttp show proxy

プロキシをセットする
netsh winhttp set proxy proxy-server="proxy.example.com:8080" bypass-list="*.example.com;<local>"
IE 設定を WinHTTP にコピーする(便利技)
カレントユーザーの IE / 設定アプリのプロキシをそのまま WinHTTP に流し込めます。社内環境で「とりあえず GUI で動いている設定をサービスにも入れたい」ときに便利です。
netsh winhttp import proxy source=ie
import proxyは IE 設定からのインポート専用で、ほかのブラウザからは取れません。詳細は netsh winhttp | Microsoft Learn を参照。
リセットする
netsh winhttp reset proxy
「いったん直接接続に戻したい」「設定がおかしくなった」ときの最初の一手として覚えておくと良いです。
環境変数(HTTP_PROXY / HTTPS_PROXY / NO_PROXY)
CLI 系・開発ツール系は基本こちらです。Windows の GUI 設定とは別物 なので、明示的に入れてあげる必要があります。
一時的に設定(このシェルだけ)
$env:HTTP_PROXY = "http://proxy.example.com:8080"
$env:HTTPS_PROXY = "http://proxy.example.com:8080"
$env:NO_PROXY = "localhost,127.0.0.1,.example.com"
ユーザー全体に永続化
[Environment]::SetEnvironmentVariable("HTTP_PROXY", "http://proxy.example.com:8080", "User")
[Environment]::SetEnvironmentVariable("HTTPS_PROXY", "http://proxy.example.com:8080", "User")
[Environment]::SetEnvironmentVariable("NO_PROXY", "localhost,127.0.0.1,.example.com", "User")
PowerShell 7 や Az PowerShell も Linux / macOS / Windows ともにこの環境変数で動きます(Az PowerShell をプロキシ経由で使う | Microsoft Learn)。
小ネタ: 環境変数名はツールによって 大文字版だけ拾うもの/小文字版を優先するものがあります。両方セットしておくのが無難です。
開発ツール別のプロキシ設定
ここが今回いちばん書きたかったところです。CLI ツールは独自に設定を持っていることが多く、環境変数だけだとカバーしきれません。
git
git config --global http.proxy http://proxy.example.com:8080
git config --global https.proxy http://proxy.example.com:8080
# 特定ホストだけ別設定にしたい場合
git config --global http."https://github.com/".proxy http://proxy.example.com:8080
# 解除
git config --global --unset http.proxy
git config --global --unset https.proxy
npm
npm config set proxy http://proxy.example.com:8080
npm config set https-proxy http://proxy.example.com:8080
npm config set noproxy "localhost,127.0.0.1,.example.com"
# 確認
npm config get proxy
pip
pip config set global.proxy http://proxy.example.com:8080
# あるいは 1 回だけ
pip install <pkg> --proxy http://proxy.example.com:8080
curl
curl は環境変数を素直に見ますが、明示したいときは次のとおりです。
curl.exe -x http://proxy.example.com:8080 https://example.com
%USERPROFILE%\.curlrc に proxy = http://proxy.example.com:8080 と書いて永続化もできます。
Docker Desktop
設定 → Resources → Proxies で GUI 設定が用意されています。コンテナ内で HTTP_PROXY 等を自動付与してくれます。
WPAD / PAC(自動構成)
社内環境では、プロキシを PAC ファイル で配ることがよくあります。「指定の URL の JavaScript を読んで、URL ごとにプロキシを判定する」仕組みです。
- WPAD (Web Proxy Auto-Discovery): DHCP / DNS から
wpad.<ドメイン>を探して PAC ファイルを自動取得する仕組み。 - PAC URL を明示: 設定アプリの「セットアップスクリプト」や IE の「自動構成スクリプト」に
http://proxy.example.com/proxy.pacのように直接書く。
WinHTTP 側でも PAC を扱えますが、netsh winhttp set proxy の直書きでは入りません。netsh winhttp set advproxy で AutoconfigUrl や AutoDetect を含む JSON を渡します。
netsh winhttp set advproxy setting-scope=machine settings="{\"Proxy\":\"\",\"ProxyBypass\":\"<local>\",\"AutoconfigUrl\":\"http://proxy.example.com/proxy.pac\",\"AutoDetect\":true}"
WSL2 のプロキシ
WSL2 は 別 OS(Linux)で動いている VM なので、Windows の GUI でプロキシを入れても そのままでは伝搬しません。これに気づかず数時間溶かしがちなので注意してください。
Windows 11 22H2 以降: autoProxy を活用する
Windows 11 22H2 以降の WSL では .wslconfig の wsl2.autoProxy がデフォルトで true になっており、Windows 側の HTTP プロキシ情報を WSL に流し込んでくれます。%UserProfile%\.wslconfig に明示すると次のようになります。
[wsl2]
autoProxy=true
dnsTunneling=true
設定変更後は wsl --shutdown で WSL を一度落としてから再起動します。
参考: Advanced settings configuration in WSL | Microsoft Learn
古い環境 / 手動で入れたい場合
WSL 内のシェルで環境変数を仕込みます。~/.bashrc あたりに書いておくと毎回効きます。
export HTTP_PROXY=http://<Windows ホスト IP>:8080
export HTTPS_PROXY=http://<Windows ホスト IP>:8080
export NO_PROXY=localhost,127.0.0.1
Windows ホスト側の IP は、WSL2 内から /etc/resolv.conf の nameserver か、ip route show default で取れます。Docker Desktop が動いている環境なら host.docker.internal を使うのが楽です。
apt のような root 権限で動くツールには別途設定が必要なケースがあります(/etc/apt/apt.conf.d/95proxies など)。
参考リンク
- netsh winhttp | Microsoft Learn
- WinHTTP の netsh.exe コマンド | Microsoft Learn
- Setting WinINet Proxy Configurations in WinHTTP | Microsoft Learn
- Advanced settings configuration in WSL (.wslconfig) | Microsoft Learn
- Use the Az PowerShell module behind a proxy | Microsoft Learn
まとめ
Windows のプロキシは 「設定アプリ」「IE」「netsh winhttp」「環境変数」「アプリ独自」「PAC / WPAD」「WSL2」と層が分かれていて、それぞれが見ている場所が違う のがポイントでした。
うまく動かないときは、「いま設定しようとしている層はどれ? 動かないツールが見ているのはどの層?」を切り分けると、だいぶ早く片付くと思います〜!