使用tun2socks实现全局代理
修改系统路由表的操作具有一定风险性,须谨慎操作。
未完待续
1.tun2socks概述
有时在纯命令行环境下,执行某些命令操作需要设置代理,比如新冠疫情期间居家办公时,通过git clone从公司内网拉取项目,从本地启动java进程调试程序,就需要连接公司的代理服务器,一些命令可以通过追加控制台代理参数export http_proxy实现从代理服务器访问目标地址,但是并不是所有的命令都支持控制台代理。
tun2socks(https://github.com/xjasonlyu/tun2socks/)是一个基于go语言的,支持多个平台的开源项目,可以在更深的层面彻底解决代理上网的问题,不同于控制台代理或命令自身支持设置代理服务器的方式,tun2socks将虚拟网络适配器从底层拦截并发送来的tcp/ip数据进行解包,将解离出的应用层数据包发送给sock/http代理服务器,并将代理服务器返回的数据再封装为tcp/ip数据包传递给虚拟网络适配器,虚拟网络适配器继而再传递给具体进程。
2.linux配置
例如当前的linux运行在虚拟机,地址是192.168.228.105,网关和DNS是192.168.228.2,代理服务器安装在宿主机192.168.228.1上
首先ip addr查看本地网络情况,可见机器上enp2s0网卡是连接本地内网的网卡,地址是192.168.228.105
[root@java105 ~]# ip addr
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
inet 127.0.0.1/8 scope host lo
valid_lft forever preferred_lft forever
inet6 ::1/128 scope host
valid_lft forever preferred_lft forever
2: enp2s0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc fq_codel state UP group default qlen 1000
link/ether 00:0c:29:8c:08:f8 brd ff:ff:ff:ff:ff:ff
inet 192.168.228.105/24 brd 192.168.228.255 scope global noprefixroute enp2s0
valid_lft forever preferred_lft forever
inet6 fe80::20c:29ff:fe8c:8f8/64 scope link noprefixroute
valid_lft forever preferred_lft forever
然后ip route查看系统路由表,通过default via 192.168.228.2 dev enp2s0可见enp2s0是默认出口,访问所有不在路由表中规定的目标地址,都通过enp2s0出站
[root@java105 ~]# ip route
default via 192.168.228.2 dev enp2s0 proto dhcp src 192.168.228.105 metric 100
192.168.228.0/24 dev enp2s0 proto kernel scope link src 192.168.228.105 metric 100然后,在使用tun2socks前,要先新建一个新的虚拟网卡tun0,随便分配个和现有不冲突的198.18.0.1/15网段,从网络层接管请求
# 创建 tun0 设备,模式为 tun
ip tuntap add mode tun dev tun0
# 给它配个IP并启用
ip addr add 198.18.0.1/15 dev tun0
ip link set dev tun0 up再次查看本地网卡信息和路由表,已经能见到tun0了,并且状态是state UP
[root@java105 ~]# ip addr
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
inet 127.0.0.1/8 scope host lo
valid_lft forever preferred_lft forever
inet6 ::1/128 scope host
valid_lft forever preferred_lft forever
2: enp2s0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc fq_codel state UP group default qlen 1000
link/ether 00:0c:29:8c:08:f8 brd ff:ff:ff:ff:ff:ff
inet 192.168.228.105/24 brd 192.168.228.255 scope global noprefixroute enp2s0
valid_lft forever preferred_lft forever
inet6 fe80::20c:29ff:fe8c:8f8/64 scope link noprefixroute
valid_lft forever preferred_lft forever
3: tun0: <POINTOPOINT,MULTICAST,NOARP,UP,LOWER_UP> mtu 1500 qdisc fq_codel state UP group default qlen 500
link/none
inet 198.18.0.1/15 scope global tun0
valid_lft forever preferred_lft forever
inet6 fe80::9601:d30a:4eec:d2e5/64 scope link stable-privacy
valid_lft forever preferred_lft forever[root@java105 ~]# ip route
default via 192.168.228.2 dev enp2s0 proto dhcp src 192.168.228.105 metric 100
192.168.228.0/24 dev enp2s0 proto kernel scope link src 192.168.228.105 metric 100
198.18.0.0/15 dev tun0 proto kernel scope link src 198.18.0.1 将对应平台的tun2socks命令下载到任意目录,并运行起来,指定监听通往刚刚建好的虚拟网卡tun0的请求
nohup ./tun2socks-linux-amd64 -device tun0 -proxy socks5://192.168.228.1:7897 &现在tun0已经在收集请求并由tun2socks处理了,但是系统默认路由还是指向enp2s0,各个进程的网络请求会涌向enp2s0而不是tun0,此时还要修改默认路由为tun0,将系统中各个进程的网络请求导入tun0
# 1. 删除现有默认路由
ip route del default
# 2. 添加新的默认路由,指向 tun0 接口
ip route add default dev tun0再次查看路由表
[root@java108 ~]# ip route
default dev tun0 scope link
192.168.228.0/24 dev enp2s0 proto kernel scope link src 192.168.228.105 metric 100
198.18.0.0/15 dev tun0 proto kernel scope link src 198.18.0.1 default已经指向了dev tun0,系统中所有tcp/udp请求都从网络层转发到dev tun0继而进入代理服务器socks5://192.168.228.1:7897
tun2socks作为一个进程当然也在不断发起网络请求到192.168.228.1,但是路由表中已经明确有了
192.168.228.0/24 dev enp2s0 proto kernel scope link src 192.168.228.105 metric 100这一条,规定了通往192.168.228.0/24的请求从物理网卡dev enp2s0出站,因此不会导致死循环。说
dev enp2s0是物理网卡当然是相对于dev tun0而言的
如果恢复原先的路由,则需要
# 先删掉走代理用的tun0路由
ip route del default dev tun0
# 添加默认路由(不要忘记网关)
ip route add default via 192.168.228.2 dev enp2s0最后需注意,tun2socks+tun这种方式仅支持代理tcp/udp,不支持对icmp请求进行代理,因此测试验证时应该用curl或telnet而不是ping,而且如果使用域名访问,还需要设置DNS
有些linux发行版(例如ubuntu),会通过systemd-resolved模块将DNS请求转发到默认网卡上设置的DNS服务器进行解析,这种情况下如果需要代理服务器解析域名,可以为tun0指定DNS地址
resolvectl dns tun0 1.1.1.1 8.8.8.83.windows配置
tun2socks在windows系统上也是可以使用的,但是和linux系统略有不同
windows系统不像Linux可以一行命令就创建tun网卡,windows系统需要额外下载tun驱动,比如wintun,下载地址https://www.wintun.net/,下载了和当前系统架构相符的dll文件后,和windows版本的tun2socks的exe文件放在同一文件夹内。
D:\>dir
驱动器 D 中的卷是 新加卷
卷的序列号是 F63E-39E9
D:\ 的目录
2026/07/09 15:40 9,948,672 tun2socks-windows-amd64.exe
2026/07/09 15:03 222,488 wintun.dll
2 个文件 10,171,160 字节以管理员权限执行以下命令,启动tun2socks
D:\>tun2socks-windows-amd64.exe -device wintun -proxy socks5://192.168.228.1:7897然后,ipconfig命令可见已经自动创建好了一个tun
C:\Users\lzj>ipconfig
Windows IP 配置
未知适配器 wintun:
连接特定的 DNS 后缀 . . . . . . . :
本地链接 IPv6 地址. . . . . . . . : fe80::7a40:175e:4da6:2ecf%25
自动配置 IPv4 地址 . . . . . . . : 169.254.163.174
子网掩码 . . . . . . . . . . . . : 255.255.0.0
默认网关. . . . . . . . . . . . . : 0.0.0.0
以太网适配器 以太网:
连接特定的 DNS 后缀 . . . . . . . :
本地链接 IPv6 地址. . . . . . . . : fe80::f53b:fb74:ed:31e2%4
IPv4 地址 . . . . . . . . . . . . : 192.168.228.120
子网掩码 . . . . . . . . . . . . : 255.255.255.0
默认网关. . . . . . . . . . . . . :但是此时流量还不能走tun,route print命令查看windows路由表,第一条 0.0.0.0 0.0.0.0 192.168.228.2 192.168.228.120 271,发现流量还是经过物理网卡192.168.228.120,通过网关192.168.228.2,和Linux上一样,windows使用tun2socks+tun同样需要修改路由表才行
IPv4 路由表
===========================================================================
活动路由:
网络目标 网络掩码 网关 接口 跃点数
0.0.0.0 0.0.0.0 192.168.228.2 192.168.228.120 271
127.0.0.0 255.0.0.0 在链路上 127.0.0.1 331
127.0.0.1 255.255.255.255 在链路上 127.0.0.1 331
127.255.255.255 255.255.255.255 在链路上 127.0.0.1 331
169.254.0.0 255.255.0.0 在链路上 169.254.163.174 261
169.254.163.174 255.255.255.255 在链路上 169.254.163.174 261
169.254.255.255 255.255.255.255 在链路上 169.254.163.174 261
192.168.228.0 255.255.255.0 在链路上 192.168.228.120 271
192.168.228.120 255.255.255.255 在链路上 192.168.228.120 271
192.168.228.255 255.255.255.255 在链路上 192.168.228.120 271
224.0.0.0 240.0.0.0 在链路上 127.0.0.1 331
224.0.0.0 240.0.0.0 在链路上 192.168.228.120 271
224.0.0.0 240.0.0.0 在链路上 169.254.163.174 261
255.255.255.255 255.255.255.255 在链路上 127.0.0.1 331
255.255.255.255 255.255.255.255 在链路上 192.168.228.120 271
255.255.255.255 255.255.255.255 在链路上 169.254.163.174 261
===========================================================================
永久路由:
网络地址 网络掩码 网关地址 跃点数
0.0.0.0 0.0.0.0 192.168.228.2 默认
===========================================================================和之前Linux的思路一样,还是tun2socks访问192.168.228.0/8网段,要走物理网卡192.168.228.120,剩下的全部流量要走tun,即169.254.163.174
route add 192.168.228.0 mask 255.255.255.0 192.168.228.2route delete 0.0.0.0 mask 0.0.0.0 192.168.228.2route add 0.0.0.0 mask 0.0.0.0 169.254.163.174配置好后,路由表大致是这样的
IPv4 路由表
===========================================================================
活动路由:
网络目标 网络掩码 网关 接口 跃点数
0.0.0.0 0.0.0.0 在链路上 169.254.163.174 6
127.0.0.0 255.0.0.0 在链路上 127.0.0.1 331
127.0.0.1 255.255.255.255 在链路上 127.0.0.1 331
127.255.255.255 255.255.255.255 在链路上 127.0.0.1 331
169.254.0.0 255.255.0.0 在链路上 169.254.163.174 261
169.254.163.174 255.255.255.255 在链路上 169.254.163.174 261
169.254.255.255 255.255.255.255 在链路上 169.254.163.174 261
192.168.228.0 255.255.255.0 在链路上 192.168.228.120 271
192.168.228.0 255.255.255.0 192.168.228.2 192.168.228.120 16
192.168.228.120 255.255.255.255 在链路上 192.168.228.120 271
192.168.228.255 255.255.255.255 在链路上 192.168.228.120 271
224.0.0.0 240.0.0.0 在链路上 127.0.0.1 331
224.0.0.0 240.0.0.0 在链路上 192.168.228.120 271
224.0.0.0 240.0.0.0 在链路上 169.254.163.174 261
255.255.255.255 255.255.255.255 在链路上 127.0.0.1 331
255.255.255.255 255.255.255.255 在链路上 192.168.228.120 271
255.255.255.255 255.255.255.255 在链路上 169.254.163.174 261其实主要起作用的就是
0.0.0.0 0.0.0.0 在链路上 169.254.163.174 6
192.168.228.0 255.255.255.0 192.168.228.2 192.168.228.120 16"如果文章对您有帮助,可以请作者喝杯咖啡吗?"
微信支付
支付宝