curl 怎么使用代理?-x、SOCKS5 和环境变量实测

用 curl 通过代理发送请求:-x 指定代理、-U 填账号密码、HTTP/HTTPS/SOCKS5/socks5h 怎么选、环境变量怎么设,以及常见报错的含义。文中命令全部实测。

教程发布于 2026年10月25日约 3 分钟

本页目录

结论先说: 让 curl 走代理,加上 -x 指定代理地址、-U 填账号密码即可:curl -x http://HOST:PORT -U "USERNAME:PASSWORD" https://example.com。地址开头的协议决定用哪种代理:http:// 或 https:// 是 HTTP 代理,socks5h:// 是由代理负责解析域名的 SOCKS5 代理。curl 也能从环境变量和配置文件读取代理,加 -v 可以看到 curl 和代理之间每一步发生了什么。

一个代理地址拆成五个部分:协议 socks5h、用户名、密码、主机、端口,分别用 ://、冒号、@ 和冒号隔开。协议决定代理类型:http:// 是 HTTP 代理,HTTPS 网站通过 CONNECT 隧道访问;https:// 是通过 TLS 连接的 HTTP 代理,比如 NanoIP 网关;socks5:// 由 curl 自己解析网站 IP;socks5h:// 由代理解析
开头的协议决定代理类型,后面是账号密码和代理地址。

基本命令

bash
curl -x http://HOST:PORT -U "USERNAME:PASSWORD" https://example.com
  • -x(完整写法 --proxy)是代理地址。
  • -U(完整写法 --proxy-user)是代理的账号密码。密码里有 shell 会特殊处理的字符时,记得加引号。

想知道网站看到的是哪个 IP,就请求 IP 查询服务。https://ipinfo.io/ip 只返回出口 IP,https://ipinfo.io/json 还会返回国家、城市和网络:

bash
curl -x http://HOST:PORT -U "USERNAME:PASSWORD" https://ipinfo.io/json

账号写在地址里,还是用 -U

账号密码也可以写进代理地址:-x http://USERNAME:PASSWORD@HOST:PORT。但只要密码里有 @、:、/ 或 #,地址就会被拆错,需要转义(@ 写成 %40,: 写成 %3A)。我们用密码 p@ss:word 测试:写在地址里要写成 p%40ss%3Aword,用 -U 则原样填写即可:

bash
curl -x "http://user:p%40ss%3Aword@127.0.0.1:28181" https://example.com
curl -x http://127.0.0.1:28181 -U "user:p@ss:word" https://example.com

用 -U 传账号密码就不用考虑转义,所以本文后面都用这种写法。

HTTP、HTTPS 和 SOCKS5 代理

协议代理类型curl 怎么做
http://HTTP 代理访问 HTTPS 网站时发 CONNECT 建隧道,访问 http:// 网站时把整个请求发给代理
https://通过 TLS 连接的 HTTP 代理同上,但先加密到代理的连接
socks5://SOCKS5先自己解析网站地址,再让代理连接这个 IP
socks5h://SOCKS5把域名发给代理,由代理解析

--socks5 和 --socks5-hostname 参数的作用,分别等同于 socks5:// 和 socks5h://。协议和代理实际支持的不一致时,报错往往看不出原因:我们测试时,用 http:// 连 SOCKS5 端口报 Recv failure: Connection reset by peer;用 socks5h:// 或 https:// 连普通 HTTP 代理,则一直卡到 curl 超时。

两种协议各自适合什么,见 SOCKS5和HTTP代理的区别。

socks5 还是 socks5h

用 socks5:// 时,curl 自己解析 example.com,把 IP 发给代理,本地 DNS 服务器能看到查询,返回的是适合你所在地的地址;用 socks5h:// 时,curl 把域名 example.com 发给 SOCKS5 代理,由代理在自己的网络、所在的国家里解析
socks5h 里的 h,把 DNS 解析从你的电脑交给了代理。

没有特别理由的话,用 socks5h://。我们的测试代理记录了同一个请求在两种写法下收到的内容:

text
socks5://   → the proxy received an IP address (curl had looked it up locally)
socks5h://  → the proxy received "example.com" (the proxy looked it up)

本地解析由你自己的 DNS 服务器回答,返回的可能是为你所在地优化的服务器,而不是代理所在地的,同时还会让本地 DNS 服务器看到你访问了哪些网站。用 socks5h://,解析就发生在代理那一端。

不用 -x 时怎么设置代理

环境变量

没有 -x 时,curl 会读取这些环境变量:

变量用于实测说明
http_proxyhttp:// 网址只认小写:大写的 HTTP_PROXY 被 curl 忽略,直接连接了
https_proxy 或 HTTPS_PROXYhttps:// 网址大小写都可以
ALL_PROXY没有更具体变量的所有网址配合 socks5h:// 代理可以使用
NO_PROXY不走代理的地址逗号分隔,* 表示全部
bash
export https_proxy="http://USERNAME:PASSWORD@HOST:PORT"
curl https://example.com

这里账号密码只能写在地址里,特殊字符要转义。其他程序也会读这些变量,export 会影响这个终端里运行的所有程序;只想对一条命令生效,就写在命令前面(https_proxy=… curl …)。

配置文件

curl 启动时会读取 ~/.curlrc(Windows 在应用数据目录下的 _curlrc),-K 文件 可以指定其他文件。写法和命令行参数相同,只是去掉横杠:

