5月28日 01:52

cURL 如何配置和使用代理服务器?

代理是 cURL 在企业网络和调试场景中的核心能力。掌握代理配置,才能在内网受限、抓包分析、隐私保护等场景下灵活使用 cURL。

代理的工作原理

cURL 通过代理服务器中转请求,流程是:cURL → 代理服务器 → 目标服务器。HTTP 代理对 HTTP 请求直接转发,对 HTTPS 请求使用 CONNECT 方法建立隧道;SOCKS 代理则在传输层转发流量,不关心上层协议。

理解这点很重要:HTTP 代理转发 HTTPS 时,代理看不到请求内容,因为它只建立了一条加密隧道。这也是为什么 HTTPS 代理和 SOCKS5h 更适合隐私敏感场景。

基本代理设置

bash
# HTTP 代理 curl -x http://proxy.example.com:8080 https://api.example.com curl --proxy http://proxy.example.com:8080 https://api.example.com # HTTPS 代理(代理连接本身加密) curl -x https://proxy.example.com:443 https://api.example.com # SOCKS5 代理 curl -x socks5://proxy.example.com:1080 https://api.example.com # SOCKS5h(DNS 由代理服务器解析,防止 DNS 泄露) curl -x socks5h://proxy.example.com:1080 https://api.example.com

-x--proxy 完全等价。socks5 和 socks5h 的区别在于 DNS 解析位置:前者由本地解析,后者由代理服务器解析。如果你在意隐私,始终优先用 socks5h。

代理类型怎么选

代理类型协议格式核心区别适用场景
HTTPhttp://明文连接代理,HTTPS 请求走 CONNECT 隧道企业缓存代理、简单转发
HTTPShttps://到代理的连接加密需要加密代理通信的场景
SOCKS4socks4://仅 TCP 转发,无认证旧系统兼容
SOCKS5socks5://支持 UDP 和多种认证方式通用代理
SOCKS5hsocks5h://DNS 由代理端解析隐私保护、防 DNS 泄露

选型建议:日常开发用 HTTP 代理即可;需要 UDP 或认证选 SOCKS5;隐私场景选 SOCKS5h。

代理认证

代理服务器通常需要身份验证。cURL 支持三种认证方式:

bash
# 方式一:在代理 URL 中嵌入凭据 curl -x http://user:password@proxy.example.com:8080 https://api.example.com # 方式二:用 -U 单独指定凭据 curl -x http://proxy.example.com:8080 -U user:password https://api.example.com # NTLM 认证(Windows 域环境常见) curl -x http://proxy.example.com:8080 --proxy-ntlm -U user:password https://api.example.com # Digest 认证 curl -x http://proxy.example.com:8080 --proxy-digest -U user:password https://api.example.com

注意:-U 方式下密码会出现在进程列表中。在共享服务器上,优先用 ~/.curlrc 或环境变量 CURL_PROXY_USER 来避免密码暴露。

环境变量与持久化配置

每次手动指定代理很繁琐,cURL 会自动读取以下环境变量:

bash
# 设置代理环境变量 export http_proxy="http://proxy.example.com:8080" export https_proxy="http://proxy.example.com:8080" export no_proxy="localhost,127.0.0.1,.example.com" # 设置后直接使用,无需 -x 参数 curl https://api.example.com # 临时忽略环境变量 curl --noproxy "*" https://api.example.com

小写变量名(http_proxy)是通用约定,大写(HTTP_PROXY)部分工具也会读取。no_proxy 指定不走代理的域名,支持通配符。

更持久的方案是写入配置文件:

bash
# ~/.curlrc proxy = "http://proxy.example.com:8080" proxy-user = "username:password" noproxy = "localhost,127.0.0.1"

写入后所有 cURL 请求默认走代理。需要临时跳过时用 curl -q(忽略 .curlrc)或 --noproxy

代理绕过

并非所有请求都需要走代理。内网地址、本地服务应该直连:

bash
# 绕过指定域名 curl --noproxy "localhost,127.0.0.1,internal.example.com" \ -x http://proxy.example.com:8080 \ https://api.example.com # 绕过所有代理(直连) curl --noproxy "*" https://api.example.com

