Skip to content

Instantly share code, notes, and snippets.

@cld4h
Last active November 26, 2024 10:41
Show Gist options
  • Save cld4h/9a03ec2f826a25be5ab974fdbc540de4 to your computer and use it in GitHub Desktop.
Save cld4h/9a03ec2f826a25be5ab974fdbc540de4 to your computer and use it in GitHub Desktop.
Bypass the GFW; clash fake-ip and tproxy; iptables and transparent proxy on Linux; 在Linux上通过 iptables 以及 clash 配置透明代理用于本机及局域网翻墙网关; Linux 翻墙路由器配置

This article show you the ultimate way to set up a transparent proxy on Linux using clash and iptables to bypass the GFW in China.

We use:

You can go to github gist to download all files mentioned in this article.

All files you need:

.
├── clash-base-config.yaml  ---🟢base config for clash to work on tproxy and fake-ip mode
├── clash.service           ---🟢systemd unit file to start up clash
├── clean.sh                ---🟢script to clean iptables
├── config.ini              ---🟢config file for subconverter
├── iptables.sh             ---🟢iptables config file
├── update-config.sh        ---🟡subscription update script; "XXXXXXXX" need to be replaced
├── config.yaml             ---⭕clash config file, to be generated from update-config.sh
├── README.md
└── README.zh-cn.md

🟢: Doesn't need to change
🟡: Needs to change
⭕: Needs to be generated

Reference

clash-tproxy

Transparent proxy demo code

Prerequisite

  • a clash installed. (By default in /usr/bin/clash)
  • iptables
  • systemd (It's totally fine to use other init programs, but here I'll only show the configuration of systemd, which is the default of most GNU/Linux distros.)
  • crontab

Steps

Create a system user called clash

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

Since we want to proxy all internet traffics, we need to prevent the traffic from looping. Thus, we create a distinct user called clash (the name can be arbitrary) to run the proxy software clash. We'll make an iptables rule in the following steps to distinguish traffic coming from the user clash.

Create iptables and routing rules

Create a shell script of iptables command called /etc/clash/iptables.sh.

The file contains 3 main sections:

  1. iptables rules to hijack the dns query traffic,
  2. config for clash chain
  3. config for clash_local chain

iptables:

┌─────────┐                                                                                      ┌─────────┐
│         │             PREROUTING                                                INPUT          │         │
│         │                                                                                      │         │
│         │  ┌─────────────────────────────────────┐                      ┌────────────────────┐ │         │
│         │  │                                     │         /───\        │                    │ │         │
│         │  │ ┌───┐  ┌─────────┐  ┌──────┐  ┌───┐ │        /     \       │ ┌──────┐  ┌──────┐ │ │         │
│         ├──┤►│raw├─►│conntrack├─►│mangle├─►│nat├─┼──────►<routing>──────┤►│mangle├─►│filter├─┤►│         │
│         │  │ └───┘  └─────────┘  └──────┘  └───┘ │        \     /       │ └──────┘  └──────┘ │ │         │
│         │  │                                     │         \─┬─/        │                    │ │         │
│         │  └─────────────────────────────────────┘           │          └────────────────────┘ │         │
│         │                                                    │                                 │         │
│         │                               ┌──────────┐         │                                 │         │
│         │                               │          │         │                                 │         │
│         │                               │ ┌──────┐ │         │                                 │         │
│         │                               │ │mangle◄─┼─────────┘                                 │         │
│ Network │                               │ └──┬───┘ │                                           │  Local  │
│Interface│                               │    │     │ FORWARD                                   │ Process │
│         │                               │ ┌──▼───┐ │                                  /───\    │         │
│         │               ┌───────────────┼─┤filter│ │                                 /     \   │         │
│         │               │               │ └──────┘ │                                <routing>◄─┤         │
│         │               │               │          │                                 \     /   │         │
│         │               │               └──────────┘                                  \─┬─/    │         │
│         │               │                                                               │      │         │
│         │  ┌────────────┼────┐               ┌──────────────────────────────────────────┼────┐ │         │
│         │  │            │    │     ─────     │                                          │    │ │         │
│         │  │ ┌───┐  ┌───▼──┐ │    /     \    │ ┌──────┐  ┌───┐  ┌──────┐  ┌─────────┐  ┌▼──┐ │ │         │
│         │◄─┼─┤nat│◄─┤mangle│◄├───<reroute>───┼─┤filter│◄─┤nat│◄─┤mangle│◄─┤conntrack│◄─┤raw│ │ │         │
│         │  │ └───┘  └──────┘ │    \check/    │ └──────┘  └───┘  └──────┘  └─────────┘  └───┘ │ │         │
│         │  │                 │     ─────     │                                               │ │         │
│         │  └─────────────────┘               └───────────────────────────────────────────────┘ │         │
│         │     POSTROUTING                                        OUTPUT                        │         │
│         │                                                                                      │         │
└─────────┘                                                                                      └─────────┘

/etc/clash/iptables.sh

#!/usr/bin/env bash

# set -ex options:
# -e Exit immediately if a command exits with a non-zero status
# -x Print commands and their arguments as they are executed.
set -ex

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

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

##################################
## hijack the dns query traffic ##
##################################

# Redirect all dns query traffic from LAN to port 1053
# Later clash will return a fake ip in 198.18.0.1/16
iptables -t nat -I PREROUTING -p udp --dport 53 -j REDIRECT --to 1053
# same for ipv6
ip6tables -t nat -I PREROUTING -p udp --dport 53 -j REDIRECT --to 1053


# Redirect dns query traffic from all local processes (except owned by user clash) to port 1053
# Later clash will return a fake ip in 198.18.0.1/16
iptables -t nat -N clash_dns
iptables -t nat -A OUTPUT -p udp --dport 53 -j clash_dns
iptables -t nat -A clash_dns -m owner --uid-owner clash -j RETURN
iptables -t nat -A clash_dns -p udp -j REDIRECT --to-ports 1053
# same for ipv6
ip6tables -t nat -N clash_dns
ip6tables -t nat -A OUTPUT -p udp --dport 53 -j clash_dns
ip6tables -t nat -A clash_dns -m owner --uid-owner clash -j RETURN
ip6tables -t nat -A clash_dns -p udp -j REDIRECT --to-ports 1053

##############################
## config for `clash` chain ##
##############################

# `clash` chain for using tproxy to redirect traffic to the clash listening port 7893
iptables -t mangle -N clash

# skip traffic to LAN or reserved address
# reference:
# https://en.wikipedia.org/wiki/List_of_assigned_/8_IPv4_address_blocks
# https://en.wikipedia.org/wiki/Private_network#IPv4
# IANA - Local Identification
iptables -t mangle -A clash -d 0.0.0.0/8 -j RETURN
# IANA - Loopback
iptables -t mangle -A clash -d 127.0.0.0/8 -j RETURN
# IANA - Private Use
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
# IPv4 Link-Local Addresses
iptables -t mangle -A clash -d 169.254.0.0/16 -j RETURN
# Multicast
iptables -t mangle -A clash -d 224.0.0.0/4 -j RETURN
# Future Use
iptables -t mangle -A clash -d 240.0.0.0/4 -j RETURN

# Forward all the other traffic to port 7893 and set tproxy 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

# Append the `clash` chain to PREROUTING to enable it
iptables -t mangle -A PREROUTING -j clash

####################################
## config for `clash_local` chain ##
####################################

# `clash_local` chain to manipulate the traffic from local process: set fwmark 666 on traffic to public address
# (which will later reroute to dev lo, then redirect to tproxy port 7893 on the `clash` chain of `PREROUTING`)
iptables -t mangle -N clash_local

# rerouting traffic from nerdctl container
#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

# Don't touch traffic to LAN and reserved address 
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

# set mark for local traffic
# clash_local set mark for the traffic from local process,
# the marked traffic will come back to PREROUTING chain.
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

# Don't touch traffic from a serving port
# https web server
# iptables -t mangle -I OUTPUT -p tcp --sport 443 -j RETURN
# transmission
# iptables -t mangle -I OUTPUT -p tcp --sport 51413 -j RETURN

# Don't touch traffic from the user `clash` to prevent looping
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

# Append the `clash_local` chain to OUTPUT to enable it
iptables -t mangle -A OUTPUT -j clash_local

#######################
## unimportant staff ##
#######################

# fix ICMP(ping)
# This step does NOT make the ping result validate 
# (clash doesn't support forwarding ICMP), it just makes ping have a result.
# set --to-destination to a accessable address.
#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
#iptables -t nat -A OUTPUT -p icmp -d 198.18.0.0/16 -j DNAT --to-destination 127.0.0.1

After applying the script above, the system iptables should be like this:

┌─────────┐                                                                                      ┌─────────┐
│         │             PREROUTING           rule1*                               INPUT          │         │
│         │                                    │                                                 │         │
│         │  ┌─────────────────────────────────┼───┐                      ┌────────────────────┐ │         │
│         │  │                                 │   │         /───\        │                    │ │         │
│         │  │ ┌───┐  ┌─────────┐  ┌──────┐  ┌─┴─┐ │        /     \       │ ┌──────┐  ┌──────┐ │ │         │
│         ├──┤►│raw├─►│conntrack├─►│mangle├─►│nat├─┼──────►<routing>──────┤►│mangle├─►│filter├─┤►│         │
│         │  │ └───┘  └─────────┘  └┬─────┘  └───┘ │        \     /       │ └──────┘  └──────┘ │ │         │
│         │  │                      │              │         \─┬─/        │                    │ │         │
│         │  └──────────────────────┼──────────────┘           │          └────────────────────┘ │         │
│         │                         │                          │                                 │         │
│         │                      ┌──┴──┐  ┌──────────┐         │                                 │         │
│         │                      │clash│  │          │         │                                 │         │
│         │                      └─────┘  │ ┌──────┐ │         │                                 │         │
│         │                               │ │mangle◄─┼─────────┘                                 │         │
│ Network │                               │ └──┬───┘ │              ┌───────────┐                │  Local  │
│Interface│                               │    │     │ FORWARD      │clash_local│                │ Process │
│         │                               │ ┌──▼───┐ │              └─┬─────────┘       /───\    │         │
│         │               ┌───────────────┼─┤filter│ │                │                /     \   │         │
│         │               │               │ └──────┘ │                ├───rule3*      <routing>◄─┤         │
│         │               │               │          │                │                \     /   │         │
│         │               │               └──────────┘                ├───rule2*        \─┬─/    │         │
│         │               │                                           │                   │      │         │
│         │  ┌────────────┼────┐               ┌──────────────────────┼───────────────────┼────┐ │         │
│         │  │            │    │     ─────     │                      │                   │    │ │         │
│         │  │ ┌───┐  ┌───▼──┐ │    /     \    │ ┌──────┐  ┌───┐  ┌───┴──┐  ┌─────────┐  ┌▼──┐ │ │         │
│         │◄─┼─┤nat│◄─┤mangle│◄├───<reroute>───┼─┤filter│◄─┤nat│◄─┤mangle│◄─┤conntrack│◄─┤raw│ │ │         │
│         │  │ └───┘  └──────┘ │    \check/    │ └──────┘  └┬──┘  └──────┘  └─────────┘  └───┘ │ │         │
│         │  │                 │     ─────     │            │                                  │ │         │
│         │  └─────────────────┘               └────────────┼──────────────────────────────────┘ │         │
│         │     POSTROUTING                                 │      OUTPUT                        │         │
│         │                                          ┌──────┴──┐                                 │         │
└─────────┘                                          │clash_dns│                                 └─────────┘
                                                     └─────────┘

 *rule1: iptables -t nat -I PREROUTING -p udp --dport 53 -j REDIRECT --to 1053
 *rule2: iptables -t mangle -A OUTPUT -p tcp -m owner --uid-owner clash -j RETURN
 *rule3: iptables -t mangle -A OUTPUT -p udp -m owner --uid-owner clash -j RETURN

It's also worth to take a look at the route rules in iptables.sh:

ip rule add fwmark 666 table 666
ip route add local 0.0.0.0/0 table 666 dev lo

ip rule manipulates rules in the routing policy database control the route selection algorithm.

So here the ip rule command make the kernel to lookup table 666 for packets with fwmark 666

ip rule reference is here.

The ip route command add a default route to device lo on routing table 666.

We can use ip route show table 666 to see the route added by ip route add local 0.0.0.0/0 table 666 dev lo

See the route table value and name mapping: cat /etc/iproute2/rt_tables

Create a cleaning script

Create a shell script to clean the iptables.

-D or --delete:

Delete one or more rules from the selected chain. There are two versions of this command: the rule can be specified as a number in the chain (starting at 1 for the first rule) or a rule to match.

-F or --flush:

Flush the selected chain (all the chains in the table if none is given).
This is equivalent to deleting all the rules one by one.

-X or --delete-chain:

Delete the optional user-defined chain specified. There must be no references to the chain. If there are, you must delete or replace the referring rules before the chain can be deleted. The chain must be empty, i.e. not contain any rules. If no argument is given, it will attempt to delete every non-builtin chain in the table.

#!/usr/bin/env bash

set -ex

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

iptables -t nat -D PREROUTING -p udp --dport 53 -j REDIRECT --to 1053 || true
ip6tables -t nat -D PREROUTING -p udp --dport 53 -j REDIRECT --to 1053 || true
iptables -t nat -D OUTPUT -p udp --dport 53 -j clash_dns || true
ip6tables -t nat -D OUTPUT -p udp --dport 53 -j clash_dns || true
iptables -t nat -F clash_dns || true
iptables -t nat -X clash_dns || true
ip6tables -t nat -F clash_dns || true
ip6tables -t nat -X clash_dns || true
#iptables -t nat -D PREROUTING -p icmp -d 198.18.0.0/16 -j DNAT --to-destination 127.0.0.1
#iptables -t nat -D OUTPUT -p icmp -d 198.18.0.0/16 -j DNAT --to-destination 127.0.0.1

iptables -t mangle -D PREROUTING -j clash || true
iptables -t mangle -F clash || true
iptables -t mangle -X clash || true

