Skip to main content

Command Palette

Search for a command to run...

使用 clash docker 做透明网关

Updated
2 min read
使用 clash docker 做透明网关

之前一直使用 OpenWrt 旁路由的方式来翻墙,但 OpenWrt 本身不够稳定,并且我长期处于只使用 OpenWrt 其中的一个插件的状态,所以决定开一台虚拟机来体验下使用 Clash 作为透明网关

先给出(从同事那借来的)配置:

version: "3"

services:
  # Enable ip_forward - https://askubuntu.com/a/311054
  # For Ubuntu Server, you also need to disable systemd-resolved
  # 1. sudo systemctl stop systemd-resolved
  # 2. sudo systemctl disable systemd-resolved
  clash:
    image: dreamacro/clash-premium
    cap_add:
      - NET_ADMIN
    devices:
      - /dev/net/tun
    network_mode: "host"
    volumes:
      - ./clash:/root/.config/clash
    restart: "always"
    logging:
      driver: "json-file"
      options:
        max-size: "5m"
port: 7890
socks-port: 7891
redir-port: 7892
allow-lan: true
bind-address: "*"
mode: Rule
log-level: info
external-controller: 0.0.0.0:9090
secret: "secret"
dns:
  enable: true
  listen: 0.0.0.0:1053
  ipv6: true
  enhanced-mode: fake-ip
  fake-ip-range: 198.18.0.1/16
  nameserver:
    - 223.5.5.5
    - 223.6.6.6

tun:
  enable: true
  stack: system
  auto-route: true
  auto-detect-interface: true

proxies:
  - name: "hk"
    type: trojan
    server: server
    port: 443
    password: password


proxy-groups:
  - name: Proxy-Fallback
    type: fallback
    proxies:
      - hk
      - DIRECT
    url: 'http://www.gstatic.com/generate_204'
    interval: 3

  - name: Proxy
    type: select
    proxies:
      - Proxy-Fallback

rule-providers:
  apple-proxy:
    type: http
    behavior: classical
    url: "https://cdn.jsdelivr.net/gh/Hackl0us/SS-Rule-Snippet@master/Rulesets/Clash/Basic/Apple-proxy.yaml"
    path: ./ruleset/Apple-proxy.yaml
    interval: 86400
  apple-direct:
    type: http
    behavior: classical
    url: "https://cdn.jsdelivr.net/gh/Hackl0us/SS-Rule-Snippet@master/Rulesets/Clash/Basic/Apple-direct.yaml"
    path: ./ruleset/Apple-direct.yaml
    interval: 86400
  china:
    type: http
    behavior: classical
    url: "https://cdn.jsdelivr.net/gh/DivineEngine/Profiles@master/Clash/RuleSet/China.yaml"
    path: ./ruleset/China.yaml
    interval: 86400
  global:
    type: http
    behavior: classical
    url: "https://cdn.jsdelivr.net/gh/DivineEngine/Profiles@master/Clash/RuleSet/Global.yaml"
    path: ./ruleset/Global.yaml
    interval: 86400
  netflix:
    type: http
    behavior: classical
    url: "https://cdn.jsdelivr.net/gh/Hackl0us/SS-Rule-Snippet@main/Rulesets/Clash/App/stream/Netflix.yaml"
    path: ./ruleset/Netflix.yaml
    interval: 86400
  disney:
    type: http
    behavior: classical
    url: "https://cdn.jsdelivr.net/gh/Hackl0us/SS-Rule-Snippet@main/Rulesets/Clash/App/stream/DisneyPlus.yaml"
    path: ./ruleset/Disney.yaml
    interval: 86400
  lan:
    type: http
    behavior: classical
    url: "https://cdn.jsdelivr.net/gh/Hackl0us/SS-Rule-Snippet@master/Rulesets/Clash/Basic/LAN.yaml"
    path: ./ruleset/LAN.yaml
    interval: 86400

rules:
  # Rule sets
  - RULE-SET,apple-proxy,Proxy
  - RULE-SET,apple-direct,Proxy
  - RULE-SET,china,DIRECT
  - RULE-SET,global,Proxy
  - RULE-SET,lan,DIRECT
  # Final rules
  - GEOIP,CN,DIRECT
  - MATCH,Proxy

然后 docker compose up -d

当然以上只是把 Clash 跑起来,宿主机仍然需要设置转发规则来转发流量到 clash dns:

# https://zhuanlan.zhihu.com/p/423684520
REDIR_PORT="7892"
CLASH_DNS_PORT="1053"

#在nat表中新建一个clash规则链
iptables -t nat -N CLASH
#排除环形地址与保留地址,匹配之后直接RETURN
iptables -t nat -A CLASH -d 0.0.0.0/8 -j RETURN
iptables -t nat -A CLASH -d 10.0.0.0/8 -j RETURN
iptables -t nat -A CLASH -d 127.0.0.0/8 -j RETURN
iptables -t nat -A CLASH -d 169.254.0.0/16 -j RETURN
iptables -t nat -A CLASH -d 172.16.0.0/12 -j RETURN
iptables -t nat -A CLASH -d 192.168.0.0/16 -j RETURN
iptables -t nat -A CLASH -d 224.0.0.0/4 -j RETURN
iptables -t nat -A CLASH -d 240.0.0.0/4 -j RETURN
#重定向tcp流量到本机 redir_host
iptables -t nat -A CLASH -p tcp -j REDIRECT --to-port "$REDIR_PORT"
#拦截外部tcp数据并交给clash规则链处理
iptables -t nat -A PREROUTING -p tcp -j CLASH

#在nat表中新建一个clash_dns规则链
iptables -t nat -N CLASH_DNS
#清空clash_dns规则链
iptables -t nat -F CLASH_DNS
#重定向udp流量到本机 clash dns
iptables -t nat -A CLASH_DNS -p udp -j REDIRECT --to-port "$CLASH_DNS_PORT"
#抓取本机产生的53端口流量交给clash_dns规则链处理
iptables -t nat -I OUTPUT -p udp --dport 53 -j CLASH_DNS
#拦截外部upd的53端口流量交给clash_dns规则链处理
iptables -t nat -I PREROUTING -p udp --dport 53 -j CLASH_DNS

之后把各种设置或主路由的 dns 网关设置为宿主机 ip 就可以翻墙了。

但是仍然有一个问题,clash 在跑的情况下宿主机不能联网了,应该是以上路由规则存在问题,正在与 ChatGPT 激情讨论中

5.2K views