--noproxy 的值支持逗号分隔的域名列表,也支持 .example.com 这样的域名后缀匹配。

代理调试技巧

代理不工作时,按以下步骤排查:

bash
# 第一步:查看完整的连接过程 curl -v -x http://proxy.example.com:8080 https://api.example.com 2>&1 | grep -i proxy # 第二步:测试代理本身是否可达 curl -v -x http://proxy.example.com:8080 http://www.google.com # 第三步:通过代理查看出口 IP(确认代理生效) curl -x http://proxy.example.com:8080 https://api.ipify.org

如果 -v 输出中看到 Connected to proxy.example.com 说明到代理的连接成功;如果卡在 Proxy auth required 说明认证问题;如果完全没有 proxy 相关输出,检查环境变量是否被正确加载。

高级配置

代理隧道:HTTP 代理默认用 CONNECT 方法为 HTTPS 建立隧道。某些旧代理不支持 CONNECT,可以显式指定:

bash
curl -x http://proxy.example.com:8080 --proxy-tunnel https://api.example.com

自定义代理请求头:某些代理会校验 User-Agent,可以通过 --proxy-header 添加:

bash
curl --proxy-header "User-Agent: MyApp/1.0" \ -x http://proxy.example.com:8080 \ https://api.example.com

代理 TLS 配置:HTTPS 代理可能要求特定的 TLS 版本或证书:

bash
# 指定 TLS 版本 curl -x https://proxy.example.com:443 --proxy-tlsv1.2 https://api.example.com # 指定代理 CA 证书 curl -x https://proxy.example.com:443 --proxy-cacert /path/to/proxy-ca.crt https://api.example.com # 跳过代理证书验证(仅调试用) curl -x https://proxy.example.com:443 --proxy-insecure https://api.example.com

实战场景

场景一:企业内网访问外部 API

企业网络通常有统一出口代理,需要域账号认证:

bash
curl -x http://corporate-proxy.company.com:8080 \ --proxy-ntlm \ -U "COMPANY\\username:password" \ --noproxy "localhost,127.0.0.1,*.internal.company.com" \ https://api.github.com/user

注意 Windows 域用户名中的反斜杠需要转义为 \\--noproxy 确保内网地址不走代理。

场景二:用 SSH 隧道做临时代理

没有代理服务器时,可以借助远程机器创建 SOCKS 代理:

bash
# 先在本地建立 SSH 隧道(后台运行) ssh -D 1080 -f -C -q -N user@remote-server # 然后通过隧道访问 curl -x socks5h://localhost:1080 https://api.example.com

-D 1080 在本地 1080 端口开 SOCKS 代理,-f -C -q -N 让 SSH 在后台压缩静默运行。用完后 kill 对应 SSH 进程即可。

场景三:配合抓包工具调试

Charles 或 Fiddler 本质上是 HTTP 代理,默认监听 8888 端口:

bash
curl -x http://localhost:8888 -k https://api.example.com

-k 跳过证书验证,因为抓包工具使用自签证书。调试 HTTPS 请求时这一步必不可少。

常见问题

代理连接超时

默认超时可能太短,特别是跨地域代理。增加超时:

bash
curl -x http://proxy.example.com:8080 --connect-timeout 30 --max-time 60 https://api.example.com

HTTPS 通过 HTTP 代理失败

正常情况下 HTTP 代理会自动用 CONNECT 方法处理 HTTPS。如果失败,检查代理是否禁止了 CONNECT,或者显式启用隧道:

bash
curl -x http://proxy.example.com:8080 --proxy-tunnel https://api.example.com

DNS 泄露

使用 socks5 代理时,DNS 请求仍在本地发出,可能暴露访问意图。换成 socks5h 让代理端解析 DNS:

bash
curl -x socks5h://proxy.example.com:1080 https://api.example.com

代理认证失败

先确认认证类型。大多数代理用 Basic 认证,企业环境可能用 NTLM 或 Digest。用 -v 查看代理返回的 Proxy-Authenticate 头,确定认证方式后再加对应参数。

标签:cURL