Windows 上统一管理代理环境变量(HTTP_PROXY / HTTPS_PROXY / NO_PROXY)

目标:在 Windows PowerShell 5.1、PowerShell 7、Git Bash 中,按需自动设置代理,并避免 VPN/内网地址被误代理


1. 背景与坑位总结

1.1 环境变量代理是什么?

很多命令行工具会读取以下环境变量来决定是否走 HTTP 代理:

  • HTTP_PROXY / HTTPS_PROXY(大写)
  • http_proxy / https_proxy(小写)
  • NO_PROXY / no_proxy:指定哪些地址 不走代理(非常关键,防止 VPN 内网被代理坑死)

1.2 大小写有什么区别?哪个“正确”?

没有“唯一正确”,只有“兼容性”:

  • Linux/macOS 生态传统更常用小写 http_proxy
  • Windows/企业工具更常见大写 HTTP_PROXY
  • 很多程序两者都支持,但并非全部

✅ 最稳做法:
- 在 Bash(Git Bash/WSL):大写 + 小写都设置
- 在 PowerShell/Windows:大写优先,必要时也补小写

1.3 为什么一定要配 NO_PROXY?

否则会出现经典现象:

  • VPN 内网能 ping
  • 但浏览器/HTTPS 不通、curl 握手失败、jumpserver 打不开

典型需要 bypass 的范围:
- localhost, 127.0.0.1
- 192.168.0.0/16
- 10.0.0.0/8
- 172.16.0.0/12

注意:有些程序不支持 CIDR(例如 192.168.0.0/16),这时建议写成 192.168. 或直接列具体 IP/域名


2. 不要再用“系统级(Machine)HTTP_PROXY/HTTPS_PROXY”

你遇到的问题本质就是:系统级代理环境变量污染了所有程序(包含浏览器/工具链)。

2.1 系统级环境变量存在哪里?

注册表位置:

  • HKLM\SYSTEM\CurrentControlSet\Control\Session Manager\Environment

2.2 风险

  • 所有程序都继承
  • VPN 内网、企业网段很容易被误代理
  • 排查非常耗时(症状看起来像 VPN/服务器问题)

✅ 建议:
- 不要在 Machine 级设置 HTTP_PROXY/HTTPS_PROXY
- 用“Shell Profile”按需注入(下面会讲)


3. PowerShell 5.1 自动代理(推荐做法)

3.1 PS5 的 profile 路径

在 PowerShell 里查看:

$PROFILE

如果文件不存在,创建:

New-Item -ItemType File -Path $PROFILE -Force
notepad $PROFILE

3.2 自动检测本地代理端口(8123)并设置环境变量

将以下内容写入 $PROFILE

# ---- Auto proxy (only when local proxy port is listening) ----
$proxyPort = 8123
$proxyUrl  = "http://127.0.0.1:$proxyPort"

function Test-ListeningPort([int]$Port) {
    try {
        # Don't pin LocalAddress; 0.0.0.0 / :: should count as listening too
        return (Get-NetTCPConnection -State Listen -LocalPort $Port -ErrorAction Stop | Measure-Object).Count -gt 0
    } catch {
        # Fallback for older/limited environments
        return [bool](netstat -ano | Select-String -Pattern "LISTENING" | Select-String -Pattern ":\b$Port\b")
    }
}

if (Test-ListeningPort $proxyPort) {
    # Upper + lower case for compatibility
    $env:HTTP_PROXY  = $proxyUrl
    $env:HTTPS_PROXY = $proxyUrl
    $env:http_proxy  = $proxyUrl
    $env:https_proxy = $proxyUrl

    # Bypass internal networks (VERY IMPORTANT for VPN)
    $noProxy = "localhost,127.0.0.1,192.168.0.0/16,10.0.0.0/8,172.16.0.0/12"
    $env:NO_PROXY = $noProxy
    $env:no_proxy = $noProxy

    Write-Host "Proxy enabled: $proxyUrl"
} else {
    Remove-Item Env:\HTTP_PROXY,Env:\HTTPS_PROXY,Env:\http_proxy,Env:\https_proxy -ErrorAction SilentlyContinue
    Remove-Item Env:\NO_PROXY,Env:\no_proxy -ErrorAction SilentlyContinue

    Write-Host "Remove proxy settings."
}
# ---- End ----

3.3 验证

重开一个 PowerShell,然后执行:

gci env:*proxy*

预期:

  • 8123 在监听 → 你会看到 HTTP_PROXY/HTTPS_PROXY/NO_PROXY...
  • 8123 不监听 → 变量为空

4. PowerShell 7 自动代理(PS7 / pwsh)

PowerShell 7 的 profile 文件与 PS5 不同

4.1 PS7 profile 路径

pwsh 里执行:

$PROFILE

常见是:

  • C:\Users\<你>\Documents\PowerShell\Microsoft.PowerShell_profile.ps1

4.2 配置方式

第 3.2 节同一段代码粘到 PS7 的 $PROFILE 里即可。

PS5/PS7 可以各自配置;如果你两边都用,建议两边都放一份。


5. Git Bash(.bashrc / .bash_profile)

Git Bash 的启动脚本通常是:

  • ~/.bashrc(交互 shell 常用)
  • ~/.bash_profile(登录 shell,可能会去 source .bashrc

5.1 自动检测 8123 并设置代理

推荐写到 ~/.bashrc

# ---- Auto proxy (only when local proxy port is listening) ----
if netstat -an 2>/dev/null | grep -qE '[:.]8123[[:space:]].*LISTEN'; then
  export http_proxy="http://127.0.0.1:8123"
  export https_proxy="http://127.0.0.1:8123"
  export HTTP_PROXY="$http_proxy"
  export HTTPS_PROXY="$https_proxy"

  # Bypass internal networks / VPN ranges
  export no_proxy="localhost,127.0.0.1,192.168.0.0/16,10.0.0.0/8,172.16.0.0/12"
  export NO_PROXY="$no_proxy"
else
  unset http_proxy https_proxy HTTP_PROXY HTTPS_PROXY no_proxy NO_PROXY
fi
# ---- End ----

5.2 验证

在 Git Bash 里:

env | grep -i proxy

6. 推荐的“最佳实践组合”

✅ 最稳(不坑 VPN / 内网)的组合是:

  1. 不要设置系统级(Machine)HTTP_PROXY/HTTPS_PROXY
  2. 在 PowerShell Profile 做“端口监听检测 → 按需注入”
  3. 在 Git Bash .bashrc 做同样逻辑
  4. 永远配置 NO_PROXY/no_proxy(至少包含内网段 + 关键内网 IP)

7. 常用排错命令备忘

7.1 查看当前进程环境变量

PowerShell:

gci env:*proxy*

Git Bash:

env | grep -i proxy

7.2 谁在监听 8123?

PowerShell:

netstat -aon | findstr :8123
Get-Process -Id <PID> | Select Name,Id,Path

7.3 验证 VPN 内网 HTTPS 是否被代理影响(curl)

PowerShell:

curl.exe -vk https://192.168.181.101/

如果你看到类似:

  • Uses proxy env variable ... 127.0.0.1:8123 → 说明走了代理
  • 直连成功返回 HTTP/1.1 200 OK → 内网访问正常

8. 小结

  • HTTP_PROXY vs http_proxy:为兼容性建议两种都设置
  • NO_PROXY 是关键:避免内网/VPN 被误代理
  • 不要用 Machine 级代理环境变量
  • 用 PowerShell Profile / .bashrc 做“端口检测 → 自动注入”是最干净的方案

评论

还没有人评论,抢个沙发吧...

Viagle Blog

欢迎来到我的个人博客网站