Docker+Clash 部署透明“网关”的实现

​目录

前言:

偶然发现原来Docker里面的Clash也能进行全局网络接管,研究了一下,目前网络上的相关文章较少,且有些在实现上有错误。

故而整理出来这篇文章,仅供学习交流使用。

我会详细的解释一些设置和步骤,即便是基础知识薄弱也应该可以看懂。

1. Clash在Docker中的部署

1.1 部署可视化clash dashboard容器

首先将dashboard的image pull下来。

docker pull haishanh/yacd

然后直接跑起来就行,注意映射一个没在使用的端口就行

docker run -p 1234:80 -d haishanh/yacd

在浏览器键入服务器地址跟端口号,我这里是输入192.168.199.10:1234,就可以打开dashboard页面

1.2 部署clash容器

准备好你的配置文件config.yaml,节点和订阅得自己想办法,这里不提供,而且我也不认识毒药是谁。

将下边的代码覆盖入你原有的基础配置

port: 7890 socks-port: 7891 #转发端口一定要配置 redir-port: 7892 #允许接管局域网流量 allow-lan: true #默认代理模式 mode: Rule log-level: warning #接口控制端口你可以自己设置,默认是9090 external-controller: 0.0.0.0:7070 #如果服务器对公网开放可以设置密码 secret: "" #external-ui: dashboard #配置由clash接管的dns解析 dns: enable: true #主要监听定向转发来的数据,后续会在路由表里配置转发端口为1053 listen: 0.0.0.0:1053 enhanced-mode: redir-host #见下方链接 nameserver: - 114.114.114.114 - 223.5.5.5 fallback: - tls://1.1.1.1:853 - tcp://1.1.1.1:53 - tcp://208.67.222.222:443 - tls://dns.google

关于配置文件中的nameserver与fallback的运行与解析机制,详见下方链接。

DNS污染对Clash(for Windows)的影响 · Fndroid/clash_for_windows_pkg Wiki (github.com)​github.com/Fndroid/clash_for_windows_pkg/wiki/DNS%E6%B1%A1%E6%9F%93%E5%AF%B9Clash%EF%BC%88for-Windows%EF%BC%89%E7%9A%84%E5%BD%B1%E5%93%8D

准备好配置文件之后 ,运行如下命令启动clash容器

docker pull dreamacro/clash docker run --name Clash -d -v ~/clash/config.yaml:/root/.config/clash/config.yaml --network="host" --privileged dreamacro/clash

其中 -v 命令之后的挂载卷映射的左侧原始路径要改成你自己的config.yaml的位置。

如果配置文件设置无误的话,可以在dashboard页面输入服务器地址与端口,链接到clash进行设置了。

2. 配置路由表

2.1. 配置服务器路由表转发规则

可以终端中输入以下命令,也可以写进.sh脚本,chmod +x 之后执行./xxx.sh。

#在nat表中新建一个clash规则链 iptables -t nat -N CLASH #排除环形地址与保留地址,匹配之后直接RETURN iptables -t nat -A CLASH -d 0.0.0.0/8 -j RETURN iptables -t nat -A CLASH -d 10.0.0.0/8 -j RETURN iptables -t nat -A CLASH -d 127.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 172.16.0.0/12 -j RETURN iptables -t nat -A CLASH -d 192.168.0.0/16 -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 #重定向tcp流量到本机7892端口 iptables -t nat -A CLASH -p tcp -j REDIRECT --to-port 7892 #拦截外部tcp数据并交给clash规则链处理 iptables -t nat -A PREROUTING -p tcp -j CLASH #在nat表中新建一个clash_dns规则链 iptables -t nat -N CLASH_DNS #清空clash_dns规则链 iptables -t nat -F CLASH_DNS #重定向udp流量到本机1053端口 iptables -t nat -A CLASH_DNS -p udp -j REDIRECT --to-port 1053 #抓取本机产生的53端口流量交给clash_dns规则链处理 iptables -t nat -I OUTPUT -p udp --dport 53 -j CLASH_DNS #拦截外部upd的53端口流量交给clash_dns规则链处理 iptables -t nat -I PREROUTING -p udp --dport 53 -j CLASH_DNS

执行之后可以先采取设置非侵入式网关来测试一下服务器上的clash代理与dns解析是否成功。

2.2 路由表持久化

路由表每次重新开机之后都会回复为默认值,如果想要将更改的内容持久化,需要借助一个软件包 iptables-persistent 实现。

sudo apt install iptables-persistent

第一次安装时会问询是否保存当前路由表配置,保存之后每次重启就都可以恢复为保存时的配置。

如果对路由表有所修改,需要重新保存,则运行如下命令。

sudo dpkg-reconfigure iptables-persistent

2.3 路由表复原

如果需要删除上述的路由表配置,执行以下命令

iptables -t nat -D PREROUTING -p tcp -j CLASH iptables -t nat -D OUTPUT -p udp --dport 53 -j CLASH_DNS iptables -t nat -D PREROUTING -p udp --dport 53 -j CLASH_DNS iptables -t nat -F CLASH iptables -t nat -X CLASH iptables -t nat -F CLASH iptables -t nat -X CLASH_DNS

3. 两种流量接管方式

3.1 非侵入式

手动设置需要被接管流量的终端设备的IP地址,将网关地址与DNS服务器地址设置为你部署clash的服务器地址。

此种方式为终端设备主动寻求流量接管。

优点是如果服务器宕机,局域网里的其他联网设备不受影响。

缺点是每一个需要接管的设备都需要手动设置,较为麻烦。

3.2 侵入式

手动设置服务器的网关地址为主路由器

vim /etc/network/interfaces

在interfaces里追加下边的参数

auto eth0 iface eth0 inet static address 192.168.199.10 netmask 255.255.255.0 gateway 192.168.199.1

其中address填写你为clash服务器手动设置的地址, gateway填写主路由器地址, reboot。

登录路由器后台,在内网DHCP配置页面,将网关与DNS服务器都设置为clash服务器的IP地址。

这样设置下,由主路由器分发给所有终端设备clash服务器的地址作为网关与dns解析接口

clash服务器处理完数据包之后发送回主路由器,并由主路由器向上送至光猫。

此时网络才是通的,实现的是旁路由的原理。

这种方法将由clash服务器全权接管局域网内的所有流量。

好处是在局域网覆盖范围内只要接入,直接走代理,不需要进行任何设置。

缺点是一旦服务器宕机,整个局域网就瘫痪了。

Tips:

打通整个网络,除了配置要没有错误之外,以下三点要反复确认

docker里的clash在运行状态路由表配置完毕clash服务器网关地址指向主路由器

附录:

我是在Friendlyarm NanoPi M4V2 开发板上刷写armbian操作系统进行的上述操作。

故而理论上所有包括开发板,电视盒之内的能运行Linux系统的设备都可以拿来用。

至于在Docker之外直接在操作系统上部署Clash的文章有很多,不过透明代理的部分依旧可以参考我这篇文章。