# 简介
很久之前写了用虚拟机 + clash 来做透明网关的文章,但最近随着学习的完善,发现之前写的不够全面,因此重新完善了下。
# 什么是透明代理
透明代理,全程为透明代理网关。
简单的说就是不让被代理的设备察觉的自己被代理的,被代理的设备上不需要运行任何代理软件 (比如 Xray、V2RayNG 等),当你连接上网络时,你的设备已经被代理了。
回忆下,我们如果正常访问,流量走向如何?
本机 -> 网关(在家庭中通常就是路由器)-> 上层网关 ->…-> 外网目的。
在这个过程中,网关(路由器)是不是就是一种代理软件,它对于应用而言就是一种透明代理。
# 为什么要用透明代理?
首先为什么要用代理?
无非就是我们的师夷长技以制夷需求或者帮助他人系统寻找漏洞的做好事行为。
这种情况下,我们通常只是要求特定应用的流量走代理,比如浏览器、渗透工具等等。
接着看看我们日常是怎么使用代理的,要代理一个浏览器,我们可以直接修改 Windows 的系统代理选项(但这个选项只可设置为 HTTP 代理,并且只是能代理 HTTP 流量),也可以在浏览器那边安装一些代理的插件,都能轻松实现浏览器流量走代理。
那问题来了,如果有些软件本身没并没有代理服务器的设置呢?
这种情况下我们可以使用 proxifer,它能够根据规则来使一些流量路由到指定的代理上。而且甚至能设置流量哦走代理链。具体原理由于商业闭源原因,貌似是在 R0 层通过过滤驱动的方式劫持流量实现的(https://www.zhihu.com/question/37610676?sort=created)。
虽然 porxifer 很好用,但它本身还是有一些问题的,比如 proxyifer 面对 widnows 的一些软件没法 hook 到(全局直连也不行)。(比如 sqlserver 管理 smss、curl 就不行)。
PS:这里贴一张 proxifier 设置了 cmd.exe 和 curl.exe 走代理的规则,但仍 hook 不到,导致流量不走代理的图
因此面对这种情况的最优解决方案我认为就是透明网关了。因为是在网关处做的代理,不需要劫持任何应用的流量,因为这对于应用而言流量其实并未走代理,而是把流量正常的交给了上级网络设备(网关)。
当然问题就是你这台机子上的所有流量都会走代理,比如你的 wechat、qq 什么的。(虽然也可以做策略,让特定流量才走,但这样就很麻烦)。
# 透明代理的实现
透明代理的实现目前主要有两种方式
①TAP/TUN 代理(在本机上即可实现)
②iptables/nftables(在 windows 下不可行,因此通常需要其他机子,不局限于实体机,虚拟机也行)
PS:我强烈建议去玩方案 2,搭建一个 openwrt,是真滴爽。
# TUN/TAP
具体原理如下:
https://blog.kghost.info/2013/03/27/linux-network-tun/
我理解就是虚拟一张网卡,让流量先经过它并在这个过程中修改了路由指向,再走出去。
具体实现的工具我选择的是 netch(其实还有其他工具,比如 sstap、Clash 之类的)
https://github.com/netchx/netch
Netch 可以实现类似 SocksCap64 那样的进程代理,也可以实现 SSTap 那样的全局 TUN/TAP 代理,和 Shadowsocks-Windows 那样的本地 Socks5,HTTP 和系统代理。至于连接至远程服务器的代理协议,目前 Netch 支持以下代理协议:Shadowsocks,VMess,Socks5,ShadowsocksR
PS: 如果 proxifier 能代理我们的目标进程就尽量用它,netch 有个毛病,不能设置进程白名单直连,也就是说如果你的 socks 是开在本地的,就会回环。虽然能通过设置直连 ip 来防止,但操作起来还是比较麻烦的。
这里我用 v2rayN 在本地开启了一个 socks 代理端口,接着使用 netch 来把本机所有流量都转到这个 socks 端口。
服务器选择我们本地的 v2rayN 的 socks 端口,模式选择 3 BypassLAN(也就是 TUN 模式,所有流量都走代理)。
此时先别急着启动,正如前面所说,它不支持进程白名单,如果直接启动了,v2rayN 的流量会被 netch 代理到 v2rayN 的 socks 端口,这就导致回环,netch 就会崩溃。
因此需要在 netch 的设置 ->WinTUN-> 全局直连 ip 中把 v2rayN 的这个节点的 ip 给加上。
这样只要一启动 netch,我们本机的流量就都走 v2rayN 的这个 socks 了。如下,cmd 的 curl 命令成功走代理。
# iptables/nftables(需要虚拟机或实体机)
这里我推荐的是 openwrt 方案,并且强烈建议拿家里不用的垃圾路由器来刷 openwrt,这样就不需要开启虚拟机消耗计算机资源了。
大致原理就是利用代理工具本地开启一个 socks 监听,然后通过 iptables 把流量转到这个 socks 监听端口上。
显而易见的,这是基于 iptables 的一种方法,因此只能用于 Linux 系统 (包括 openwrt / 安卓)。由于其比 tun2socks 更高效率以及适合在路由器中配置而被广泛使用(openwrt 等软路由系统)。
iptables 与 nftables 实现透明代理的原理相同,下文统一使用 iptables。
# 基于 openwrt 的透明代理
openwrt 其实就是一个软路由的系统,其底层还是 Linux,通常内置了 clash、passwall 等师夷长技以制夷工具。
并且其配置简单,支持 pppoe 拨号、DHCP 等功能,只要插上网线它就是一个网关,一个路由。
所以用它做透明网关是非常轻松的。
第一步是刷系统,看是用虚拟机来搭还是实体机了。我是用的硬路由刷的,见我之前的文章。
虚拟机安装也不麻烦。
安装好后,需要让 openwrt 连上网,这里我是有线的 PPPOE 上网。
然后有网后就配置科学上网工具即可。
当然如果打的是内网,代理是个正向的 socks 不是机场的话,也是可以自定义的添加的。
回到主页面,选择服务器,并勾选全局模式即可。
这样,当我们通过有线(无线)的方式连接上它后,它就会为我们分配 ip,相当于它就是我们的路由器了。
然后我们的全部流量都会根据这个规则(全局?GFW?),由 openwrt 决定流向了。
(如果是虚拟机做的 openwrt 的话,就把网关设置成它就行了)
PS:如果是硬路由改装的 openwrt,并且有网卡的话,openwrt 甚至可以发射 wifi,然后我们直接连接它的 wifi,这样整个网络的所有设备都会去走代理。以后随身携带,出门干架前直接连上它,就不需要担心真实 ip 被拔了。
# Linux 虚拟机 + Clash
# 下载并配置 clash
# 下载 clash
wget https://github.com/Dreamacro/clash/releases/download/v1.10.0/clash-linux-amd64-v1.10.0.gz | |
mv clash-linux-amd64-v1.10.0 /usr/local/bin/clash | |
chmod +x /usr/local/bin/clash |
# 配置 clash
clash 的配置文件在当前用户的.config/clash 目录下
我们需要新建一个文件夹然后将 config.yaml 给加进去
mkdir ~/.config/clash | |
cd ~/.config/clash | |
wget https://github.com/haishanh/yacd/archive/gh-pages.zip | |
mv yacd-gh-pages/ dashboard/ |
(没机场就去买,如果用的是免费机场,你可能就得注意下了,毕竟前阵子 clash 刚爆了个 RCE 漏洞。)
然后将我们 windows 上的 config.yaml copy 一份,稍做修改,主要是开启 redir-port,并允许局域网访问,同时启用 web dashboard
由于在路由器或虚拟机中使用 Clash 做透明代理时,需要使用 Clash 内置的 DNS 服务器进行解析,DNS 服务器会生成 IP 和域名的关系,从而在 Clash 端反推对应的域名(因为 redir 只能传递 IP)
所以必须要配置 DNS 服务器,在 config.yaml 的后面追加配置
这时候 clash 的配置我们设置的差不多了。此时直接运行 clash,开启监听。
访问 127.0.0.1:9090/ui/ 可以看到 dashboard
# 配置 ubuntu
# 开启 IP 转发
一个网关最重要的功能就是转发,因此我们需要开启 linux 的转发规则
echo "net.ipv4.ip_forward = 1" >> /etc/sysctl.conf && sysctl -p | |
echo "net.ipv6.conf.all.forwarding = 1" >> /etc/sysctl.conf && sysctl -p | |
cat /proc/sys/net/ipv4/ip_forward |
显示为 1 则成功开启
# 配置 iptables 规则
只是开启了转发还不够,如果不做配置,我们所有访问它的流量都会被 ubutn 给转发掉,这样我们就不能直接在这边 ssh 这台 ubuntu 了。所以我们需要修改规则,让 ubuntu 只把非内网和环回的地址转发到 clash 上。
这里 iptables 的作用是转发流量到 clash 的 redir-port 端口。
需要注意的是:iptables 规则我们每次重启后都需要设置
iptables -t nat -N Clash | |
iptables -t nat -A Clash -d 192.168.0.0/16 -j RETURN #这个网段的不走代理 | |
iptables -t nat -A Clash -d 127.0.0.0/8 -j RETURN | |
iptables -t nat -A Clash -d 172.16.0.0/12 -j RETURN | |
iptables -t nat -A Clash -d 10.0.0.0/8 -j RETURN | |
iptables -t nat -A Clash -d 169.254.0.0/16 -j RETURN | |
iptables -t nat -A Clash -d 0.0.0.0/8 -j RETURN | |
iptables -t nat -A Clash -d 224.0.0.0/4 -j RETURN | |
iptables -t nat -A Clash -d 240.0.0.0/4 -j RETURN | |
iptables -t nat -A Clash -p tcp -j REDIRECT --to-ports 7892 | |
iptables -t nat -A PREROUTING -p tcp -j Clash |
如果想要删除某条规则的话
iptables -t nat -L -n --line-number #列出 nat 表中的规则 | |
iptables -t nat -D Clash 1 #删除 nat 表中 Clash 链中的第一条规则 |
# clash 的其他配置(主要是机场自身的 rule 规则)
机场中的配置文件可能存在一些问题,比如淘宝、百度之类的就不走代理,一般来说是没啥毛病的,但是我们攻击的目标是它们,你不走代理这就不对劲了是吧。
因此更新节点的时候需要注意,config.ymal 下面的 rule 规则,给全球拦截、直连、净化什么的都加上节点选择的规则,这样就可以实现全走代理了。
这里我们选择让全球直连直接通节点选择,但是这样的话全球直连这个规则也失去了意义。(推荐)
就原本的流量可能是 windwos->ubuntu-> 目标 ip 命中全球直连规则 -> 直接不走代理,直接连接
走节点选择的话就是 windwos->ubuntu-> 目标 ip 命中全球直连规则 -> 节点选择 -> 代理节点
# 流量接管
按照上述步骤按照部署完成后,我们本机把网关和 dns 设置成 ubuntu 所在的机子就能够通过代理上网了。