0

树莓派 C

 2 years ago
source link: https://mritd.com/2022/02/06/clash-tproxy/
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

一、注意事项

本文中内网 CIDR 为 192.168.0.0/16, 即所有地址段规则、配置都是针对当前内网 CIDR 进行处理的; clash fake-ip 的 CIDR 为 198.18.0.0/16, 请不要写错成 192, 这是 198(也不要问我为什么强调).

二、安装 Clash

本文所采用的透明代理方式不依赖于 TUN, 所有是否是增强版本不重要, 如果可以请尽量使用最新版本.

# x86 用户请自行替换
wget https://github.com/Dreamacro/clash/releases/download/v1.9.0/clash-linux-armv8-v1.9.0.gz

# 解压
gzip -d clash-linux-armv8-v1.9.0.gz

# 安装到系统 PATH
chmod +x clash-linux-armv8-v1.9.0
mv clash-linux-armv8-v1.9.0 /usr/bin/clash

创建专用的 clash 用户:

useradd -M -s /usr/sbin/nologin clash

编写 Systemd 配置文件:

cat > /lib/systemd/system/clash.service <<EOF
[Unit]
Description=Clash TProxy
After=network.target

[Service]
Type=simple
User=clash
Group=clash
CapabilityBoundingSet=CAP_NET_ADMIN CAP_NET_BIND_SERVICE CAP_NET_RAW
AmbientCapabilities=CAP_NET_ADMIN CAP_NET_BIND_SERVICE CAP_NET_RAW
Restart=on-failure

ExecStartPre=+/usr/bin/bash /etc/clash/clean.sh
ExecStart=/usr/bin/clash -d /etc/clash
ExecStartPost=+/usr/bin/bash /etc/clash/iptables.sh

ExecStopPost=+/usr/bin/bash /etc/clash/clean.sh

[Install]
WantedBy=multi-user.target
EOF

三、调整配置

本文中 Clash 配置文件、脚本等统一存放到 /etc/clash 目录中, 针对于 Clash 配置文件, 着重说明重点配置, 完整配置请从官方 Wiki 复制: https://github.com/Dreamacro/clash/wiki/configuration#all-configuration-options

3.1、端口配置

端口配置请尽量保持默认, 如果需要调整端口, 请同步修改后面相关脚本中的端口(TProxy):

# 注释掉 port 端口配置, 使用 mixed-port
#port: 7890

# 注释掉 socks-port 端口配置, 使用 mixed-port
#socks-port: 7891

# 注释掉 redir-port 端口配置, 因为全部采用 TProxy 模式
#redir-port: 7892

# TProxy 的透明代理端口
tproxy-port: 7893

# mixed-port 端口将同时支持 SOCKS5/HTTP
mixed-port: 7890

# 允许来自局域网的连接
allow-lan: true

# 绑定到所有接口
bind-address: '*'

3.2、DNS 配置

Clash 配置中请开启 DNS, 并使用 fake-ip 模式, 样例配置如下:

dns:
  enable: true
  listen: 0.0.0.0:1053
  ipv6: false
  default-nameserver:
    - 114.114.114.114
    - 8.8.8.8
  enhanced-mode: fake-ip

3.3、防火墙规则

为了保证防火墙规则不被破坏, 本文采用脚本暴力操作, 如果宿主机有其他 iptables 控制程序, 则推荐手动执行并通过 iptables-persistent 等工具进行持久化;

/etc/clash/iptables.sh: 负责启动时添加 iptables 规则

#!/usr/bin/env bash

set -ex

# ENABLE ipv4 forward
sysctl -w net.ipv4.ip_forward=1

# ROUTE RULES
ip rule add fwmark 666 lookup 666
ip route add local 0.0.0.0/0 dev lo table 666

# clash 链负责处理转发流量 
iptables -t mangle -N clash

# 目标地址为局域网或保留地址的流量跳过处理
# 保留地址参考: https://zh.wikipedia.org/wiki/%E5%B7%B2%E5%88%86%E9%85%8D%E7%9A%84/8_IPv4%E5%9C%B0%E5%9D%80%E5%9D%97%E5%88%97%E8%A1%A8
iptables -t mangle -A clash -d 0.0.0.0/8 -j RETURN
iptables -t mangle -A clash -d 127.0.0.0/8 -j RETURN
iptables -t mangle -A clash -d 10.0.0.0/8 -j RETURN
iptables -t mangle -A clash -d 172.16.0.0/12 -j RETURN
iptables -t mangle -A clash -d 192.168.0.0/16 -j RETURN
iptables -t mangle -A clash -d 169.254.0.0/16 -j RETURN

