前言

Clash 是一款 “人尽皆知” 的代理软件,支持多种代理,多种强大的规则分流,同时支持多种方式部署在网关上。 在闭源的 Premium 内核中支持 tracing 功能,可以方便的采集经过 Clash 核心的流量数据。 本次将抛弃其作为代理软件的作用,使用 Clash 作为网关的上网行为管理监控控制,配合 influxDB + Grafana 展示数据。

部署 Clash

由于需要使用 Clash Premium 闭源内核,因此只能通过托管于 Github 上的 Clash Premium Relase 页面下载。 下面将以 Debian 10 x86 作为例子

wget https://github.com/Dreamacro/clash/releases/download/premium/clash-linux-amd64-2021.05.08.gz
gunzip clash-linux-amd64-2021.05.08.gz
sudo chmod +x clash*
sudo mv clash* /usr/local/bin/clash
sudo mkdir /etc/clash

通过以上的命令可以安装 clash 到系统,并创建配置文件夹 /etc/clash 个人倾向于使用 systemd 作为进程管理器,通过以下命令创建 clash 的 service 文件

sudo cat <<EOF > /etc/systemd/system/clash.service
[Unit]
Description=clash service
After=network.target

[Service]
Type=simple
ExecStart=/usr/local/bin/clash -d /etc/clash/
#ExecStartPost=
#ExecStopPost=
ExecReload=curl -X PUT -d '{"PATH": "/etc/clash/config.yaml", "force": true}' http://127.0.0.1:8080/configs
Restart=on-failure
LimitCORE=infinity
LimitNOFILE=500000
LimitNPROC=500000

[Install]
WantedBy=multi-user.target
EOF
sudo systemctl daemon-reload
sudo systemctl start clash

clash 在启动后会自动在配置文件夹创建 config.yaml Country.mmdb

cat /etc/clash/config.yaml

执行下面命令会发现配置文件仅有一行就可以运行了

mixed-port: 7890

当然,我们要将 clash 作为网关当然不能只有这一行,执行下面的命令写入必要的内容至配置文件


20220410 Clash Premium 更新 新增了 Linux 下的 auto-routeauto-detect-interface

20220417 Clash Premium 更新 为 Linux 新增了 ebpf moudle 下的 redirect-to-tun

已添加在下面的配置实例中,可按需取消注释

*注意新版本中的 auto-route 会默认劫持本机及所有通过本机的流量,如果有任何问题可按采用旧方案

update 20220513


sudo cat <<EOF > /etc/clash/config.yaml
external-controller: 0.0.0.0:8080
#external-ui: ui
#mixed-port: 7890
#redir-port: 7892
allow-lan: true
mode: Rule
log-level: info
ipv6: false
experimental:
  ignore-resolve-fail: true
profile:
  # open tracing exporter API
  tracing: true
tun: 
  enable: true
#  auto-route: true # 20220410 新增 Linux 支持 , Updata 20220513
#  auto-detect-interface: true # 20220410 新增 Linux 支持 , Updata 20220513
  stack: system
# ebpf: # 20220410 为 Linux 新增 ebpf 支持 , Updata 20220513
#  redirect-to-tun:
#    - eth0 # 确定网卡为机器的出口网卡

dns: 
  enable: true # set true to enable dns (default is false)
  ipv6: false # default is false
  listen: 0.0.0.0:23453
  enhanced-mode: redir-host
  nameserver:
    - 119.29.29.29
    - 223.5.5.5
  fallback:
    - https://1.0.0.1/dns-query
    - https://8.8.4.4/dns-query
    - tls://8.8.8.8:853
    - tls://1.0.0.1:853
EOF
sudo systemctl restart clash

需要注意的是上面的 DNS 配置仅供参考,这里的配置会显著影响你的上网体验。同时 listen: 0.0.0.0:23453 中的 23453 仅当局域网内存在如 AdGuardHome 等自建 DNS 服务端时,避免冲突。自建 DNS 服务端可以修改上游 DNS 有且仅有为 <clash-ip>:23453 即可与 clash 一起使用。当然也可以直接将 clash 作为 DNS 服务端,具体可修改端口为 53 或观看配置文档使用 DNS-Hijack 功能。

其中 profile dns 为必须项,本次使用 Tun 模式来接收局域网的流量因此 tun 项也是必须项。 启用 Tun 模式,clash 会创建名为 utun 的虚拟网卡,并自动添加 198.18.0.1/24 作为网卡配置,因此只需将来自局域网的流量路由至 utun 即可。

sudo echo "net.ipv4.ip_forward=1" >> /etc/sysctl.conf
sudo sysctl -p

执行上面的命令开启本机的路由转发


如果选择启用 auto-route 请不要执行以下的命令,避免出现意想不到的问题

update 20220513


