网关代理(透明代理)

最近 macOS 一直没有办法更新,即使set了https代理,然后最近做一些实验需要一个稳定的长时间在线的Linux实例。

多方面考虑下来还是要在NAS上开个虚拟机,既然都开了,不妨把网络问题一并解决吧。

env:

  • ubuntu 20.04 (LTS)
  • clash v1.10.0
  • iptables v1.8.4 (legacy)

install

1. 开启转发

vim /etc/sysctl.conf

# 去掉注释
net.ipv4.ip_forward = 1
# 生效
sysctl -p

2. 安装 clash

https://github.com/Dreamacro/clash

下载release, 解压出来

# 添加可执行权限
chmod +x clash

mkdir config

把你机场的配置文件放在 config 目录下

mv /tmp/ipel.yaml config/config.yaml

设置 redir-port

# HTTP 代理端口
# 不需要了 可以关掉
# port: 7890 

# SOCKS5 代理端口
# 不需要了 可以关掉
# socks-port: 7891 

# Linux 和 macOS 的 redir 代理端口
redir-port: 7892 

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

# Clash 的 RESTFUL API
external-controller: '0.0.0.0:9090'

3. 运行clash

./clash -d config/ 

4. 配置 DNS

此处很关键。

  1. 要保证不用透明代理的客户端访问网络是正常的
  2. 还要保证用透明代理的客户端访问国际网络的资源是正常解析的

所以计划是:

不走透明代理的客户端 使用路由器的网关和DNS,设置了透明代理的客户端使用这个server上的网关和DNS。

ubuntu 新版本都会自带一个本地DNS服务,非常难用 禁用掉。

sudo systemctl disable systemd-resolved.service
sudo systemctl stop systemd-resolved

配置 clash 开启 DNS

vim config/config.yaml
dns:
  enable: true
  ipv6: false
  # 本地DNS禁用掉之后 53 端口就可以用了
  listen: 0.0.0.0:53
  enhanced-mode: fake-ip
  fake-ip-range: 198.18.0.1/16
  nameserver:
    - '1.1.1.1'

5. iptables

这里非常关键

顺序都不能错

# 在 nat 下 创建 clash 规则
iptables -t nat -N clash
iptables -t nat -N clash_dns

# 让当前机器成为一个网关服务器
iptables -t filter -A FORWARD -j ACCEPT
iptables -t nat -A POSTROUTING -s 192.168.0.0/16 -j MASQUERADE

# 这个是 fake-ip 对应的dns地址,一般不用动
iptables -t nat -A PREROUTING -p tcp --dport 53 -d 198.19.0.0/24 -j clash_dns
iptables -t nat -A PREROUTING -p udp --dport 53 -d 198.19.0.0/24 -j clash_dns
iptables -t nat -A PREROUTING -p tcp -j clash

# 这里需要注意的是,--to-destination 是 clash 在 局域网中的地址
# 因为直接开启了 53 端口, 这两个配置不生效了,放着不管就行
# iptables -t nat -A clash_dns -p udp --dport 53 -d 198.19.0.0/24 -j DNAT --to-destination 192.168.50.35:5353
# iptables -t nat -A clash_dns -p tcp --dport 53 -d 198.19.0.0/24 -j DNAT --to-destination 192.168.50.35:5353

# 绕过一些内网地址,(RETURN 表示退出当前Chain,返回到上一级的Chain继续匹配)
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

# 注意, 这边的 7892 对应 clash 配置里的 redir-port
iptables -t nat -A clash -p tcp -j REDIRECT --to-ports 7892

6. clash service (optional)

把 clash 写成 service 就不用想办法把它弄到后台了

vim /lib/systemd/system/clash.service 
[Unit]
Description=Clash Service
After=network.target

[Service]
Type=simple
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

ExecStart=/home/ubuntu/clash/clash-linux-amd64 -d /home/ubuntu/clash/config

[Install]
WantedBy=multi-user.target

启动和停止

# 两种方法均可以用
service clash start

systemctl stop clash

7. web ui (optional)

有很多 web ui 可以用

在 settings 里把 地址指向网关的 9090 端口就可以了

8. 客户端配置

步骤如下:

  1. 记下路由器分配的IP地址和掩码 (这两个不变)
  2. 设置 网关/路由器 和 DNS 地址 为网关地址

// 图片已丢失

windows settings

这里以 windows 11 设置为例,macOS 需要在两个页面中分别设置。操作步骤一样。

trouble shoot

  1. 网关没有被透明代理 (正常现象,网关要也想被透明代理 还需要增加 iptables 规则,我个人觉得没必要 不展开来讲了)
  2. 怎么清除规则 (iptables -t nat -F clash
  3. 怎么重置 iptables 规则 (见下文)
  4. 怎么保存 iptables 规则 (见下文)
  5. 怎么从网络更新 clash 配件文件?(不能 因为还有自定义的配置要修改,手动下载配置 按照上面的配置文件修改 然后重启 clash)

重置 iptables 规则

# reset the default policies in the filter table.
iptables -P INPUT ACCEPT
iptables -P FORWARD ACCEPT
iptables -P OUTPUT ACCEPT
# reset the default policies in the nat table.
iptables -t nat -P PREROUTING ACCEPT
iptables -t nat -P POSTROUTING ACCEPT
iptables -t nat -P OUTPUT ACCEPT
# reset the default policies in the mangle table.
iptables -t mangle -P PREROUTING ACCEPT
iptables -t mangle -P OUTPUT ACCEPT
# flush all the rules in the filter and nat tables.
iptables -F
iptables -t nat -F
iptables -t mangle -F
# erase all chains that's not default in filter and nat table.
iptables -X
iptables -t nat -X
iptables -t mangle -X

保存 iptables 规则

不通的操作系统 位置不一样 此处使用 Ubuntu, 更多规则参见 refs

iptables-save  > /etc/iptables/rules.v4
iptables-restore < /etc/iptables/rules.v4

refs