iptables -t mangle -A clash -d 224.0.0.0/4 -j RETURN
iptables -t mangle -A clash -d 240.0.0.0/4 -j RETURN

# 其他所有流量转向到 7893 端口,并打上 mark
iptables -t mangle -A clash -p tcp -j TPROXY --on-port 7893 --tproxy-mark 666
iptables -t mangle -A clash -p udp -j TPROXY --on-port 7893 --tproxy-mark 666

# 转发所有 DNS 查询到 1053 端口
# 此操作会导致所有 DNS 请求全部返回虚假 IP(fake ip 198.18.0.1/16)
iptables -t nat -I PREROUTING -p udp --dport 53 -j REDIRECT --to 1053

# 如果想要 dig 等命令可用, 可以只处理 DNS SERVER 设置为当前内网的 DNS 请求
#iptables -t nat -I PREROUTING -p udp --dport 53 -d 192.168.0.0/16 -j REDIRECT --to 1053

# 最后让所有流量通过 clash 链进行处理
iptables -t mangle -A PREROUTING -j clash

# clash_local 链负责处理网关本身发出的流量
iptables -t mangle -N clash_local

# nerdctl 容器流量重新路由
#iptables -t mangle -A clash_local -i nerdctl2 -p udp -j MARK --set-mark 666
#iptables -t mangle -A clash_local -i nerdctl2 -p tcp -j MARK --set-mark 666

# 跳过内网流量
iptables -t mangle -A clash_local -d 0.0.0.0/8 -j RETURN
iptables -t mangle -A clash_local -d 127.0.0.0/8 -j RETURN
iptables -t mangle -A clash_local -d 10.0.0.0/8 -j RETURN
iptables -t mangle -A clash_local -d 172.16.0.0/12 -j RETURN
iptables -t mangle -A clash_local -d 192.168.0.0/16 -j RETURN
iptables -t mangle -A clash_local -d 169.254.0.0/16 -j RETURN

iptables -t mangle -A clash_local -d 224.0.0.0/4 -j RETURN
iptables -t mangle -A clash_local -d 240.0.0.0/4 -j RETURN

# 为本机发出的流量打 mark
iptables -t mangle -A clash_local -p tcp -j MARK --set-mark 666
iptables -t mangle -A clash_local -p udp -j MARK --set-mark 666

# 跳过 clash 程序本身发出的流量, 防止死循环(clash 程序需要使用 "clash" 用户启动) 
iptables -t mangle -A OUTPUT -p tcp -m owner --uid-owner clash -j RETURN
iptables -t mangle -A OUTPUT -p udp -m owner --uid-owner clash -j RETURN

# 让本机发出的流量跳转到 clash_local
# clash_local 链会为本机流量打 mark, 打过 mark 的流量会重新回到 PREROUTING 上
iptables -t mangle -A OUTPUT -j clash_local

# 修复 ICMP(ping)
# 这并不能保证 ping 结果有效(clash 等不支持转发 ICMP), 只是让它有返回结果而已
# --to-destination 设置为一个可达的地址即可
sysctl -w net.ipv4.conf.all.route_localnet=1
iptables -t nat -A PREROUTING -p icmp -d 198.18.0.0/16 -j DNAT --to-destination 127.0.0.1

/etc/clash/clean.sh: 负责启动前/停止后清理 iptables 规则(暴力清理)

#!/usr/bin/env bash

set -ex

ip rule del fwmark 666 table 666 || true
ip route del local 0.0.0.0/0 dev lo table 666 || true

iptables -t nat -F
iptables -t nat -X
iptables -t mangle -F
iptables -t mangle -X clash || true
iptables -t mangle -X clash_local || true

3.4、最终目录结构

所有配置编写完成后, 其目录结构如下:

root@openrpi # ❯❯❯ tree -L 1 /etc/clash
/etc/clash
├── clean.sh
├── config.yaml
└── iptables.sh

最后需要修复 /etc/clash 目录权限, 因为 Clash 启动后会写入其他文件:

chown -R clash:clash /etc/clash

四、启动及测试

如果所有配置和文件安装没问题的话, 可以直接通过 Systemd 启动:

# 启动
systemctl start clash

# 查看日志
jouranlctl -fu clash

如果启动成功, 那么此时内网设备将网关设置到当前 Clash 所在机器即可完成透明代理; 如果 Clash 机器足够稳定, 也可以一步到位将内网路由器的 DHCP 设置中下发的网关直接填写为 Clash 机器 IP(Clash 机器需要使用静态 IP).


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK