Skip to main content

透明代理(Clash)

Clash

Download release from GitHub, unarchive and move to /usr/bin/clash, add executable permissions:

curl -o clash.gz https://github.com/Dreamacro/clash/releases/download/v1.1.0/clash-linux-amd64-v1.1.0.gz
gzip -dk clash.gz
mv clash /usr/bin/clash
chmod +x /usr/bin/clash

Create /etc/systemd/system/clash.service:

[Unit]
Description=clash daemon
[Service]
Type=simple
LimitNOFILE=49152
ExecStart=/usr/bin/clash -d /etc/clash
[Install]
WantedBy=multi-user.target

Prepare a clash config in /etc/clash/config.yml, the following just showing some key instructions, not the complete configuration, you need to modify by yourself:

redir-port: 7892
mode: rule

proxies:
- { name: 'My Upstream Proxy', type: 'http', server: 'example.com', port: 443}

proxy-groups:
- { name: "Proxy", type: select, proxies: ['My Upstream Proxy']}

rules:

# Domains don't want to be proxy
- DOMAIN-SUFFIX,alipay.com,DIRECT
- DOMAIN-SUFFIX,baidu.com,DIRECT
- DOMAIN-SUFFIX,bilibili.com,DIRECT
- DOMAIN-SUFFIX,douban.com,DIRECT
- DOMAIN-SUFFIX,iqiyi.com,DIRECT
- DOMAIN-SUFFIX,jd.com,DIRECT
- DOMAIN-SUFFIX,qq.com,DIRECT
- DOMAIN-SUFFIX,taobao.com,DIRECT
- DOMAIN-SUFFIX,tmall.com,DIRECT
- DOMAIN-SUFFIX,weibo.com,DIRECT
- DOMAIN-SUFFIX,zhihu.com,DIRECT

# Domain keywords to be proxy
- DOMAIN-KEYWORD,amazon,Proxy
- DOMAIN-KEYWORD,google,Proxy
- DOMAIN-KEYWORD,gmail,Proxy
- DOMAIN-KEYWORD,youtube,Proxy
- DOMAIN-KEYWORD,facebook,Proxy
- DOMAIN-KEYWORD,twitter,Proxy
- DOMAIN-KEYWORD,instagram,Proxy
- DOMAIN-KEYWORD,dropbox,Proxy

# Local address
- IP-CIDR,127.0.0.0/8,DIRECT
- IP-CIDR,172.16.0.0/12,DIRECT
- IP-CIDR,192.168.0.0/16,DIRECT
- IP-CIDR,10.0.0.0/8,DIRECT
- IP-CIDR,17.0.0.0/8,DIRECT
- IP-CIDR,100.64.0.0/10,DIRECT

# Finally rules
- GEOIP,CN,DIRECT
- MATCH,Proxy

Redir proxy

We will use iptables to redirect TCP connections to our clash redir port.

First, create a chain for Clash:

iptables -t nat -N CLASH

Ignore connections to local private address:

iptables -t nat -A CLASH -p tcp -d 0.0.0.0/8 -j RETURN
iptables -t nat -A CLASH -p tcp -d 10.0.0.0/8 -j RETURN
iptables -t nat -A CLASH -p tcp -d 127.0.0.0/8 -j RETURN
iptables -t nat -A CLASH -p tcp -d 172.16.0.0/12 -j RETURN
iptables -t nat -A CLASH -p tcp -d 192.168.0.0/16 -j RETURN

Ignore connections to redir port to avoid cyclic redirect:

iptables -t nat -A CLASH -p tcp -m tcp --dport 7892 -j RETURN

We also need ignore connections to your upstream proxy to avoid cyclic redirect:

# if you upstream proxy has a stable address
iptables -t nat -A CLASH -p tcp -d <your upstream proxy address> -j RETURN
# if you upstream proxy has a stable proxy
iptables -t nat -A CLASH -p tcp -m tcp --dport <your upstream proxy port> -j RETURN

Then, redirect to clash:

iptables -t nat -A CLASH -p tcp -j REDIRECT --to-ports 7892

Send traffics from LAN to the CLASH chain:

iptables -t nat -A PREROUTING -s 10.0.0.0/24 -p tcp -j CLASH

Now, all of your outgoing connections will be redirect to Clash.

Troubles about DNS

Unlike a system proxy, iptables redirect traffic on the IP layer, it uses IP instead of a domain. So the domain-related rules in Clash don’t work.

The DNS query is sent by UDP, which can’t redirect by the previous rules, and may produce an incorrect result. We are going to use Clash’s DNS to replace systemd-resolved — the default DNS resolver of Ubuntu.

Disable systemd-resolved:

systemctl disable systemd-resolved
systemctl stop systemd-resolved

Modify Clash config:

dns:
enable: true
ipv6: false
listen: 127.0.0.53:53
enhanced-mode: redir-host
nameserver:
- 119.29.29.29
- 223.5.5.5
fallback:
- 'tls://1.1.1.1:853'
- 'tls://8.8.8.8:853'
- 'tls://9.9.9.9:853'

Clash will resolve domains by servers in nameserver section and fallback section in the same time.

Servers in nameserver section are fast but unreliable, if it returns an address which GEOIP country is CN, we use that; otherwise, we wait for the result form servers in fallback section.

In this process, Clash will remember the mapping from domain to IP, so Clash will know the domain of a redirected connection, and apply domain-related rules. Now, Clash will provide correct DNS resolve on 127.0.0.53:53. Then we need set dnsmasq as a DNS cache server, Modify the following lines in /etc/dnsmasq.conf:

port=53
no-resolv
server=127.0.0.53
cache-size=1000

Modify /etc/resolv.conf to use dnsmasq as local resolver:

nameserver 127.0.0.1