iptables -t mangle -D OUTPUT -p tcp -m owner --uid-owner clash -j RETURN || true
iptables -t mangle -D OUTPUT -p udp -m owner --uid-owner clash -j RETURN || true
iptables -t mangle -D OUTPUT -j clash_local || true
iptables -t mangle -F clash_local || true
iptables -t mangle -X clash_local || true

Fixing ping

One major drawback of the fake-ip mode is that you can't ping a fake ip.

The solution above to redirect all ping request to the localhost is "掩耳盗铃", it doesn't provide any useful information.

Sadly, all devices from LAN can't use ping, but fortunately you can alias ping to sudo -u clash ping for this gateway to use ping.

alias ping="sudo -u clash ping"

Provide a systemd unit file to start clash at a single command

This step is optional, but I felt it's extremely convenient to start clash by running a single command.

You can also make clash start at boot time.

The systemd config file is in the appended files with the name clash.service

put it under /usr/lib/systemd/system, and run sudo systemctl start clash to start running clash.

To start it at boot time, run sudo systemctl enable clash.

Configuring clash

Now let's set clash up to work.

Clash use -d option to set configuration directory and -f option to specify configuration file.

The default configuration file name is config.yaml when -f is omitted.

We want to use crontab to periodically update the clash config from a subscription url.

Construct the subscription URL

TL;DR. Just replace XXXXXXXX with your encoded subscription URL .

https://sub.xeton.dev/sub?target=clash&new_name=true&filename=config.yaml&url=XXXXXXXX&config=https%3A%2F%2Fgist.githubusercontent.com%2Fcld4h%2F9a03ec2f826a25be5ab974fdbc540de4%2Fraw%2Fconfig.ini

We use subconverter to generate config file for clash.

You need to change a few parameters in the subscription URL to generate a proper config file for clash to work in fake-ip mode.

To be specific:

  1. the url parameter should be the correct subscription URL and encoded.
  2. Multiple subscription URL should be seperated by |, or %7C after URL Encoding.
  3. the config parameter should point to a correct configuration file. ⚠️

⚠️ NOTICE: the configuration file for subconverter is extremely important!

ACL4SSR project provide a default configuration file for subconverter, it's fine but NOT ENOUGH for clash to work on fake-ip mode.

To make it work, you need specify clash_rule_base by inserting this line to the configuration file for subconverter

clash_rule_base=https://gist.githubusercontent.com/cld4h/9a03ec2f826a25be5ab974fdbc540de4/raw/clash-base-config.yaml

What this line does is that it tells the subconverter to use the file in the url above instead of the default clash base configuration.

Or you can just use the config.ini here

Sample url:

https://sub.xeton.dev/sub?        --- backend address
target=clash                      --- client type
&new_name=true                    --- create a new filename
&filename=config.yaml             --- filename
&url=                             --- Node info
ss%3A%2F%2FYmYtY2ZiOnRlc3QvIUAjOkAxOTIuMTY4LjEwMC4xOjg4ODg%23example-server
%7C                               --- the delimiter | to seperate multiple urls
ss%3A%2F%2FYmYtY2ZiOnRlc3QvIUAjOkAxOTIuMTY4LjEwMC4xOjg4ODg%23example-server-2
&config=                          --- config file for subconverter; .ini format
https%3A%2F%2Fgist.githubusercontent.com%2Fcld4h%2F9a03ec2f826a25be5ab974fdbc540de4%2Fraw%2Fconfig.ini
                                  --- options below is unnecessary and can be omitted
&list=false                       --- 用于输出 Surge Node List 或者 Clash Proxy Provider 或者 Quantumult (X) 的节点订阅 或者 解码后的 SIP002
&tfo=false                        --- 用于开启该订阅链接的 TCP Fast Open,默认为 false
&scv=false                        --- 用于关闭 TLS 节点的证书检查,默认为 false
&fdn=false                        --- 用于过滤目标类型不支持的节点,默认为 true
&sort=false                       --- 用于对输出的节点或策略组按节点名进行再次排序,默认为 false

Set up a cronjob

Create a shell script /etc/clash/update-config.sh with the following content:

#!/usr/bin/env bash
set -ex
/usr/bin/curl "https://sub.xeton.dev/sub?target=clash&new_name=true&filename=config.yaml&url=XXXXXXXX&config=https%3A%2F%2Fgist.githubusercontent.com%2Fcld4h%2F9a03ec2f826a25be5ab974fdbc540de4%2Fraw%2Fconfig.ini" -o /etc/clash/config.yaml

⚠️ The URL should be replace.

Manually executing it to make sure the config file is generated successfully.

Make sure you have the following contents in your config.yaml file for clash:

tproxy-port: 7893

dns:
  enable: true
  listen: 0.0.0.0:1053
  enhanced-mode: fake-ip
  fake-ip-range: 198.18.0.1/16

Add a cronjob by executing sudo crontab -e and add this line to executing the script at 10:00 AM every day.

0 10 * * * /usr/bin/bash /etc/clash/update-config.sh

本文展示了在Linux下使用clash和iptables搭建透明代理进行翻墙的步骤

我们用到了

你可以从 github gist 来下载本文中提到的文件。

配置所需的全部文件:

.
├── clash-base-config.yaml  ---🟢clash的基础配置以使其工作在tproxy和fake-ip模式
├── clash.service           ---🟢systemd 配置文件
├── clean.sh                ---🟢清理iptables的脚本
├── config.ini              ---🟢subconverter的配置文件
├── iptables.sh             ---🟢iptables配置文件
├── update-config.sh        ---🟡订阅更新脚本; 须将"XXXXXXXX"替换成你的订阅地址
├── config.yaml             ---⭕clash 配置文件, 须从update-config.sh生成
├── README.md
└── README.zh-cn.md

🟢: 无需修改
🟡: 需要修改
⭕: 需要生成

参考

clash-tproxy

Transparent proxy demo code

准备条件

  • 安装好的 clash .(默认在 /usr/bin/clash 路径下)
  • iptables
  • systemd (你完全可以使用其他的启动程序,这不过在这里我只展示systemd的配置过程,因为大多数GNU/Linux发行版默认使用systemd)
  • crontab

步骤

创建一个名为clash的系统用户

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

由于我们要做全局的透明代理(代理网卡上的全部流量),所有我们需要避免代理软件发出的流量再次进入代理软件形成回路无限循环。

因此,我们创建一个独立的用户 clash (名字可以是任意的,但要一致) 来运行代理软件。 之后通过iptables的规则将 clash 用户的流量分离出来。

创建iptables和路由规则

创建一个内容是iptables命令的shell脚本 /etc/clash/iptables.sh.

文件包含三个主要部分:

  1. iptables规则用于劫持DNS请求流量
  2. PREROUTING 中 clash 链的配置
  3. OUTPUT 中 clash_local 链的配置

iptables 示意图:

