什么是透明代理
传统代理需要在每台设备上手动配置代理地址,而透明代理工作在网关层面——局域网内的设备只需将默认网关和 DNS 指向代理机器,所有 TCP 流量就会被自动拦截并转发到上游代理,设备本身无需任何代理配置。
这对于不方便设置代理的设备(智能电视、IoT 设备、游戏主机等)尤其有用。
trans_proxy 的工作原理
trans_proxy 是一个用 Rust 编写的透明代理工具,支持 macOS 和 Linux,基于 tokio 异步运行时构建。下图展示了它的整体架构:
原始目的地址恢复
透明代理面临的第一个问题是:流量被 NAT 重定向到 trans_proxy 的监听端口后,如何知道客户端原本要访问的目标地址?
trans_proxy 针对不同平台采用了不同的方案:
- macOS (pf):通过
DIOCNATLOOKioctl 查询 pf 的 NAT 状态表,从中获取连接被重定向前的原始目的地址 - Linux (nftables):通过
SO_ORIGINAL_DSTgetsockopt 从 accepted socket 上读取原始目的地址
主机名解析
拿到原始 IP 和端口后,trans_proxy 还需要将 IP 解析为域名,因为上游 HTTP CONNECT 代理需要的是 CONNECT hostname:port 格式的请求。trans_proxy 按以下优先级确定主机名:
- SNI 提取:对于 TLS 连接(端口 443),解析 ClientHello 消息中的 SNI 扩展字段,直接获取客户端要访问的域名,无需解密 TLS 流量
- DNS 表查询:如果启用了内置 DNS 转发器,trans_proxy 会记录 DNS 查询结果,从中反查 IP 对应的域名
- IP 回退:如果以上两种方式都无法获取域名,则直接使用 IP 地址
内置 DNS 转发器
trans_proxy 内置了一个 DNS 转发器,监听在网关接口的 53 端口,具备以下能力:
- DNS-over-HTTPS (DoH):支持将 DNS 查询通过 HTTPS 发送到上游 DNS 服务器(默认 Cloudflare),防止 DNS 污染
- HTTP/2 连接池:复用 HTTP/2 连接,降低 DoH 查询延迟
- TTL 缓存:根据 DNS 记录的 TTL 值缓存查询结果
- 查询合并:对同一域名的并发查询进行合并,避免重复请求
这个 DNS 转发器不仅提供 DNS 服务,还为上面提到的主机名解析提供 IP 到域名的反查记录。
防火墙集成
trans_proxy 通过脚本管理防火墙规则:
- macOS:使用 pf 的 anchor 机制,将 NAT 重定向规则挂载到独立的 anchor 下,不影响系统已有的 pf 规则
- Linux:创建独立的 nftables table,同样不会干扰现有的防火墙配置
安装与编译
# 克隆仓库
git clone https://github.com/madeye/trans_proxy.git
cd trans_proxy
# 编译(需要 Rust 1.70+)
cargo build --release
# 编译产物在 target/release/trans_proxy
使用方法
macOS
假设网关机器的网络接口为 en0,上游 HTTP CONNECT 代理运行在本地 127.0.0.1:1082:
# 启动 trans_proxy(启用 DNS 转发器)
sudo ./trans_proxy --upstream-proxy 127.0.0.1:1082 --dns
# 设置 pf NAT 重定向规则
sudo scripts/pf_setup.sh en0 8443
Linux
假设网关接口为 eth0,上游代理在 127.0.0.1:7890:
# 启动 trans_proxy
sudo ./trans_proxy --upstream-proxy 127.0.0.1:7890 --dns --interface eth0
# 设置 nftables 规则
sudo scripts/nftables_setup.sh eth0 8443
主要参数
| 参数 | 默认值 | 说明 |
|---|---|---|
--listen-addr | 0.0.0.0:8443 | trans_proxy 监听地址 |
--upstream-proxy | (必填) | 上游 HTTP CONNECT 代理地址 |
--dns | 关闭 | 启用内置 DNS 转发器 |
--interface | en0 / eth0 | 网关网络接口 |
--dns-upstream | Cloudflare DoH | 上游 DNS 服务器(支持 UDP 或 DoH) |
--log-level | info | 日志级别(trace/debug/info/warn/error) |
-d / --daemon | 关闭 | 以守护进程方式运行 |
客户端配置
局域网内的设备只需两步:
- 将默认网关设为运行 trans_proxy 的机器 IP
- 将 DNS 服务器设为同一 IP(如果启用了
--dns)
支持 macOS、iOS、Windows、Linux、Android 等所有主流平台,设备端无需安装任何软件。
安装为系统服务
trans_proxy 支持一键安装为系统服务:
sudo ./trans_proxy --upstream-proxy 127.0.0.1:1082 --dns --install
- macOS:创建 LaunchDaemon,开机自启
- Linux:创建 systemd unit,并通过
ExecStartPre/ExecStopPost自动管理 nftables 规则的加载和清除
卸载服务:
sudo ./trans_proxy --uninstall
排查问题
遇到问题时,先提高日志级别观察:
sudo ./trans_proxy --upstream-proxy 127.0.0.1:1082 --dns --log-level debug
常见问题:
/dev/pf权限错误(macOS):确保以 root 权限运行- NAT 查询失败:检查防火墙规则是否正确加载(macOS 用
pfctl -sa,Linux 用nft list ruleset) - 连接超时:确认上游代理运行正常,检查网关机器是否开启了 IP 转发(Linux 需要
sysctl net.ipv4.ip_forward=1) - DNS 解析失败:确认 53 端口没有被其他进程占用(
lsof -i :53)
与 Caddy 正向代理配合
trans_proxy 需要一个上游 HTTP CONNECT 代理。如果你还没有现成的,可以参考之前的文章用 Caddy 搭建一个。一个典型的组合方式:
局域网设备 → trans_proxy(网关) → Caddy HTTPS 正向代理(远程服务器) → 目标网站
这样局域网内的设备无需任何配置,所有流量自动通过加密隧道转发。
小结
trans_proxy 解决的核心问题是:如何让局域网内所有设备无感知地通过代理访问网络。它的优势在于:
- 零配置客户端:设备只需改网关和 DNS,无需安装软件或配置代理
- 跨平台:同时支持 macOS (pf) 和 Linux (nftables) 作为网关
- DNS 防污染:内置 DoH 转发器,从源头解决 DNS 污染问题
- 无侵入式防火墙管理:anchor / 独立 table 机制不干扰现有规则
- 异步高性能:基于 tokio,每个连接独立调度,适合网关场景的高并发需求