pip install PySocks
这里可以详细解释一下原理:
1️⃣ 默认情况
get_url 在 Ansible 中底层调用的是 Python 的 urllib 或 requests 模块:
import urllib.request
它们原生只支持 HTTP、HTTPS 和 FTP 代理,例如:
http_proxy=http://1.2.3.4:8080 https_proxy=http://1.2.3.4:8080
当你写:
environment:
ALL_PROXY: socks5://120.240.166.145:10080
普通的 urllib 并不能识别 socks5:// 这个协议,所以不会生效,也就是你下载一直失败。
2️⃣ PySocks 的作用
PySocks 是 Python 的一个库,它提供了 SOCKS 协议支持,同时能挂钩到 Python 的 socket 层:
import socks
import socket
socks.set_default_proxy(socks.SOCKS5, "120.240.166.145", 10080)
socket.socket = socks.socksocket
- 它会重写 Python 的标准 socket 类,让所有通过 socket 发出的连接都走 SOCKS 代理。
- 因为
urllib、requests等都是基于标准 socket 发起 TCP 连接的,所以重写 socket 后,它们就能通过 SOCKS5 代理访问网络了。
这就是为什么“安装 PySocks 并配置 ALL_PROXY 后,get_url 就能用 SOCKS5 代理”——底层 socket 被劫持了。
3️⃣ 总结
- 没有 PySocks:Python 的网络模块识别不了
socks5://,代理无效。 - 安装 PySocks:它会 hook socket,实现 SOCKS5 支持,所有 Python 代码(包括 Ansible 的 get_url)都能使用 SOCKS5 代理。
- 注意:这种方式是Python 层面劫持 socket,所以全局有效,适用于 urllib、requests,但不适用于系统级
curl/wget,除非它们也支持 SOCKS5。
如果你需要,我可以帮你画一个图,直观显示 Python + PySocks 处理 SOCKS5 请求的流程。
你希望我画吗?
========================== Python 请求流程对比
1️⃣ 没有 PySocks
Python urllib/requests | | 代理 URL = socks5://... V socket.connect() | X 无法识别 socks5 协议 | 连接失败 / 无法通过代理
2️⃣ 安装 PySocks
Python urllib/requests | | 代理 URL = socks5://... V PySocks hook | V socket.connect() -> PySocks socket | | 通过 SOCKS5 代理服务器转发请求 V 目标服务器
说明:
- PySocks 通过替换 / hook Python 标准库的 socket.connect 方法, 在 Python 层面实现 SOCKS5 协议解析和数据转发。
- 对系统命令 (curl/wget) 无效,除非它们本身支持 SOCKS5。