┌─────────┐                                                                                      ┌─────────┐
│         │             PREROUTING                                                INPUT          │         │
│         │                                                                                      │         │
│         │  ┌─────────────────────────────────────┐                      ┌────────────────────┐ │         │
│         │  │                                     │         /───\        │                    │ │         │
│         │  │ ┌───┐  ┌─────────┐  ┌──────┐  ┌───┐ │        /     \       │ ┌──────┐  ┌──────┐ │ │         │
│         ├──┤►│raw├─►│conntrack├─►│mangle├─►│nat├─┼──────►<routing>──────┤►│mangle├─►│filter├─┤►│         │
│         │  │ └───┘  └─────────┘  └──────┘  └───┘ │        \     /       │ └──────┘  └──────┘ │ │         │
│         │  │                                     │         \─┬─/        │                    │ │         │
│         │  └─────────────────────────────────────┘           │          └────────────────────┘ │         │
│         │                                                    │                                 │         │
│         │                               ┌──────────┐         │                                 │         │
│         │                               │          │         │                                 │         │
│         │                               │ ┌──────┐ │         │                                 │         │
│         │                               │ │mangle◄─┼─────────┘                                 │         │
│ Network │                               │ └──┬───┘ │                                           │  Local  │
│Interface│                               │    │     │ FORWARD                                   │ Process │
│         │                               │ ┌──▼───┐ │                                  /───\    │         │
│         │               ┌───────────────┼─┤filter│ │                                 /     \   │         │
│         │               │               │ └──────┘ │                                <routing>◄─┤         │
│         │               │               │          │                                 \     /   │         │
│         │               │               └──────────┘                                  \─┬─/    │         │
│         │               │                                                               │      │         │
│         │  ┌────────────┼────┐               ┌──────────────────────────────────────────┼────┐ │         │
│         │  │            │    │     ─────     │                                          │    │ │         │
│         │  │ ┌───┐  ┌───▼──┐ │    /     \    │ ┌──────┐  ┌───┐  ┌──────┐  ┌─────────┐  ┌▼──┐ │ │         │
│         │◄─┼─┤nat│◄─┤mangle│◄├───<reroute>───┼─┤filter│◄─┤nat│◄─┤mangle│◄─┤conntrack│◄─┤raw│ │ │         │
│         │  │ └───┘  └──────┘ │    \check/    │ └──────┘  └───┘  └──────┘  └─────────┘  └───┘ │ │         │
│         │  │                 │     ─────     │                                               │ │         │
│         │  └─────────────────┘               └───────────────────────────────────────────────┘ │         │
│         │     POSTROUTING                                        OUTPUT                        │         │
│         │                                                                                      │         │
└─────────┘                                                                                      └─────────┘

/etc/clash/iptables.sh 内容如下:

#!/usr/bin/env bash

# set -ex 选项说明:
# -e 当有命令以非0值退出时立刻结束执行
# -x 当命令执行时打印命令及其参数
set -ex

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

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

##################################
## hijack the dns query traffic ##
##################################

# 转发从局域网收到的所有 DNS 查询流量到 1053 端口
# 此操作会导致所有 DNS 请求全部返回虚假 IP(fake ip 198.18.0.1/16)
iptables -t nat -I PREROUTING -p udp --dport 53 -j REDIRECT --to 1053
# ipv6 同样配置
ip6tables -t nat -I PREROUTING -p udp --dport 53 -j REDIRECT --to 1053


# 转发从所有本机进程(除去uid为clash的进程)收到的所有 DNS 查询流量到 1053 端口
# 此操作会导致所有 DNS 请求全部返回虚假 IP(fake ip 198.18.0.1/16)
iptables -t nat -N clash_dns
iptables -t nat -A OUTPUT -p udp --dport 53 -j clash_dns
iptables -t nat -A clash_dns -m owner --uid-owner clash -j RETURN
iptables -t nat -A clash_dns -p udp -j REDIRECT --to-ports 1053
# ipv6 同样配置
ip6tables -t nat -N clash_dns
ip6tables -t nat -A OUTPUT -p udp --dport 53 -j clash_dns
ip6tables -t nat -A clash_dns -m owner --uid-owner clash -j RETURN
ip6tables -t nat -A clash_dns -p udp -j REDIRECT --to-ports 1053

##############################
## config for `clash` chain ##
##############################

# `clash` 链负责利用tproxy将流量转发到clash的7893端口
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
# https://zh.wikipedia.org/wiki/%E4%B8%93%E7%94%A8%E7%BD%91%E7%BB%9C
# IANA - Local Identification
iptables -t mangle -A clash -d 0.0.0.0/8 -j RETURN
# IANA - Loopback
iptables -t mangle -A clash -d 127.0.0.0/8 -j RETURN
# IANA - Private Use
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
# IPv4 Link-Local Addresses
iptables -t mangle -A clash -d 169.254.0.0/16 -j RETURN
# Multicast
iptables -t mangle -A clash -d 224.0.0.0/4 -j RETURN
# Future Use
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

# 将 `clash` 链加在PREROUTING链后面使其生效
iptables -t mangle -A PREROUTING -j clash

####################################
## config for `clash_local` chain ##
####################################

# `clash_local` 链负责处理本机的本地进程发出的流量:给发往公网的流量打上666标记
# (之后会reroute给lo设备,然后会在PREROUTING中的clash链上转发到tproxy 7893端口)
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
# clash_local 链会为本机流量打 mark, 打过 mark 的流量会重新回到device lo,再从PREROUTING开始走流程.
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

# 跳过来自服务端口的流量
# https web server
# iptables -t mangle -I OUTPUT -p tcp --sport 443 -j RETURN
# transmission
# iptables -t mangle -I OUTPUT -p tcp --sport 51413 -j RETURN

# 跳过 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` 链加在 OUTPUT 链后面使其生效
iptables -t mangle -A OUTPUT -j clash_local

#######################
## unimportant staff ##
#######################

# 修复 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
#iptables -t nat -A OUTPUT -p icmp -d 198.18.0.0/16 -j DNAT --to-destination 127.0.0.1

当执行完上述脚本后,iptables的状态如下图所示:

┌─────────┐                                                                                      ┌─────────┐
│         │             PREROUTING           rule1*                               INPUT          │         │
│         │                                    │                                                 │         │
│         │  ┌─────────────────────────────────┼───┐                      ┌────────────────────┐ │         │
│         │  │                                 │   │         /───\        │                    │ │         │
│         │  │ ┌───┐  ┌─────────┐  ┌──────┐  ┌─┴─┐ │        /     \       │ ┌──────┐  ┌──────┐ │ │         │
│         ├──┤►│raw├─►│conntrack├─►│mangle├─►│nat├─┼──────►<routing>──────┤►│mangle├─►│filter├─┤►│         │
│         │  │ └───┘  └─────────┘  └┬─────┘  └───┘ │        \     /       │ └──────┘  └──────┘ │ │         │
│         │  │                      │              │         \─┬─/        │                    │ │         │
│         │  └──────────────────────┼──────────────┘           │          └────────────────────┘ │         │
│         │                         │                          │                                 │         │
│         │                      ┌──┴──┐  ┌──────────┐         │                                 │         │
│         │                      │clash│  │          │         │                                 │         │
│         │                      └─────┘  │ ┌──────┐ │         │                                 │         │
│         │                               │ │mangle◄─┼─────────┘                                 │         │
│ Network │                               │ └──┬───┘ │              ┌───────────┐                │  Local  │
│Interface│                               │    │     │ FORWARD      │clash_local│                │ Process │
│         │                               │ ┌──▼───┐ │              └─┬─────────┘       /───\    │         │
│         │               ┌───────────────┼─┤filter│ │                │                /     \   │         │
│         │               │               │ └──────┘ │                ├───rule3*      <routing>◄─┤         │
│         │               │               │          │                │                \     /   │         │
│         │               │               └──────────┘                ├───rule2*        \─┬─/    │         │
│         │               │                                           │                   │      │         │
│         │  ┌────────────┼────┐               ┌──────────────────────┼───────────────────┼────┐ │         │
│         │  │            │    │     ─────     │                      │                   │    │ │         │
│         │  │ ┌───┐  ┌───▼──┐ │    /     \    │ ┌──────┐  ┌───┐  ┌───┴──┐  ┌─────────┐  ┌▼──┐ │ │         │
│         │◄─┼─┤nat│◄─┤mangle│◄├───<reroute>───┼─┤filter│◄─┤nat│◄─┤mangle│◄─┤conntrack│◄─┤raw│ │ │         │
│         │  │ └───┘  └──────┘ │    \check/    │ └──────┘  └┬──┘  └──────┘  └─────────┘  └───┘ │ │         │
│         │  │                 │     ─────     │            │                                  │ │         │
│         │  └─────────────────┘               └────────────┼──────────────────────────────────┘ │         │
│         │     POSTROUTING                                 │      OUTPUT                        │         │
│         │                                          ┌──────┴──┐                                 │         │
└─────────┘                                          │clash_dns│                                 └─────────┘
                                                     └─────────┘

 *rule1: iptables -t nat -I PREROUTING -p udp --dport 53 -j REDIRECT --to 1053
 *rule2: iptables -t mangle -A OUTPUT -p tcp -m owner --uid-owner clash -j RETURN
 *rule3: iptables -t mangle -A OUTPUT -p udp -m owner --uid-owner clash -j RETURN

研究一下 iptables.sh 中的路由规则:

ip rule add fwmark 666 table 666
ip route add local 0.0.0.0/0 table 666 dev lo

ip rule 用于控制策略路由数据库,管理策略路由的路由选择算法

这里 ip rule 命令让内核对标记有666的数据包查找666号路由表

ip rule 参考文档

ip route 命令在666号路由表中添加了一条到lo设备的默认路由

我们可以通过 ip route show table 666 来查看 ip route add local 0.0.0.0/0 table 666 dev lo 添加的路由项

查看路由表编号和名称的映射: cat /etc/iproute2/rt_tables

创建规则清理脚本

在退出clash后需清除设定的规则

-D--delete:

从所选链中删掉一条或多条规则。 可以指定要删除的规则号;或指定规则内容(将 -A-I 替换成 -D 即可)

-F or --flush:

刷新所选链,相当于逐条清除链上的所有规则

-X or --delete-chain:

删除用户定义的链

#!/usr/bin/env bash

set -ex

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

iptables -t nat -D PREROUTING -p udp --dport 53 -j REDIRECT --to 1053 || true
ip6tables -t nat -D PREROUTING -p udp --dport 53 -j REDIRECT --to 1053 || true
iptables -t nat -D OUTPUT -p udp --dport 53 -j clash_dns || true
ip6tables -t nat -D OUTPUT -p udp --dport 53 -j clash_dns || true
iptables -t nat -F clash_dns || true
iptables -t nat -X clash_dns || true
ip6tables -t nat -F clash_dns || true
ip6tables -t nat -X clash_dns || true
#iptables -t nat -D PREROUTING -p icmp -d 198.18.0.0/16 -j DNAT --to-destination 127.0.0.1
#iptables -t nat -D OUTPUT -p icmp -d 198.18.0.0/16 -j DNAT --to-destination 127.0.0.1

iptables -t mangle -D PREROUTING -j clash || true
iptables -t mangle -F clash || true
iptables -t mangle -X clash || true

iptables -t mangle -D OUTPUT -p tcp -m owner --uid-owner clash -j RETURN || true
iptables -t mangle -D OUTPUT -p udp -m owner --uid-owner clash -j RETURN || true
iptables -t mangle -D OUTPUT -j clash_local || true
iptables -t mangle -F clash_local || true
iptables -t mangle -X clash_local || true

修正ping

fake-ip 模式的一个主要缺点是无法ping

前面 iptables.sh 中将所有ping请求重定向到127.0.0.1 的操作是掩耳盗铃的,它不提供任何信息。

但是,可以通过clash用户的身份进行ping

alias ping="sudo -u clash ping"

提供systemd unit file 以一键启动clash及相关iptables等配置

此步骤是可选的,但我觉得能够一键启动/关闭clash很方便。

同时也可以设置clash开机启动。

Systemd 配置文件命名为clash.service ,放在 /usr/lib/systemd/system 目录下,执行 sudo systemctl start clash 来启动运行clash

开机启动: sudo systemctl enable clash.

配置clash

下面看一看对clash本身的配置

clash 使用 -d 选项得到配置文件目录; -f 选项得到配置文件

-f 被忽略时,默认的配置文件名是 config.yaml

我们想要通过 crontab 从clash的订阅链接中定时更新clash的配置文件

构造订阅连接

TL;DR. 将下面URL中XXXXXXXX 替换成URL Encode后的节点订阅URL即可

https://sub.xeton.dev/sub?target=clash&new_name=true&filename=config.yaml&url=XXXXXXXX&config=https%3A%2F%2Fgist.githubusercontent.com%2Fcld4h%2F9a03ec2f826a25be5ab974fdbc540de4%2Fraw%2Fconfig.ini

我们通过subconverter来生成clash的配置文件。

你需要修改订阅链接中的一些参数以使得生成的clash正确配置成 监听tproxy 以及 fake-ip 模式

具体的:

  1. url 参数要是正确的节点信息并且经过URL Encode.
  2. 多个节点订阅URL要用 | 分割, 此符号URL Encode 之后是 %7C .
  3. config 参数是用于告诉subconverter如何进行订阅转换的关键,应当配置正确. ⚠️

⚠️ 注意: 这里subconverter 的配置文件非常重要

ACL4SSR 项目提供了一个默认的subconverter配置文件,这个文件没问题,但默认的选项不足以让clash开启fake-ip模式并监听tproxy

要想使其工作,需指定 clash_rule_base: 在中插入下面这一行

clash_rule_base=https://gist.githubusercontent.com/cld4h/9a03ec2f826a25be5ab974fdbc540de4/raw/clash-base-config.yaml

这一行的作用是告诉subconverter使用URL中的文件作为clash的基础配置

或者你可以直接使用我的config.ini

示例URL:

