clashindocker
clashindocker copied to clipboard
Using docker to run clash as a bypass route
使用clash作为旁路由
提供了两种方式,一种是使用docker+macvlan+iptables,另一种是使用clash的tun模式.两种方式各有优缺点,可以根据自己的需求选择.
| 方式 | 优点 | 缺点 |
|---|---|---|
| docker+macvlan+iptables | 1. 对系统入侵性小 2. 便于迁移 |
1. 根据网友的热心提示,只能代理TCP 2. 宿主机的流量没有经过代理 |
| clash tun模式 | 代理所有流量(TCP+UDP) | 在本地会生成一些配置文件但是在指定位置 |
以下方法仅在X86设备上测试过,其他设备请自行测试.
推荐使用方式二,对IPV6的配制更好,并且方便宿主机的网络代理.
虽然项目名字写着在docker中使用clash,但是最近发现使用systemd直接运行clash使用tun的方式更加实用.
方式一: docker+macvlan+iptables
前言
软路由,openwrt,是老生常谈的内容了。但是我更加喜欢all in one,而且不喜欢用虚拟机。每次装openwrt的主要目的也只是使用其中的clash。所以我就干脆直接用docker+clash来充当软路由的功能了。其中使用到的主要工具是docker,macvlan,clash(mihomo),iptables.
创建macvlan网络
为了能够让docker启动的容器作为家庭网络中的旁路由,因此需要创建macvlan网络。
其中192.168.3.1为你局域网的网关,em1为你机器的网卡名称,这两个请根据实际情况修改。
- (可选)让docker监听ipv6。 编辑etc/docker/daemon.json文件
{
"ipv6": true,
"fixed-cidr-v6": "2409:DA8:8001:7B22:200::/80"
}
重启docker
sudo systemctl restart docker
- 创建macvlan 没有ipv6的版本
docker network create -d macvlan \
--subnet=192.168.3.0/24 \
--gateway=192.168.3.1 \
-o parent=em1 \
-o macvlan_mode=bridge macnet
有ipv6的版本
docker network create -d macvlan --ipv6 \
--subnet=192.168.3.0/24 \
--gateway=192.168.3.1 \
--subnet=2409:DA8:8001:7B22:200::/80
--gateway=2409:DA8:8001:7B22:200::1 \
-o parent=em1 \
-o macvlan_mode=bridge macnet
注意看含义,有的值需要变
制作docker镜像并创建容器
- 获取代码
git clone https://github.com/UntaggedRui/clashindocker
cd clashindocker
cp example.yml config.yml
-
更改地址
docker-compose.yml中的ipv4_address为你的ip地址. -
更改
config.yml中的proxy-provider的url为你的机场订阅地址. -
启动容器
docker compose up -d
-
假设你的docker容器ip地址为
192.168.3.23. 通过http://192.168.3.23:9090/ui/可以管理clash,进行切换节点等.后端地址为http://192.168.3.23:9090/,密码为yourpassword. -
在同一个局域网下,将其他机器的网关设置为
192.168.3.23就可以实现该机器的所有流量都经过clash,并且根据clash的规则进行分流. -
可以不看的说明. example.yml中使用
proxy-provider和rule-providers来实现远端配置. 示例中是两个机场的情况.如果只有一个机场,删除其中一个和下面proxy-groups对应的部分即可.这个配置文件中需要注意以下几点.
-
配置
redir-port来让clash能够处理请求.redir-port: 7892 -
配置web管理配合metacubexd来进行网页管理.
external-controller: '0.0.0.0:9090' external-ui: ui # RESTful API 的口令 secret: 'yourpassword'
- 可以通过web界面更新内核,使用clash(mihomo_alpha)的最新版本.

如果有无法使用的欢迎在issue中讨论.
方式二: clash tun模式
前言
根据热心网友的提示,方式一的操作只能代理 TCP.并且clash本来就是单独的二进制文件,没有依赖,产生的额外文件也可控,所以可以不用使用docker进行隔离.因此这里介绍一种使用clash tun模式来做旁路由的模式.
准备工作
-
获取代码
git clone https://github.com/UntaggedRui/clashindocker cd clashindocker cp example.yml config.yml -
更改
config.yml中的配置. 开启tun模式,将tun的enable设置为true(第95行). 设置proxy-provider的url为你的机场订阅地址. -
将clash注册为系统服务方便管理. 修改
clash.service中的WorkingDirectory和ExecStart中的路径,指向正确的位置.然后将clash.service放到/lib/systemd/system/中.然后执行如下指定,设置clash开机自启,并立即起动服务.sudo systemctl enable clash --now对于启动和关闭与常规的服务方式一样.
sudo systemctl start clash sudo systemctl stop clash sudo systemctl restart clash -
查看clash的运行状态,此时本机流量应该是通过clash代理的.
sudo journalctl -u clash -f -
在同一个局域网下,将其他机器的网关设置为你的机器的ip地址就可以实现该机器的所有流量都经过clash,并且根据clash的规则进行分流. 为了让DNS劫持生效,设备的DNS不能设置为局域网地址,需要是公网地址或者198.18.0.1,详见官方的描述:
Since tun.auto-route does not intercept LAN traffic, if your system DNS is set to servers in private subnets, DNS hijack will not work. You can either:
- Use a non-private DNS server as your system DNS like 1.1.1.1
- Or manually set up your system DNS to the Clash DNS (by default, 198.18.0.1)
关于DNS的配置参考了这篇文章.
- 如果其他机器能够正常上网就万事大吉不用管下面的了.如果无法上网,可能是由于iptables的原因,可以执行如下命令,开启转发.
sudo iptables -P FORWARD ACCEPT
如果能够正常上网就万事大吉不用管下面的了.如果还不行再加上这句试试.
sudo iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE
我不会iptables这个东西,很难受.
- 内核更新参考方式一中的第8步.