在 cURL 中使用代理,就是用 -x 或 --proxy 命令行选项指定代理服务器的地址和端口,从而让 cURL 请求经由中间服务器转发。
本文详细介绍 cURL 中与代理服务交互的各种方法和命令行选项,涵盖基础的 HTTP/HTTPS 代理、需身份验证的代理、SOCKS 代理,以及通过环境变量进行配置。
基础代理配置
让 cURL 使用代理最常见的方法,是使用 -x 或 --proxy 选项,后面跟上代理服务器的地址和端口。
HTTP/HTTPS 代理
要让 HTTP 或 HTTPS 请求经由 HTTP/HTTPS 代理转发,请指定代理的地址和端口。
语法:
curl -x [protocol://][user:password@]proxyhost[:port] [URL]
示例:
-
对 HTTP 目标使用 HTTP 代理:
bash curl -x http://your.proxy.server:8080 http://example.com
该命令让 cURL 使用 HTTP 代理协议,通过your.proxy.server的8080端口发送对http://example.com的请求。 -
对 HTTPS 目标使用 HTTP 代理:
bash curl -x http://your.proxy.server:8080 https://secure.example.com
当通过 HTTP 代理访问 HTTPS 目标时,cURL 通常使用CONNECT方法经代理建立到目标服务器的隧道。随后 SSL/TLS 握手直接在 cURL 与secure.example.com之间完成,HTTP 代理不参与加密。 -
对 HTTP 目标使用 HTTPS 代理:
bash curl -x https://your.secure.proxy.server:8443 http://example.com
这会让请求经由自身使用 HTTPS 的代理转发。cURL 与your.secure.proxy.server之间的连接是加密的。
需身份验证的代理
许多代理服务需要身份验证。cURL 支持多种代理验证方式,主要是 Basic、NTLM 和 Digest。
Basic 验证
对于需要用户名和密码的代理,使用 --proxy-user 选项,或把凭据直接嵌入代理 URL。
语法:
curl -x [protocol://]proxyhost[:port] --proxy-user "username:password" [URL]
curl -x [protocol://]username:password@proxyhost[:port] [URL]
示例:
-
使用
--proxy-user:
bash curl -x http://your.proxy.server:8080 --proxy-user "proxyuser:proxypass" http://example.com -
把凭据嵌入 URL:
bash curl -x http://proxyuser:[email protected]:8080 http://example.com
如果用户名或密码中包含特殊字符,必须进行 URL 编码。例如密码p@ssword应写成p%40ssword。
其他验证方式
Basic 验证最为常见,但 cURL 也为特定环境支持其他方式。
--proxy-ntlm:为代理启用 NTLM 验证。--proxy-digest:为代理启用 Digest 验证。
示例(NTLM):
curl -x http://your.proxy.server:8080 --proxy-ntlm --proxy-user "DOMAIN\proxyuser:proxypass" http://example.com
SOCKS 代理
SOCKS(Socket Secure)代理工作在比 HTTP 代理更低的层级,可处理多种网络协议。cURL 支持 SOCKS4、SOCKS4a 和 SOCKS5。
SOCKS5 代理
SOCKS5 是最通用的 SOCKS 协议,支持 IPv4、IPv6、UDP 和身份验证。
语法:
curl --socks5 [user:password@]proxyhost[:port] [URL]
示例:
-
基础 SOCKS5 代理:
bash curl --socks5 your.socks5.server:1080 http://example.com
默认情况下,cURL 会先在本地解析主机名example.com,再把 IP 地址发送给 SOCKS5 代理。 -
由远端解析 DNS 的 SOCKS5 代理:
bash curl --socks5-hostname your.socks5.server:1080 http://example.com
--socks5-hostname选项让 cURL 把主机名example.com发送给 SOCKS5 代理,由代理执行 DNS 解析。在本地 DNS 解析可能暴露您所在位置的场景中,这对匿名性和绕过地理限制至关重要。 -
带身份验证的 SOCKS5 代理:
bash curl --socks5-hostname socksuser:[email protected]:1080 http://example.com
SOCKS4/SOCKS4a 代理
SOCKS4 是较旧的协议,主要面向 IPv4,且不支持身份验证。SOCKS4a 扩展了 SOCKS4,允许由代理解析主机名。
语法:
curl --socks4 proxyhost[:port] [URL]
curl --socks4a proxyhost[:port] [URL]
示例(SOCKS4a):
curl --socks4a your.socks4.server:1080 http://example.com
与 --socks5-hostname 类似,--socks4a 可确保由代理解析目标主机名。
通过代理访问 HTTPS 目标与 SSL/TLS
当 cURL 通过 HTTP 代理发起 HTTPS 请求时,它会先向代理发送 CONNECT 请求。代理随后建立到目标 HTTPS 服务器的 TCP 隧道。cURL 通过该隧道直接与目标服务器完成 SSL/TLS 握手。
SSL 证书校验
默认情况下,cURL 会校验目标服务器的 SSL 证书。如果证书无效、已过期或为自签名,cURL 将中止连接。
-
--insecure或-k: 关闭 SSL 证书校验。请谨慎使用,主要用于测试或使用自签名证书的已知可信环境。
bash curl -x http://your.proxy.server:8080 https://self-signed.example.com -k -
--cacert [file]: 指定用于校验的自定义 CA 证书包。
bash curl -x http://your.proxy.server:8080 https://secure.example.com --cacert /path/to/custom_ca.pem
用于代理配置的环境变量
cURL 也可以从环境变量中读取代理设置。这适合系统级或会话级的代理配置,无需为每条命令都加上 -x 选项。
常用环境变量
http_proxy:用于 HTTP 请求的代理。https_proxy:用于 HTTPS 请求的代理。all_proxy:当http_proxy或https_proxy未设置时,作为所有协议的兜底代理。no_proxy:以逗号分隔的主机名、域名或 IP 地址列表,这些目标将绕过代理。
语法:
export http_proxy="http://your.proxy.server:8080"
export https_proxy="http://your.proxy.server:8080" # 注意:访问 HTTPS 目标时通常也使用 HTTP 代理
export no_proxy="localhost,127.0.0.1,.localdomain"
示例:
-
设置 HTTP 代理:
bash export http_proxy="http://proxyuser:[email protected]:8080" curl http://example.com -
设置 HTTPS 代理(经由 HTTP 代理):
bash export https_proxy="http://your.proxy.server:8080" curl https://secure.example.com -
让特定主机绕过代理:
bash export http_proxy="http://your.proxy.server:8080" export no_proxy="internal.example.com" curl http://internal.example.com # 该请求将绕过代理 curl http://external.example.com # 该请求将使用代理
优先级
命令行选项的优先级高于环境变量。如果指定了 -x,它会覆盖所有 http_proxy、https_proxy 或 all_proxy 环境变量。
代理连接的故障排查
在遇到 cURL 与代理相关的问题时,有若干选项可辅助诊断。
-
--verbose或-v: 输出关于请求和响应的详细信息,包括代理连接尝试、报文头和 SSL/TLS 协商过程。这通常是调试的第一步。
bash curl -v -x http://your.proxy.server:8080 http://example.com -
--trace [file]: 将所有收发数据(含报文头和正文)的完整跟踪写入指定文件。
bash curl --trace debug.log -x http://your.proxy.server:8080 http://example.com -
代理服务器日志: 检查代理服务器日志中与您的 cURL 请求相关的连接尝试、验证失败或错误信息。
-
网络连通性: 用
ping、telnet或netcat等工具确认运行 cURL 的机器能通过指定端口访问代理服务器。
bash telnet your.proxy.server 8080
telnet连接成功说明基本的网络可达性没有问题。
主要代理选项对比
| cURL 选项 | 说明 | 协议 | 身份验证 | DNS 解析 |
|---|---|---|---|---|
-x, --proxy |
通用代理设置(HTTP/HTTPS 代理) | HTTP、HTTPS | 支持 | 本地 |
--proxy-user |
指定代理验证所用的用户名和密码 | HTTP、HTTPS | 支持 | 不适用 |
--socks5 |
SOCKS5 代理,默认本地 DNS 解析 | 全部 | 支持 | 本地 |
--socks5-hostname |
SOCKS5 代理,远端 DNS 解析 | 全部 | 支持 | 远端(代理) |
--socks4 |
SOCKS4 代理,本地 DNS 解析 | 全部 | 不支持 | 本地 |
--socks4a |
SOCKS4a 代理,远端 DNS 解析 | 全部 | 不支持 | 远端(代理) |
http_proxy(env) |
HTTP 代理的环境变量 | HTTP | 支持 | 本地 |
https_proxy(env) |
HTTPS 代理的环境变量(通常是用于隧道的 HTTP 代理) | HTTPS | 支持 | 本地 |
all_proxy(env) |
其他变量未设置时用于所有协议的环境变量 | 全部 | 支持 | 本地 |
no_proxy(env) |
用于指定绕过代理的主机的环境变量 | 不适用 | 不适用 | 不适用 |