https://sub.xeton.dev/sub?        --- 后端地址
target=clash                      --- 客户端类型
&new_name=true                    --- 重命名
&filename=config.yaml             --- 文件名
&url=                             --- 节点信息
ss%3A%2F%2FYmYtY2ZiOnRlc3QvIUAjOkAxOTIuMTY4LjEwMC4xOjg4ODg%23example-server
%7C                               --- 分隔符 |
ss%3A%2F%2FYmYtY2ZiOnRlc3QvIUAjOkAxOTIuMTY4LjEwMC4xOjg4ODg%23example-server-2
&config=                          --- subconverter的配置文件; .ini 格式
https%3A%2F%2Fgist.githubusercontent.com%2Fcld4h%2F9a03ec2f826a25be5ab974fdbc540de4%2Fraw%2Fconfig.ini
                                  --- 下面这些配置是多余的,没啥用
&list=false                       --- 用于输出 Surge Node List 或者 Clash Proxy Provider 或者 Quantumult (X) 的节点订阅 或者 解码后的 SIP002
&tfo=false                        --- 用于开启该订阅链接的 TCP Fast Open,默认为 false
&scv=false                        --- 用于关闭 TLS 节点的证书检查,默认为 false
&fdn=false                        --- 用于过滤目标类型不支持的节点,默认为 true
&sort=false                       --- 用于对输出的节点或策略组按节点名进行再次排序,默认为 false

设置定时更新订阅任务

创建订阅更新脚本 /etc/clash/update-config.sh ,内容如下:

#!/usr/bin/env bash
set -ex
/usr/bin/curl "https://sub.xeton.dev/sub?target=clash&new_name=true&filename=config.yaml&url=XXXXXXXX&config=https%3A%2F%2Fgist.githubusercontent.com%2Fcld4h%2F9a03ec2f826a25be5ab974fdbc540de4%2Fraw%2Fconfig.ini" -o /etc/clash/config.yaml

⚠️ 上面的URL要替换一下

手动执行一下上述脚本确认配置文件能够正常生成。

确保你的clashconfig.yaml配置文件中有如下内容:

tproxy-port: 7893

dns:
  enable: true
  listen: 0.0.0.0:1053
  enhanced-mode: fake-ip
  fake-ip-range: 198.18.0.1/16

添加定时任务: 执行 sudo crontab -e 并加入下面这一行以在每天早上10:00执行订阅更新脚本。