text
proxy = "http://HOST:PORT"
proxy-user = "USERNAME:PASSWORD"

哪个设置优先

curl 读取代理的顺序,先找到的生效:命令行里的 -x;其次是配置文件里的 proxy,即 ~/.curlrc 或 curl -K 文件;再次是环境变量 https_proxy、http_proxy、ALL_PROXY;都没有就直接连接。写在 --noproxy 或 NO_PROXY 里的地址任何情况下都不走代理
命令行优先,其次是配置文件,最后是环境变量。

我们测试时,-x 和配置文件都会覆盖错误的 https_proxy。-x 和 -K 同时出现时,命令行里写在后面的生效,所以 curl 最先读取的 ~/.curlrc 不会覆盖你的 -x。某个请求不想走代理,用 --noproxy '*';想忽略 ~/.curlrc,把 -q 放在命令最前面。

排查代理连接

用 -v 查看通信过程

-v 会打印每一步。下面是通过测试代理的一次正常请求的开头:

text
* Connected to 127.0.0.1 (127.0.0.1) port 28181
* Proxy auth using Basic with user 'user'
* Establish HTTP proxy tunnel to example.com:443
> CONNECT example.com:443 HTTP/1.1
> Proxy-Authorization: Basic dXNlcjpwQHNzOndvcmQ=
< HTTP/1.1 200 Connection established
* CONNECT tunnel established, response 200

> 开头的是 curl 发给代理的,< 开头的是代理的回复。隧道没有建立,说明问题出在 curl 和代理之间,和网站无关。注意 Proxy-Authorization 只是 Base64 编码,并没有加密:带真实账号的 -v 输出不要贴到工单或聊天里。

通过代理用 -I(只看响应头)时,第一行是代理的 HTTP/1.1 200 Connection established,后面才是网站自己的响应头,所以看到的第一个状态行并不是网站的。

用 -w 给每一步计时

bash
curl -x http://HOST:PORT -U "USERNAME:PASSWORD" -o /dev/null -s \
  -w 'connect: %{time_connect}s  tls: %{time_appconnect}s  total: %{time_total}s\n' \
  https://example.com

time_connect 是连接代理的耗时;它和 time_appconnect 之间的差,是建隧道加上和网站 TLS 握手的耗时。连接慢,问题在你到代理的线路;连接快但总耗时长,问题在出口或网站。

常见报错

退出码 7、56、97、28 的报错信息来自我们的实测;退出码 5 的说明来自 curl 文档。

退出码报错信息常见原因
7Failed to connect to 127.0.0.1 port 1 after 0 ms: Couldn't connect to server端口错误,或你的网络连不上代理
56CONNECT tunnel failed, response 407没有填或填错了代理账号密码,见代理 407 错误
56Recv failure: Connection reset by peer协议写错,比如用 http:// 连 SOCKS5 端口
97User was rejected by the SOCKS5 server (1 1).SOCKS5 的用户名或密码错误
28Connection timed out after 8006 milliseconds连不上代理,或用了代理不支持的协议
5Could not resolve proxy代理主机名写错了

在 NanoIP 代理上使用 curl

动态住宅和移动代理通过 HTTPS 网关连接,账号密码用 Dynamic Routes 里生成的路由:

bash
curl -x https://gateway.nanoip.net:1111 -U "USERNAME:PASSWORD" https://ipinfo.io/json

每个静态 ISP 代理都有自己的主机和端口,同一组账号同时支持 HTTP 和 SOCKS5:

bash
curl -x http://HOST:PORT -U "USERNAME:PASSWORD" https://ipinfo.io/json
curl -x socks5h://HOST:PORT -U "USERNAME:PASSWORD" https://ipinfo.io/json

在轮换路由上多运行几次住宅代理的命令,每次 IP 都会变;粘性路由或静态 ISP 的 IP 则保持不变。NanoIP 只用用户名密码认证,在任何网络下命令都一样。各项信息在哪里看,见新手入门;会话类型的区别,见轮换会话和粘性会话的区别。

常见问题

curl 会使用系统代理设置吗?

不会。curl 不读取 macOS 和 Windows 网络设置里的代理,只认 -x、配置文件和上面这些环境变量。

怎么让某些地址不走代理?

加 --noproxy,后面跟逗号分隔的地址,比如 --noproxy localhost,example.com;也可以设置 NO_PROXY。--noproxy '*' 表示所有地址都不走代理。

为什么浏览器能用,curl 不行?

浏览器可能用的是另一个代理,或者根本没用代理。先用 env | grep -i proxy 看看设置了哪些变量,再用 -x 和 -U 明确指定代理,查看 -v 的输出。

作者:NanoIP Team · Proxy infrastructure and customer support team

相关文章

教程

Playwright 怎么设置代理?Node.js 实测教程

在 Playwright 里给整个浏览器或每个上下文设置代理、填写账号密码、检查出口 IP,以及常见报错的处理方法。文中代码均已实际运行。

约 4 分钟

对比

独享IP和共享IP有什么区别?代理怎么选

独享代理IP在套餐期内只有你在用,共享IP同时有多个用户。本文用图讲清共享会带来哪些影响、各自适合什么场景,以及购买前要问服务商的五个问题。

约 5 分钟

配置遇到问题?

我们的技术支持团队可以和你一起检查代理配置。