网关代理(透明代理)
最近 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
此处很关键。
- 要保证不用透明代理的客户端访问网络是正常的
- 还要保证用透明代理的客户端访问国际网络的资源是正常解析的
所以计划是:
不走透明代理的客户端 使用路由器的网关和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. 客户端配置
步骤如下:
- 记下路由器分配的IP地址和掩码 (这两个不变)
- 设置 网关/路由器 和 DNS 地址 为网关地址
// 图片已丢失
这里以 windows 11 设置为例,macOS 需要在两个页面中分别设置。操作步骤一样。
trouble shoot
- 网关没有被透明代理 (正常现象,网关要也想被透明代理 还需要增加 iptables 规则,我个人觉得没必要 不展开来讲了)
- 怎么清除规则 (
iptables -t nat -F clash
) - 怎么重置 iptables 规则 (见下文)
- 怎么保存 iptables 规则 (见下文)
- 怎么从网络更新 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