0 10 * * * /usr/bin/bash /etc/clash/update-config.sh
mixed-port: 7890
tproxy-port: 7893
allow-lan: true
bind-address: "*"
mode: rule
log-level: info
ipv6: true
external-controller: :9090
secret: "1qazxsw23edcvfr4"
profile:
store-selected: false
store-fake-ip: true
dns:
enable: true
listen: 0.0.0.0:1053
enhanced-mode: fake-ip
fake-ip-range: 198.18.0.1/16
# Hostnames in this list will not be resolved with fake IPs
# i.e. questions to these domain names will always be answered with their
# real IP addresses
fake-ip-filter:
# - '*.lan'
# - localhost.ptlogin2.qq.com
# - cloud.dns.army
default-nameserver:
# aka. Bootstrap DNS
# default-nameserver is used by the server to resolve the IP address of the DoH/DoT resolver that you specify in nameserver. Only accept IP.
# Clash will use 114.114.114.114 and 8.8.8.8 as default-nameserver. If you configure this parameter, clash will override these two default values.
- 114.114.114.114
- 8.8.8.8
nameserver:
- 223.5.5.5 # 阿里DNS
- 180.76.76.76 # 百度DNS
- 119.29.29.29 # 腾讯DNS
- 117.50.11.11 # ONE DNS拦截版 恶意网站拦截、广告过滤
- 117.50.10.10 # ONE DNS纯净版 直接返回其真实的响应结果
- 114.114.114.114 # 114DNS
- https://dns.alidns.com/dns-query # 阿里 DoH DNS
- https://doh.360.cn/dns-query # 360 DoH DNS
fallback:
# - 8.8.8.8 # 谷歌DNS
# - 1.1.1.1 # Cloudflare DNS
# - tls://dns.rubyfish.cn:853
# - https://dns.rubyfish.cn/dns-query
- https://cloudflare-dns.com/dns-query
- https://1.1.1.1/dns-query
- tls://8.8.8.8:853
- tls://1.0.0.1:853
- tls://dns.google:853
- https://dns.google/dns-query
fallback-filter:
geoip: true # 默认
geoip-code: CN
ipcidr: # 在这个网段内的 IP 地址会被考虑为被污染的 IP
- 240.0.0.0/4
# 1. clash DNS 请求逻辑:
# (1) 当访问一个域名时, nameserver 与 fallback 列表内的所有服务器并发请求,得到域名对应的 IP 地址。
# (2) clash 将选取 nameserver 列表内,解析最快的结果。
# (3) 若解析结果中,IP 地址属于 国外,那么 clash 将选择 fallback 列表内,解析最快的结果。
#
# 因此,我在 nameserver 和 fallback 内都放置了无污染、解析速度较快的国内 DNS 服务器,以达到最快的解析速度。
# 但是 fallback 列表内服务器会用在解析境外网站,为了结果绝对无污染,我仅保留了支持 DoT/DoH 的两个服务器。
#
# 2. clash DNS 配置注意事项:
# (1) 如果您为了确保 DNS 解析结果无污染,请仅保留列表内以 tls:// 或 https:// 开头的 DNS 服务器,但是通常对于国内域名没有必要。
# (2) 如果您不在乎可能解析到污染的结果,更加追求速度。请将 nameserver 列表的服务器插入至 fallback 列表内,并移除重复项。
#
# 3. 关于 DNS over HTTPS (DoH) 和 DNS over TLS (DoT) 的选择:
# 对于两项技术双方各执一词,而且会无休止的争论,各有利弊。各位请根据具体需求自行选择,但是配置文件内默认启用 DoT,因为目前国内没有封锁或管制。
# DoH: 以 https:// 开头的 DNS 服务器。拥有更好的伪装性,且几乎不可能被运营商或网络管理封锁,但查询效率和安全性可能略低。
# DoT: 以 tls:// 开头的 DNS 服务器。拥有更高的安全性和查询效率,但端口有可能被管制或封锁。
# 若要了解更多关于 DoH/DoT 相关技术,请自行查阅规范文档。
[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
ExecStop=+/usr/bin/bash /etc/clash/clean.sh
[Install]
WantedBy=multi-user.target
#!/usr/bin/env bash
set -ex
ip rule del fwmark 666 table 666 || true
ip route del local 0.0.0.0/0 table 666 dev lo || true
iptables -t nat -D PREROUTING -p udp --dport 53 -j REDIRECT --to 1053 || true
ip6tables -t nat -D PREROUTING -p udp --dport 53 -j REDIRECT --to 1053 || true
iptables -t nat -D OUTPUT -p udp --dport 53 -j clash_dns || true
ip6tables -t nat -D OUTPUT -p udp --dport 53 -j clash_dns || true
iptables -t nat -F clash_dns || true
iptables -t nat -X clash_dns || true
ip6tables -t nat -F clash_dns || true
ip6tables -t nat -X clash_dns || true
#iptables -t nat -D PREROUTING -p icmp -d 198.18.0.0/16 -j DNAT --to-destination 127.0.0.1
#iptables -t nat -D OUTPUT -p icmp -d 198.18.0.0/16 -j DNAT --to-destination 127.0.0.1
iptables -t mangle -D PREROUTING -j clash || true
iptables -t mangle -F clash || true
iptables -t mangle -X clash || true
iptables -t mangle -D OUTPUT -p tcp -m owner --uid-owner clash -j RETURN || true
iptables -t mangle -D OUTPUT -p udp -m owner --uid-owner clash -j RETURN || true
iptables -t mangle -D OUTPUT -j clash_local || true
iptables -t mangle -F clash_local || true
iptables -t mangle -X clash_local || true
[custom]
;不要随意改变关键字,否则会导致出错
;acl4SSR规则-在线更新版
;去广告:支持
;自动测速:支持
;微软分流:支持
;苹果分流:支持
;增强中国IP段:不支持
;增强国外GFW:不支持
ruleset=🎯 全球直连,https://raw.githubusercontent.com/ACL4SSR/ACL4SSR/master/Clash/LocalAreaNetwork.list
ruleset=🎯 全球直连,https://raw.githubusercontent.com/ACL4SSR/ACL4SSR/master/Clash/UnBan.list
ruleset=🛑 全球拦截,https://raw.githubusercontent.com/ACL4SSR/ACL4SSR/master/Clash/BanAD.list
ruleset=🍃 应用净化,https://raw.githubusercontent.com/ACL4SSR/ACL4SSR/master/Clash/BanProgramAD.list
ruleset=📢 谷歌FCM,https://raw.githubusercontent.com/ACL4SSR/ACL4SSR/master/Clash/Ruleset/GoogleFCM.list
ruleset=🎯 全球直连,https://raw.githubusercontent.com/ACL4SSR/ACL4SSR/master/Clash/GoogleCN.list
ruleset=🎯 全球直连,https://raw.githubusercontent.com/ACL4SSR/ACL4SSR/master/Clash/Ruleset/SteamCN.list
ruleset=Ⓜ️ 微软服务,https://raw.githubusercontent.com/ACL4SSR/ACL4SSR/master/Clash/Microsoft.list
ruleset=🍎 苹果服务,https://raw.githubusercontent.com/ACL4SSR/ACL4SSR/master/Clash/Apple.list
ruleset=📲 电报信息,https://raw.githubusercontent.com/ACL4SSR/ACL4SSR/master/Clash/Telegram.list
ruleset=🌍 国外媒体,https://raw.githubusercontent.com/ACL4SSR/ACL4SSR/master/Clash/ProxyMedia.list
ruleset=🚀 节点选择,https://raw.githubusercontent.com/ACL4SSR/ACL4SSR/master/Clash/ProxyLite.list
ruleset=🎯 全球直连,https://raw.githubusercontent.com/ACL4SSR/ACL4SSR/master/Clash/ChinaDomain.list
ruleset=🎯 全球直连,https://raw.githubusercontent.com/ACL4SSR/ACL4SSR/master/Clash/ChinaCompanyIp.list
;ruleset=🎯 全球直连,[]GEOIP,LAN
ruleset=🎯 全球直连,[]GEOIP,CN
ruleset=🐟 漏网之鱼,[]FINAL
clash_rule_base=https://gist.githubusercontent.com/cld4h/9a03ec2f826a25be5ab974fdbc540de4/raw/clash-base-config.yaml
custom_proxy_group=🚀 节点选择`select`[]♻️ 自动选择`[]DIRECT`.*
custom_proxy_group=♻️ 自动选择`url-test`.*`http://www.gstatic.com/generate_204`300,,50
custom_proxy_group=🌍 国外媒体`select`[]🚀 节点选择`[]♻️ 自动选择`[]🎯 全球直连`.*
custom_proxy_group=📲 电报信息`select`[]🚀 节点选择`[]🎯 全球直连`.*
custom_proxy_group=Ⓜ️ 微软服务`select`[]🎯 全球直连`[]🚀 节点选择`.*
custom_proxy_group=🍎 苹果服务`select`[]🚀 节点选择`[]🎯 全球直连`.*
custom_proxy_group=📢 谷歌FCM`select`[]🚀 节点选择`[]🎯 全球直连`[]♻️ 自动选择`.*
custom_proxy_group=🎯 全球直连`select`[]DIRECT`[]🚀 节点选择`[]♻️ 自动选择
custom_proxy_group=🛑 全球拦截`select`[]REJECT`[]DIRECT
custom_proxy_group=🍃 应用净化`select`[]REJECT`[]DIRECT
custom_proxy_group=🐟 漏网之鱼`select`[]🚀 节点选择`[]🎯 全球直连`[]♻️ 自动选择`.*
add_emoji=true
remove_old_emoji=true
emoji=(故障|流量|时间|应急),🏳️‍🌈
emoji=(?i:JP|Japan|Tokyo|Osaka|Saitama|日本|东京|大阪|埼玉|[^-]日),🇯🇵
emoji=(?i:KR|Korea|KOR|首尔|韩|韓),🇰🇷
emoji=(?i:SG|Singapore|新加坡|狮城|[^-]新),🇸🇬
emoji=(?i:US|America|United.*?States|美国|[^-]美|波特兰|达拉斯|俄勒冈|凤凰城|费利蒙|硅谷|拉斯维加斯|洛杉矶|圣何塞|圣克拉拉|西雅图|芝加哥),🇺🇸
emoji=(?i:TW|Taiwan|新北|彰化|CHT|台湾|[^-]台|HINET),🇹🇼
emoji=(?i:HK|Hong.*?Kong|HKT|HKBN|HGC|WTT|CMI|[^-]港),🇭🇰
enable_rule_generator=true
overwrite_original_rules=true
#!/usr/bin/env bash
# After applying this script, the system iptables should be like this:
#┌─────────┐ ┌─────────┐
#│ │ PREROUTING rule1* INPUT │ │
#│ │ │ │ │
#│ │ ┌─────────────────────────────────┼───┐ ┌────────────────────┐ │ │
#│ │ │ │ │ /───\ │ │ │ │
#│ │ │ ┌───┐ ┌─────────┐ ┌──────┐ ┌─┴─┐ │ / \ │ ┌──────┐ ┌──────┐ │ │ │
#│ ├──┤►│raw├─►│conntrack├─►│mangle├─►│nat├─┼──────►<routing>──────┤►│mangle├─►│filter├─┤►│ │
#│ │ │ └───┘ └─────────┘ └┬─────┘ └───┘ │ \ / │ └──────┘ └──────┘ │ │ │
#│ │ │ │ │ \─┬─/ │ │ │ │
#│ │ └──────────────────────┼──────────────┘ │ └────────────────────┘ │ │
#│ │ │ │ │ │
#│ │ ┌──┴──┐ ┌──────────┐ │ │ │
#│ │ │clash│ │ │ │ │ │
#│ │ └─────┘ │ ┌──────┐ │ │ │ │
#│ │ │ │mangle◄─┼─────────┘ │ │
#│ Network │ │ └──┬───┘ │ ┌───────────┐ │ Local │
#│Interface│ │ │ │ FORWARD │clash_local│ │ Process │
#│ │ │ ┌──▼───┐ │ └─┬─────────┘ /───\ │ │
#│ │ ┌───────────────┼─┤filter│ │ │ / \ │ │
#│ │ │ │ └──────┘ │ ├───rule3* <routing>◄─┤ │
#│ │ │ │ │ │ \ / │ │
#│ │ │ └──────────┘ ├───rule2* \─┬─/ │ │
#│ │ │ │ │ │ │
#│ │ ┌────────────┼────┐ ┌──────────────────────┼───────────────────┼────┐ │ │
#│ │ │ │ │ ───── │ │ │ │ │ │
#│ │ │ ┌───┐ ┌───▼──┐ │ / \ │ ┌──────┐ ┌───┐ ┌───┴──┐ ┌─────────┐ ┌▼──┐ │ │ │
#│ │◄─┼─┤nat│◄─┤mangle│◄├───<reroute>───┼─┤filter│◄─┤nat│◄─┤mangle│◄─┤conntrack│◄─┤raw│ │ │ │
#│ │ │ └───┘ └──────┘ │ \check/ │ └──────┘ └┬──┘ └──────┘ └─────────┘ └───┘ │ │ │
#│ │ │ │ ───── │ │ │ │ │
#│ │ └─────────────────┘ └────────────┼──────────────────────────────────┘ │ │
#│ │ POSTROUTING │ OUTPUT │ │
#│ │ ┌──────┴──┐ │ │
#└─────────┘ │clash_dns│ └─────────┘
# └─────────┘
#
# *rule1: iptables -t nat -I PREROUTING -p udp --dport 53 -j REDIRECT --to 1053
# *rule2: iptables -t mangle -A OUTPUT -p tcp -m owner --uid-owner clash -j RETURN
# *rule3: iptables -t mangle -A OUTPUT -p udp -m owner --uid-owner clash -j RETURN
# set -ex options:
# -e Exit immediately if a command exits with a non-zero status
# -x Print commands and their arguments as they are executed.
set -ex
# ENABLE ipv4 forward
sysctl -w net.ipv4.ip_forward=1
# ROUTE RULES
ip rule add fwmark 666 table 666
ip route add local 0.0.0.0/0 table 666 dev lo
##################################
## hijack the dns query traffic ##
##################################
# Redirect all dns query traffic from LAN to port 1053
# Later clash will return a fake ip in 198.18.0.1/16
# 转发从局域网收到的所有 DNS 查询流量到 1053 端口
# 此操作会导致所有 DNS 请求全部返回虚假 IP(fake ip 198.18.0.1/16)
iptables -t nat -I PREROUTING -p udp --dport 53 -j REDIRECT --to 1053
# same for ipv6
# ipv6 同样配置
ip6tables -t nat -I PREROUTING -p udp --dport 53 -j REDIRECT --to 1053
# Redirect dns query traffic from all local processes (except owned by user clash) to port 1053
# Later clash will return a fake ip in 198.18.0.1/16
# 转发从所有本机进程(除去uid为clash的进程)收到的所有 DNS 查询流量到 1053 端口
# 此操作会导致所有 DNS 请求全部返回虚假 IP(fake ip 198.18.0.1/16)
iptables -t nat -N clash_dns
iptables -t nat -A OUTPUT -p udp --dport 53 -j clash_dns
iptables -t nat -A clash_dns -m owner --uid-owner clash -j RETURN
iptables -t nat -A clash_dns -p udp -j REDIRECT --to-ports 1053
# same for ipv6
# ipv6 同样配置
ip6tables -t nat -N clash_dns
ip6tables -t nat -A OUTPUT -p udp --dport 53 -j clash_dns
ip6tables -t nat -A clash_dns -m owner --uid-owner clash -j RETURN
ip6tables -t nat -A clash_dns -p udp -j REDIRECT --to-ports 1053
##############################
## config for `clash` chain ##
##############################
# `clash` chain to manipulate traffic from LAN
# `clash` 链负责处理来自 局域网 的流量
iptables -t mangle -N clash
# skip traffic to LAN or reserved address
# reference:
# https://en.wikipedia.org/wiki/List_of_assigned_/8_IPv4_address_blocks
# https://en.wikipedia.org/wiki/Private_network#IPv4
# 目标地址为局域网或保留地址的流量跳过处理
# 保留地址参考:
# 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
# https://zh.wikipedia.org/wiki/%E4%B8%93%E7%94%A8%E7%BD%91%E7%BB%9C
# IANA - Local Identification
iptables -t mangle -A clash -d 0.0.0.0/8 -j RETURN
# IANA - Loopback
iptables -t mangle -A clash -d 127.0.0.0/8 -j RETURN
# IANA - Private Use
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
# IPv4 Link-Local Addresses
iptables -t mangle -A clash -d 169.254.0.0/16 -j RETURN
# Multicast
iptables -t mangle -A clash -d 224.0.0.0/4 -j RETURN
# Future Use
iptables -t mangle -A clash -d 240.0.0.0/4 -j RETURN
# Forward all the other traffic to port 7893 and set tproxy mark
# 其他所有流量转向到 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
# Append the `clash` chain to PREROUTING to enable it
# 将 `clash` 链加在PREROUTING链后面使其生效
iptables -t mangle -A PREROUTING -j clash
####################################
## config for `clash_local` chain ##
####################################
# `clash_local` chain to manipulate traffic from local process
# `clash_local` 链负责处理本机的本地进程发出的流量
iptables -t mangle -N clash_local
# rerouting traffic from nerdctl container
# 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
# Don't touch traffic to LAN and reserved address
# 跳过内网流量
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
# set mark for local traffic
# clash_local set mark for the traffic from local process,
# the marked traffic will come back to PREROUTING chain.
# 为本机发出的流量打 mark
# clash_local 链会为本机流量打 mark, 打过 mark 的流量会重新回到 PREROUTING 上
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
# Don't touch traffic from a serving port
# 跳过来自服务端口的流量
# https web server
# iptables -t mangle -I OUTPUT -p tcp --sport 443 -j RETURN
# transmission
# iptables -t mangle -I OUTPUT -p tcp --sport 51413 -j RETURN
# Don't touch traffic from the user `clash` to prevent looping
# 跳过 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
# Append the `clash_local` chain to OUTPUT to enable it
# 将 `clash_local` 链加在 OUTPUT 链后面使其生效
iptables -t mangle -A OUTPUT -j clash_local
#######################
## unimportant staff ##
#######################
# fix ICMP(ping)
# This step does NOT make the ping result validate
# (clash doesn't support forwarding ICMP), it just makes ping have a result.
# set --to-destination to a accessable address.
# 修复 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
#iptables -t nat -A OUTPUT -p icmp -d 198.18.0.0/16 -j DNAT --to-destination 127.0.0.1
#!/usr/bin/env bash
# You need to replace XXXXXXXX to your subscription url for this script to work.
set -ex
/usr/bin/curl "https://sub.xeton.dev/sub?target=clash&new_name=true&filename=config.yaml&url=XXXXXXXX&config=https%3A%2F%2Fgist.githubusercontent.com%2Fcld4h%2F9a03ec2f826a25be5ab974fdbc540de4%2Fraw%2Fconfig.ini" -o /etc/clash/config.yaml
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment