什么是透明代理
传统代理需要在每台设备上手动配置代理地址,透明代理则工作在网关这一层:局域网设备只要把默认网关和 DNS 指向代理机器,所有 TCP 流量就会被自动拦截并转发到上游代理,设备本身不用做任何代理配置。
这对不方便设置代理的设备(智能电视、IoT 设备、游戏主机等)尤其有用。
trans_proxy 的工作原理
trans_proxy 是一个用 Rust 写的透明代理工具,支持 macOS 和 Linux,基于 tokio 异步运行时。它的整体架构如下:
获取原始目的地址
透明代理要解决的第一个问题是:流量被 NAT 重定向到 trans_proxy 的监听端口后,怎么知道客户端原本想访问的地址?
trans_proxy 在两个平台上用了不同的办法:
- macOS (pf):通过
DIOCNATLOOKioctl 查询 pf 的 NAT 状态表,拿到连接被重定向前的原始目的地址 - Linux (nftables):在 accept 出来的 socket 上通过
SO_ORIGINAL_DSTgetsockopt 读取原始目的地址
解析出 hostname
拿到原始 IP 和端口后,还要把 IP 还原成域名,因为上游 HTTP CONNECT 代理需要 CONNECT hostname:port 格式的请求。trans_proxy 按下面的优先级确定 hostname:
- SNI 提取:对 TLS 连接(端口 443),解析 ClientHello 里的 SNI 扩展字段,直接拿到客户端要访问的域名,不需要解密 TLS 流量
- DNS 反查:如果启用了内置 DNS 转发器,trans_proxy 会记录 DNS 查询结果,可以从里面反查 IP 对应的域名
- IP fallback:两种办法都拿不到域名时,就直接用 IP
内置 DNS 转发器
trans_proxy 内置了一个 DNS 转发器,监听网关接口的 53 端口,功能包括:
- DNS-over-HTTPS (DoH):把 DNS 查询通过 HTTPS 发给上游 DNS 服务器(默认 Cloudflare),避免 DNS 污染
- HTTP/2 连接池:复用 HTTP/2 连接,降低 DoH 查询延迟
- TTL 缓存:按 DNS 记录的 TTL 缓存查询结果
- 查询合并(coalescing):合并对同一域名的并发查询,避免重复请求
除了提供 DNS 服务,它记录的查询结果也给上面的 hostname 解析提供了 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 | 关闭 | 以 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,每个连接独立调度,适合网关的高并发场景