IFACE=`ip route get 1 | awk '{print $5;exit}'`
IPCIDR=`ip addr show $IFACE | grep inet | grep -v inet6 | awk '{print $2;exit}'`
IP=`ip route get 1 | awk '{print $7;exit}'`
sudo cat <<EOF > /etc/clash/start.sh
#!/bin/bash
sleep 1
iptables -t nat -A POSTROUTING -o $IFACE -j MASQUERADE
#ip link set dev utun up
ip route add default via 198.18.0.1 dev utun table 200
ip -6 route add default dev utun table 200
ip rule add from $IP lookup main prio 5995
ip rule add to $IPCIDR lookup main prio 5996
ip rule add from $IPCIDR lookup 200 prio 5997
EOF

sudo cat <<EOF > /etc/clash/stop.sh
#!/bin/bash
sleep 1
iptables -t nat -D POSTROUTING -o $IFACE -j MASQUERADE
#ip link set dev utun down
ip route del default via 198.18.0.1 dev utun table 200
ip -6 route del default dev utun table 200
ip rule del prio 5995
ip rule del prio 5996
ip rule del prio 5997
EOF

sudo chmod 744 /etc/clash/start.sh
sudo chmod 744 /etc/clash/stop.sh
sudo sed -i "s/#ExecStartPost=/ExecStartPost=+\/etc\/clash\/start.sh/g" /etc/systemd/system/clash.service
sudo sed -i "s/#ExecStopPost=/ExecStopPost=+\/etc\/clash\/stop.sh/g" /etc/systemd/system/clash.service
sudo systemctl daemon-reload

上面的命令将会开启本机的路由转发并识别本机 eth0 对应的网段,路由网段内的流量至 clash 核心,并且会排除来自本机的流量避免回环,如有本机代理需求可尝试使用 HTTP 代理或是采用 cgroup 等方式排除来自 clash 核心的流量。

到这里只需将局域网内其他设备的网关及 DNS 修改为 clash 所在 IP 即可将 clash 作为网关使用,你可以发挥你的想象力完成这个步骤,当然直接手动修改设备网络配置是最简单粗暴的… 如果是修改 DHCP 的话,要确保 clash 所在系统指向的网关为下一跳路由而不是它自己…

部署 Clash-tracing

Clash-tracing 的项目主页 给出的部署命令是采用 Docker-Compose 部署,考虑到之后的 influxDB 及 Grafana 本次还是用 Docker 部署,当然你也可以直接直接部署到系统内…

安装 Docker 及 Docker-Compose

以下的按照指令在大陆地区可能会出现连接不畅的问题,如果不能顺利安装请自行搜索可行的安装方法。 参考 Docker 官方安装教程安装必要的依赖…

sudo apt update
sudo apt install -y apt-transport-https ca-certificates curl gnupg lsb-release

添加来自 Docker 官方的 GPG Key

curl -fsSL https://download.docker.com/linux/debian/gpg | sudo gpg --dearmor -o /usr/share/keyrings/docker-archive-keyring.gpg

然后添加 x86 架构的 stable repo,如果不是 x86 请执行对应的命令

echo \
"deb [arch=amd64 signed-by=/usr/share/keyrings/docker-archive-keyring.gpg] https://download.docker.com/linux/debian \
$(lsb_release -cs) stable" | sudo tee /etc/apt/sources.list.d/docker.list > /dev/null

然后就可以安装 Docker 了

sudo apt update
sudo apt install -y docker-ce docker-ce-cli containerd.io

然后就可以安装 Docker-Compose 了 还是根据 Docker 的官方安装教程,需要提出的是这里提供的命令安装的版本是 1.29 ,可能因为时间已经过时

sudo curl -L "https://github.com/docker/compose/releases/download/1.29.2/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose
sudo chmod +x /usr/local/bin/docker-compose
sudo ln -s /usr/local/bin/docker-compose /usr/bin/docker-compose
docker-compose --version

如果一切顺利那么到这里 Docker 及 Docker-Compose 就按照完成了。

开始安装 Clash-tracing 及部署 influxDB 和 Grafana


20220210 clash-tracing 新版本更新,从 influxDB 切换至 Loki

Update 20220513


首先,需要来到一个可用硬盘空间足够大的文件夹,因为 influxDB 也会放在这里,随着时间的推移数据库的占用会越来越大。 确保来到一个可用硬盘空间不小的文件夹,开始拉取 clash-tracing 的项目文件

sudo git clone https://github.com/Dreamacro/clash-tracing.git

然后,需要修改 docker-compose.yml 内与 clash 核心对接的配置,由于那么安装之前的配置,执行下面的命令即可

cd clash-tracing
IP=`ip route get 1 | awk '{print $7;exit}'`
sed -i "s/192.168.88.201:9090/$IP:8080/g" docker-compose.yml

需要说明的是,部署时可能会需要畅通的网络以拉取 Docker 镜像及编译所需的开发库,如果你的网络不佳,可能需要提前解决。 进入项目目录,开始部署

docker-compose up -d

这里可能会出现因为内存不足导致的编译失败,通过临时添加 Swap 并重新执行可以解决

# 开启 2G 大小的 Swap
sudo dd if=/dev/zero of=/root/swapfile bs=1M count=2048
sudo mkswap /root/swapfile
sudo swapon /root/swapfile

# 删除新增的 2G Swap
sudo swapoff /root/swapfile
sudo rm -f /root/swapfile

取决于网路状况可能会需要一些时间,等待完成后执行

docekr ps

应该就可以看到三个容器都已经启动成功了


切换到 Loki 后这里可能会出现 Loki 启动失败的情况,原因是目录权限与所有者不符

执行 chown -R 10001:10001 ./loki/data 修改 loki 数据目录权限

Update 20220513


CONTAINER ID   IMAGE                   COMMAND                  CREATED         STATUS         PORTS                                       NAMES
7cb81addfd11   clash-tracing_scraper   "/scraper"               5 seconds ago   Up 2 seconds                                               scraper
d12b0702cbfc   grafana/grafana         "/run.sh"                5 seconds ago   Up 2 seconds   0.0.0.0:3000->3000/tcp, :::3000->3000/tcp   grafana
17de091d79d4   influxdb:1.8-alpine     "/entrypoint.sh infl…"   5 seconds ago   Up 2 seconds   8086/tcp                                    influxdb

如果你是在 root 权限的文件夹执行部署的,那么 Grafana 可能会无法启动,原因是 Grafana Docker 镜像内默认是以 User(472) Group(0) 的用户和组运行的,在 root 用户和组下的文件夹会出现无权限的情况。 这里给出一个解决方案,在 docekr-compose.yml 文件中对应部分增加一行使得 Grafana 容器以 root 用户运行即可,但是会有潜在安全问题,请慎重考虑执行。(即不要在公网运行,或者不要将 3000 端口暴露于公网上)

···
grafana:
    image: grafana/grafana
    volumes:
      - ./grafana:/var/lib/grafana
    ports:
      - "3000:3000"
    user: "0" # 新增的部分
    container_name: grafana
···

之后执行一下命令,重新创建 Grafana 容器即可。

docker rm -f grafana
docker-compose up -d

至此,全部就算部署完毕了,influxDB 的相关数据库文件存放在 clash-tracing/data 内,Grafana 的相关配置文件存放在 clash-tracing/grafana


Loki 的相关数据库文件存放在 clash-tracing/loki/data

Update 20220513


配置 Grafana 及导入 Clash-tracing Dashboard


20220210 切换至 Loki 后需要选择 Logging & document database 下的 Loki

配置中的 http://influxdb:8086 也需要替换为 http://loki:3100,底下的 User Password 等无需填写

Update 20220513


在浏览器输入 <ip>:3000 进入 Grafana 的网页端,默认账号及密码均为 admin 更改默认密码后即可进入控制页面,点击左侧 Configuration-Data Sources,新建 influxDB 数据源。 按下图输入对应内容 点击左侧 Create-Import 输入 https://github.com/Dreamacro/clash-tracing/raw/master/grafana.json 中的内容以导入模板(没错这个模板来自 clash 项目。

最后结果如下图所示

进阶(不是

如果完整的执行了前面的内容,并且没有出现什么问题,那么 clash 应该已经能够正常的接管所有经过所在机器的来自局域网内的流量了,同样的 tracing 也能展示对应的数据了。

那么就可以运用 clash 的核心功能——基于规则的路由功能,对流经的数据进行“精细”的控制。

由于使用的是 clash 项目的闭源 Premium 内核,因此可以利用一些特有的功能。 首先还是要了解一下 clash 的配置文件 config.yaml

port: 7890                            # HTTP 端口
socks-port: 7891                      # SOCKS 端口
redir-port: 7892                      # Redir 端口
tproxy-port: 7893                     # TPROXY 端口
mixed-port: 7890                      # 混合 HTTP SOCKS 端口
authentication:                       # HTTP SOCKS 端口 鉴权
allow-lan: false                      # 是否允许来自局域网的 IP 
bind-address: '*'                     # 在 Allow-Lan 为 True 的情况下,监听绑定的 IP
mode: rule                            # 模式,direct global rule  script
log-level: info                       # 日志输出级别
ipv6: false
external-controller: 127.0.0.1:9090   # RESTful web API
external-ui: folder                   # ...
interface-name: en0                   # 指定的上游网卡
hosts:                                # ...
profile:                              # ...
tun:                                  # Tun 配置
ebpf:                                 # Linux ebpf 配置 # Update 20220513
dns:                                  # DNS 配置
proxies: 
proxy-groups:
proxy-providers:
rule-providers:
script:
rules:

可以看到,在之前的写入的配置文件中没有写入代理代理组规则等模块,所以默认经过 clash 的所有流量都会被直接放行,没有做任何处理。

clash 默认包含两个代理

DIRECT: directly connects to the target without any proxies involved

REJECT: a black hole for packets. Clash will not process any I/O to this policy.

因此,可以在 rules 模块中添加一些简单的规则如:

rules:
  - DOMAIN-SUFFIX,pornhub.com,REJECT
  - MATCH,DIRECT

这样就能阻止经过 clash 的流量流向以 pornhub.com 结尾的域名,从而封锁对应的网站。 类似的更多 rules 规则可以查看 clash 的官方文档

修改完成之后可以执行 sudo systemctl reload clash 使得 clash 重新加载配置文件而不至于重新启动

未完待续