21 个版本
0.3.1 | 2024 年 7 月 24 日 |
---|---|
0.3.0 | 2024 年 7 月 20 日 |
0.2.24 | 2024 年 7 月 16 日 |
0.2.23 | 2024 年 6 月 23 日 |
0.2.11 | 2024 年 2 月 25 日 |
#301 在 网络编程
312 每月下载量
145KB
3K SLoC
tun2proxy
Linux、Android、macOS、iOS 和 Windows 上 HTTP 和 SOCKS 代理的隧道接口。
更多信息可以在 wiki 中找到
特性
- HTTP 代理支持(未认证、基本和摘要认证)
- SOCKS4 和 SOCKS5 支持(未认证、用户名/密码认证)
- SOCKS4a 和 SOCKS5h 支持(通过虚拟 DNS 功能)
- 为所有流量设置最小的配置
- 支持 IPv4 和 IPv6
- 针对某些用例的 GFW 避免机制(见 问题 #35)
- SOCKS5 UDP 支持
- 本地支持代理 DNS over TCP
构建
克隆存储库并将 cd
进入项目文件夹。然后运行以下命令
cargo build --release
构建适用于 Apple 设备的框架
要为 macOS 和 iOS 构建一个 XCFramework,请运行以下命令
./build-apple.sh
安装
从二进制文件安装
从 发布 下载二进制文件并将其放在您的 PATH
中。
真实性验证
从 v0.2.23 开始支持 构建起源证明。这些证明允许您确保构建是通过 GitHub CI/CD 流程从 GitHub 上的代码生成的。要验证构建文件的真实性,您可以使用 GitHub CLI
gh attestation verify <*.zip file> --owner tun2proxy
从源安装
如果您已安装 rust 工具链,则此操作应该会成功
cargo install tun2proxy
注意:在 Windows 上,您需要将 wintun DLL 复制到与二进制文件相同的目录。默认情况下,它是
%USERPROFILE%\.cargo\bin
设置
自动设置
使用--setup
,可以让tun2proxy配置您的系统,自动将所有流量通过指定的代理路由。这需要以root权限运行工具,并将大致执行描述手动设置的章节中概述的步骤,但使用挂载绑定来覆盖/etc/resolv.conf
文件。
您可以使用以下命令运行工具
sudo ./target/release/tun2proxy --setup --proxy "socks5://1.2.3.4:1080"
除了SOCKS5外,还支持SOCKS4和HTTP。
请注意,如果您的代理是一个非全局IP地址(例如,因为代理是由运行在本地的某些隧道工具提供的),您还需要提供通过实际隧道传输流量的服务器的公网IP地址。在这种情况下,如果您想使用自动设置功能,工具将告诉您通过--bypass <IP/CIDR>
指定地址。
手动设置
一个标准的设置,可以将系统中的所有流量通过隧道接口路由,可能如下所示
# The proxy type can be either SOCKS4, SOCKS5 or HTTP.
PROXY_TYPE=SOCKS5
PROXY_IP=1.2.3.4
PROXY_PORT=1080
BYPASS_IP=123.45.67.89
# Create a tunnel interface named tun0 which you can bind to,
# so we don't need to run tun2proxy as root.
sudo ip tuntap add name tun0 mode tun
sudo ip link set tun0 up
# To prevent a routing loop, we add a route to the proxy server that behaves
# like the default route.
sudo ip route add "$BYPASS_IP" $(ip route | grep '^default' | cut -d ' ' -f 2-)
# Route all your traffic through tun0 without interfering with the default route.
sudo ip route add 128.0.0.0/1 dev tun0
sudo ip route add 0.0.0.0/1 dev tun0
# If you wish to also route IPv6 traffic through the proxy, these two commands will do.
sudo ip route add ::/1 dev tun0
sudo ip route add 8000::/1 dev tun0
# Make sure that DNS queries are routed through the tunnel.
sudo sh -c "echo nameserver 198.18.0.1 > /etc/resolv.conf"
./target/release/tun2proxy --tun tun0 --proxy "$PROXY_TYPE://$PROXY_IP:$PROXY_PORT"
此工具实现了一个虚拟DNS功能,由--dns virtual
开关使用。当检测到端口53的DNS数据包时,从198.18.0.0/15
选择一个IP地址并将其映射到查询名称。旨在该范围内的IP地址的连接将向代理提供映射后的查询名称而不是IP地址。由于许多代理不支持UDP,这通常可以使大多数情况下的即插即用体验成为可能,而不需要依赖第三方解析器或应用程序。根据您的用例,您可能想使用--dns direct
禁用此功能。在这种情况下,您可能需要一个额外的工具,如dnsproxy,该工具配置为监听本地UDP端口,并通过TCP与第三方上游DNS服务器通信。
当您终止此程序并想消除上述几个命令造成的影响时,可以执行以下命令。路由将与隧道设备一起自动删除。
sudo ip link del tun0
CLI
Tunnel interface to proxy.
Usage: tun2proxy [OPTIONS] --proxy <URL> [ADMIN_COMMAND]...
Arguments:
[ADMIN_COMMAND]... Specify a command to run with root-like capabilities in the new namespace when using `--unshare`.
This could be useful to start additional daemons, e.g. `openvpn` instance
Options:
-p, --proxy <URL> Proxy URL in the form proto://[username[:password]@]host:port, where proto is one of
socks4, socks5, http. For example: socks5://myname:[email protected]:1080
-t, --tun <name> Name of the tun interface, such as tun0, utun4, etc. If this option is not provided, the
OS will generate a random one
--tun-fd <fd> File descriptor of the tun interface
--unshare Create a tun interface in a newly created unprivileged namespace while maintaining proxy
connectivity via the global network namespace
-6, --ipv6-enabled IPv6 enabled
-s, --setup Routing and system setup, which decides whether to setup the routing and system
configuration. This option is only available on Linux and requires root-like privileges.
See `capabilities(7)`
-d, --dns <strategy> DNS handling strategy [default: direct] [possible values: virtual, over-tcp, direct]
--dns-addr <IP> DNS resolver address [default: 8.8.8.8]
-b, --bypass <IP/CIDR> IPs used in routing setup which should bypass the tunnel, in the form of IP or IP/CIDR.
Multiple IPs can be specified, e.g. --bypass 3.4.5.0/24 --bypass 5.6.7.8
--tcp-timeout <seconds> TCP timeout in seconds [default: 600]
--udp-timeout <seconds> UDP timeout in seconds [default: 10]
-v, --verbosity <level> Verbosity level [default: info] [possible values: off, error, warn, info, debug, trace]
-h, --help Print help
-V, --version Print version
目前,tun2proxy支持HTTP、SOCKS4/SOCKS4a和SOCKS5。代理以URL格式提供给--proxy
参数。例如,一个位于1.2.3.4:3128
的HTTP代理,用户名为john.doe
,密码为secret
,提供为--proxy http://john.doe:secret@1.2.3.4:3128
。这类似于curl的--proxy
参数。
Docker支持
Tun2proxy可以作为其他Docker容器的代理。要使用此功能,首先构建镜像
docker build -t tun2proxy .
然后,从tun2proxy镜像启动一个容器
docker run -d \
-v /dev/net/tun:/dev/net/tun \
--sysctl net.ipv6.conf.default.disable_ipv6=0 \
--cap-add NET_ADMIN \
--name tun2proxy \
tun2proxy --proxy proto://[username[:password]@]host:port
然后,您可以通过共享网络命名空间(如kubernetes sidecar)将运行中的容器的网络提供给另一个工作容器
docker run -it \
--network "container:tun2proxy" \
ubuntu:latest
配置技巧
DNS
当您的机器上的服务或本地网络中的服务器执行DNS解析时,DNS解析将通过隧道接口进行,因为指向localhost或您的本地网络的路径比0.0.0.0/1
和128.0.0.0/1
更具体。在这种情况下,建议您更新/etc/resolv.conf
文件以使用通过隧道接口路由的名称服务器地址。当虚拟DNS正常工作时,您将看到类似DNS查询:example.org
的日志消息,这是您的机器解析后连接到的主机名。
请注意,像NetworkManager
这样的软件可能会在任何时候自动更改/etc/resolv.conf
文件,从而导致DNS泄露。一种防止这种情况的临时解决方案是将文件设置为不可变,如下所示:sudo chattr +i "$(realpath /etc/resolv.conf)"
。
IPv6
一些代理服务器可能不支持IPv6。在虚拟DNS中使用时,这不是问题,因为DNS名称由代理服务器解析。当DNS名称在本地解析为IPv6地址时,这成为问题,因为代理将要求与IPv6目的地建立连接。在这种情况下,您可以在机器上禁用IPv6。这可以通过sysctl -w net.ipv6.conf.all.disable_ipv6=1
和sysctl -w net.ipv6.conf.default.disable_ipv6=1
或通过ip -6 route del default
来完成,这将导致libc
解析器(和其他软件)不发出针对IPv6地址的DNS AAAA请求。
依赖关系
~21–35MB
~574K SLoC