Clash透明代理实现方式总结
什么是透明代理呢?
透明代理,全程为透明代理网关,透明
就是感觉不到,透明代理
就是感觉不到自己使用代理。 至于什么网站地址可以使用代理这样的规则判断都交给了网关
去处理。
因此,网关
实际上起着流量转发的作用,将需要使用代理的请求
中转到代理客户端处理,将不需要使用代理的请求正常处理。
在什么位置实现透明代理?
正常家庭上网的模式是这样的:
Phone/PC/Pad
|
1 |
|
+-------v-------+ 2 +--------+
| |-------------> |
| WiFi 路由器 | | 树莓派 |
| <-------------| |
+------+--+-----+ 3 +--------+
| |
3.1| | 3.2
| +----------> China LAN
v
+---+---+
| Proxy |
+---+---+
|
|
v
Internet WAN
这里的
树莓派
是可选设备,如果你打算实现旁路由
。
- 透明代理需要接管局域网中所有流量,因此
路由器
是最适合实现透明代理
的位置(这也是为何很多人要刷改版第三方固件原因)。 - 路由器的硬件类型和配置千差万别,实现代理软件类型也不同,因此不是所有透明代理实现方案都通用,我们会选择比较通用的方案介绍。
实现透明代理的两个关键点:
- DNS转发: 决定哪些域名需要更换更合理的DNS服务器处理。
- 代理转发: 决定哪些域名使用代理转发请求。
常见DNS转发服务端:
Dnsmasq
: 通常路由器默认的DNS服务端,是一个开源的轻量级DNS转发和DHCP、TFTP服务器,使用C语言编写。优点:资源占用低,易于配置。支持的平台包括Linux、BSD、Smoothwall、IP-Cop、floppyfw、Firebox、LEAF、Freesco, fli4l、CoyoteLinux及Android等,并且在dd-wrt、openwrt路由器系统中也有使用,dnsmasq源码地址。Clash
: Clash内置的比较丰富的DNS转发规则,使用Go语言编写,同时也是一个支持多协议的代理客户端,一个软件具备了透明代理的两个关键功能。
DNS客户端
和代理客户端
的种类比较多,这里无法一一列举。
透明代理的核心是规则
,Linux
系统自带的iptables
可以使用Forwarding
转发规则来自定义网络请求规则。
iptables实现透明代理
路由器环境:
- CPU架构:Armv7l 不支持VPF,因此要使用
Armv5
可执行程序。 - 路由器固件: KS梅林380版本
- Clash选择版本: Clash Premium v1.7.0(2021.09.07版)
- dnsmasq版本: 路由器自带。
实现透明代理大致过程:
iptables
的作用:
- 转发
80
、443
目标端口请求到Clash
的 1080 端口进行代理中转。 - 转发UDP的
53
端口到Clash
的1053
端口进行DNS解析
。
Clash
服务的作用:
- 根据URL规则判断是
直连
还是代理透传
。 - 根据
DNS规则
判断使用哪个DNS服务器
进行DNS解析。
接下来,详细介绍每个服务的操作。
iptables
配置规则
大部分Linux系统都支持
iptables
,包括路由器。
因此此方法通用所有Linux系统。
这里要完成的内容:
- 定义链表 TCP 端口为80/443 请求转发给 Clash服务的
redir-port
端口。 - 定义链表 UDP 端口为53 请求转发给 Clash服务的
dns.listen
端口。
这里没有什么复杂的ipset规则定义,因为规则都交给了Clash
实现配置。如果你没有使用Clash
,那么这里你需要使用到了ipset
定义URL规则保证只转发需要走代理的TCP请求通过Clash
处理。
设置iptables
命令如下:
lan_ipaddr="192.168.50.1" # 局域网路由器IP地址
dns_port="1053" # DNS转发服务端口
redir_port="3333" # 透明代理转发端口
iptables -t nat -N CLASH_TCP_RULE
iptables -t nat -F CLASH_TCP_RULE
iptables -t nat -A PREROUTING -p tcp -s ${lan_ipaddr}/16 -j CLASH_TCP_RULE
# Fake-IP 规则添加
iptables -t nat -A OUTPUT -p tcp -d 198.18.0.0/16 -j REDIRECT --to-port ${redir_port}
# 本地地址请求不转发
iptables -t nat -A CLASH_TCP_RULE -d 10.0.0.0/8 -j RETURN
iptables -t nat -A CLASH_TCP_RULE -d 127.0.0.0/8 -j RETURN
iptables -t nat -A CLASH_TCP_RULE -d 169.254.0.0/16 -j RETURN
iptables -t nat -A CLASH_TCP_RULE -d 172.16.0.0/12 -j RETURN
iptables -t nat -A CLASH_TCP_RULE -d ${lan_ipaddr}/16 -j RETURN
# 服务端口3333接管HTTP/HTTPS请求转发
iptables -t nat -A CLASH_TCP_RULE -s ${lan_ipaddr}/16 -p tcp -m multiport --dport 80,443 -j REDIRECT --to-ports ${redir_port}
# 转发DNS请求到端口 dns_port 解析
iptables -t nat -N CLASH_DNS_RULE
iptables -t nat -F CLASH_DNS_RULE
iptables -t nat -A CLASH_DNS_RULE -p udp -s ${lan_ipaddr}/16 --dport 53 -j REDIRECT --to-ports $dns_port
iptables -t nat -I OUTPUT -p udp --dport 53 -j CLASH_DNS_RULE
iptables -t nat -A PREROUTING -p udp -s ${lan_ipaddr}/16 --dport 53 -j CLASH_DNS_RULE
当不想使用
iptables
规则时,当然要记得清理掉不需要的配置。否则路由器不知道会出现什么问题。
清除iptables
规则的命令如下:
# 清理iptables规则
iptables -t nat -D PREROUTING -p tcp -s ${lan_ipaddr}/16 -j CLASH_TCP_RULE
iptables -t nat -F CLASH_TCP_RULE
iptables -t nat -X CLASH_TCP_RULE
iptables -t nat -D PREROUTING -p udp -s ${lan_ipaddr}/16 --dport 53 -j CLASH_DNS_RULE
iptables -t nat -D OUTPUT -p udp --dport 53 -j CLASH_DNS_RULE
iptables -t nat -F CLASH_DNS_RULE
iptables -t nat -X CLASH_DNS_RULE
就这样,我们实现
DNS
请求和HTTP/HTTPS
协议请求都转发给了Clash
的工作。下一步,我们就要操作
Clash
完成规则的配置。
Clash配置规则
分两部分说明:
- DNS请求转发配置
- 代理转发规则配置
DNS请求转发配置
Clash支持两种DNS模式:
redir-host
: 传统的DNS转发模式,局域网根据规则查询DNS请求获取真实IP地址。fake-ip
: 伪造IP模式,内部DNS查询得到的是伪造IP段的某个地址,局域网使用伪IP与Clash
通信,Clash
会根据伪IP找到真实IP使用SOCKS代理进行通信。
下面是详细的DNS配置:
# 透明代理开启DNS
dns:
enable: true
ipv6: false
listen: 0.0.0.0:1053
enhanced-mode: redir-host # redir-host or fake-ip
# fake-ip-range: 198.18.0.1/16 # Fake IP addresses pool CIDR
use-hosts: true # lookup hosts and return IP record
nameserver:
- 119.29.29.29 # DNSpod DNS 17ms
- 223.5.5.5 # 阿里 19ms
# 提供 fallback 时,如果GEOIP非 CN 中国时使用 fallback 解析
fallback:
- tls://8.8.8.8:853 # Google DNS over TLS 50ms
- tls://8.8.4.4:853 # cloudflare DNS over TLS 50ms
- https://1.1.1.1/dns-query # cloudflare DNS over HTTPS
- https://dns.google/dns-query # Google DNS over HTTPS
# 强制DNS解析使用`fallback`配置
fallback-filter:
# true: CN使用nameserver解析,非CN使用fallback
geoip: true
# geoip设置为false时有效: 不匹配`ipcidr`地址时会使用`nameserver`结果,匹配`ipcidr`地址时使用`fallback`结果。
ipcidr:
- 240.0.0.0/4
切换使用redir-host
或fake-ip
模式也很简单, 修改enhanced-mode: fake-ip
,去掉fake-ip-range
前面的#
号。
然后在iptables
中增加如下语句:
# Fake-IP 规则添加
iptables -t nat -A OUTPUT -p tcp -d 198.18.0.0/16 -j REDIRECT --to-port ${redir_port}
其中的${redir_port}
需要替换成Clash
转发端口例如3333
。
DNS
解析问题已经解决啦! 到这里就解决了DNS污染
问题。但还有很多问题导致我们访问的网站链接被重置或无法访问。
因此,接下来,还要使用Clash
转发代理进行HTTP/HTTPS请求转发。
Clash代理规则配置
我们之前已经使用iptables
将80、443
端口请求(也就是HTTP/HTTPS)请求都转发给3333
端口(Clash的转发端口)。
因此,我们只需要在Clash
中设置规则,决定哪些请求走代理转发,哪些直接转发。这些规则在Clash
中配置起来非常简单。
我们看下Clash Premium
版本支持的rule-providers
配置内容:
# 专业版支持 rule-providers
rule-providers:
reject:
type: http
behavior: domain
url: "https://cdn.jsdelivr.net/gh/Loyalsoldier/[email protected]/reject.txt"
path: ./ruleset/reject.yaml
interval: 86400
icloud:
type: http
behavior: domain
url: "https://cdn.jsdelivr.net/gh/Loyalsoldier/[email protected]/icloud.txt"
path: ./ruleset/icloud.yaml
interval: 86400
apple:
type: http
behavior: domain
url: "https://cdn.jsdelivr.net/gh/Loyalsoldier/[email protected]/apple.txt"
path: ./ruleset/apple.yaml
interval: 86400
google:
type: http
behavior: domain
url: "https://cdn.jsdelivr.net/gh/Loyalsoldier/[email protected]/google.txt"
path: ./ruleset/google.yaml
interval: 86400
proxy:
type: http
behavior: domain
url: "https://cdn.jsdelivr.net/gh/Loyalsoldier/[email protected]/proxy.txt"
path: ./ruleset/proxy.yaml
interval: 86400
direct:
type: http
behavior: domain
url: "https://cdn.jsdelivr.net/gh/Loyalsoldier/[email protected]/direct.txt"
path: ./ruleset/direct.yaml
interval: 86400
private:
type: http
behavior: domain
url: "https://cdn.jsdelivr.net/gh/Loyalsoldier/[email protected]/private.txt"
path: ./ruleset/private.yaml
interval: 86400
gfw:
type: http
behavior: domain
url: "https://cdn.jsdelivr.net/gh/Loyalsoldier/[email protected]/gfw.txt"
path: ./ruleset/gfw.yaml
interval: 86400
greatfire:
type: http
behavior: domain
url: "https://cdn.jsdelivr.net/gh/Loyalsoldier/[email protected]/greatfire.txt"
path: ./ruleset/greatfire.yaml
interval: 86400
tld-not-cn:
type: http
behavior: domain
url: "https://cdn.jsdelivr.net/gh/Loyalsoldier/[email protected]/tld-not-cn.txt"
path: ./ruleset/tld-not-cn.yaml
interval: 86400
telegramcidr:
type: http
behavior: ipcidr
url: "https://cdn.jsdelivr.net/gh/Loyalsoldier/[email protected]/telegramcidr.txt"
path: ./ruleset/telegramcidr.yaml
interval: 86400
cncidr:
type: http
behavior: ipcidr
url: "https://cdn.jsdelivr.net/gh/Loyalsoldier/[email protected]/cncidr.txt"
path: ./ruleset/cncidr.yaml
interval: 86400
lancidr:
type: http
behavior: ipcidr
url: "https://cdn.jsdelivr.net/gh/Loyalsoldier/[email protected]/lancidr.txt"
path: ./ruleset/lancidr.yaml
interval: 86400
# 黑名单模式,命中规则使用代理
rules:
- PROCESS-NAME,v2ray,DIRECT
- PROCESS-NAME,xray,DIRECT
- PROCESS-NAME,naive,DIRECT
- PROCESS-NAME,trojan,DIRECT
- PROCESS-NAME,trojan-go,DIRECT
- PROCESS-NAME,ss-local,DIRECT
- PROCESS-NAME,privoxy,DIRECT
- PROCESS-NAME,leaf,DIRECT
- PROCESS-NAME,v2ray.exe,DIRECT
- PROCESS-NAME,xray.exe,DIRECT
- PROCESS-NAME,naive.exe,DIRECT
- PROCESS-NAME,trojan.exe,DIRECT
- PROCESS-NAME,trojan-go.exe,DIRECT
- PROCESS-NAME,ss-local.exe,DIRECT
- PROCESS-NAME,privoxy.exe,DIRECT
- PROCESS-NAME,leaf.exe,DIRECT
- PROCESS-NAME,Surge,DIRECT
- PROCESS-NAME,Surge 2,DIRECT
- PROCESS-NAME,Surge 3,DIRECT
- PROCESS-NAME,Surge 4,DIRECT
- PROCESS-NAME,Surge%202,DIRECT
- PROCESS-NAME,Surge%203,DIRECT
- PROCESS-NAME,Surge%204,DIRECT
- PROCESS-NAME,Thunder,DIRECT
- PROCESS-NAME,DownloadService,DIRECT
- PROCESS-NAME,qBittorrent,DIRECT
- PROCESS-NAME,Transmission,DIRECT
- PROCESS-NAME,fdm,DIRECT
- PROCESS-NAME,aria2c,DIRECT
- PROCESS-NAME,Folx,DIRECT
- PROCESS-NAME,NetTransport,DIRECT
- PROCESS-NAME,uTorrent,DIRECT
- PROCESS-NAME,WebTorrent,DIRECT
- PROCESS-NAME,aria2c.exe,DIRECT
- PROCESS-NAME,BitComet.exe,DIRECT
- PROCESS-NAME,fdm.exe,DIRECT
- PROCESS-NAME,NetTransport.exe,DIRECT
- PROCESS-NAME,qbittorrent.exe,DIRECT
- PROCESS-NAME,Thunder.exe,DIRECT
- PROCESS-NAME,ThunderVIP.exe,DIRECT
- PROCESS-NAME,transmission-daemon.exe,DIRECT
- PROCESS-NAME,transmission-qt.exe,DIRECT
- PROCESS-NAME,uTorrent.exe,DIRECT
- PROCESS-NAME,WebTorrent.exe,DIRECT
- DOMAIN,clash.razord.top,DIRECT
- DOMAIN,yacd.haishan.me,DIRECT
- RULE-SET,private,DIRECT
- RULE-SET,reject,REJECT
- RULE-SET,direct,DIRECT
- RULE-SET,cncidr,DIRECT
- RULE-SET,lancidr,DIRECT
- RULE-SET,tld-not-cn,PROXY
- RULE-SET,gfw,PROXY
- RULE-SET,greatfire,PROXY
- RULE-SET,telegramcidr,PROXY
- RULE-SET,google,PROXY
- RULE-SET,proxy,PROXY
- RULE-SET,apple,PROXY
- RULE-SET,icloud,DIRECT
- MATCH,DIRECT
看着有点长,但是与直接将每个域名都写进来相比已经很短了。
使用rule-provider
的好处就是,规则可以定时更新,而且配置内容很规整。至于使用白名单还是黑名单方式就是最后的规则集设置了。
- 黑名单模式,意为 「只有命中规则的网络流量,才使用代理」 ,适用于服务器线路网络质量不稳定或不够快,或服务器流量紧缺的用户。通常也是软路由用户、家庭网关用户的常用模式。
- 白名单模式,意为 「没有命中规则的网络流量,统统使用代理」 ,适用于服务器线路网络质量稳定、快速,不缺服务器流量的用户。
这里的配置方式采用了黑名单规则方式
。
白名单最后的配置如下:
rules:
...
...
...
- RULE-SET,private,DIRECT
- RULE-SET,reject,REJECT
- RULE-SET,icloud,DIRECT
- RULE-SET,apple,DIRECT
- RULE-SET,google,DIRECT
- RULE-SET,proxy,PROXY
- RULE-SET,direct,DIRECT
- RULE-SET,telegramcidr,PROXY
- GEOIP,,DIRECT
- GEOIP,CN,DIRECT
- MATCH,PROXY
如果你想看配置示例,这里可以查看一个支持代理订阅源的配置 config.yaml
完成透明代理配置
到这里,我们就完成了透明代理的所有工作。
再来回顾一下透明代理的实现过程:
- 配置
iptables
转发代理规则: 实现HTTP/HTTPS请求转发到Clash
转发端口3333
。 - 配置
iptables
转发DNS规则: 实现DNS请求转发到Clash
内置DNS服务1053
端口。 - 配置
Clash
代理转发规则: 根据URL规则集决定哪些URL通过代理转发请求。
希望通过这样的介绍,可以帮到你。
结尾:安全的DNS协议类型
通常普通DNS查询是不安全的,可以被别人跟踪记录的,为了解决安全问题就产生了
DoH
和DoT
等协议。
DoH(DNS over HTTPS)
: 一个进行安全化的域名解析方案。其意义在于以加密的HTTPS协议进行DNS解析请求,避免原始DNS协议中用户的DNS解析请求被窃听或者修改的问题(例如中间人攻击)来达到保护用户隐私的目的。Google及Mozilla基金会正在测试此协议,提高网络安全性。 支持DoH的公共DNS列表。DoT(DNS over TLS)
: 通过传输层安全协议(TLS)来加密并打包域名系统(DNS)的安全协议。此协议旨在防止中间人攻击与控制DNS数据以保护用户隐私。RFC 7858及RFC 8310定义了DNS over TLS
。 支持DoT的公共DNS列表。dns2socks
: 这个不是协议,而是将DNS查询请求通过SOCKS
代理做了个转发,如果SOCKS
代理隧道是安全的,那么这个过程就相对安全一些。到了隧道的另一端(代理服务端)之后是否安全还是看代理服务端是否使用了DoH
或DoT
协议进行转发。
按照这么配置下来网页都没啥问题;就是手机上google play和youtube的app都打不开;感觉是clash rule配置的问题
可以通过 yacd web界面中查看“连接”信息,如果透明代理设置成功可以看到内网连接请求以及匹配的rule规则使用了哪个代理。
有台网口带宽最大的win10想做完全代理服务器,其他机器所有流量都走这台机器的网卡。
在WSL2+Ubuntu20.04上安装docker desktop,docker desktop跑的clash。配置好以后用其他机器的系统的输入带宽最大的win10的IP:7890可以正常使用。iptables配置规则总是弄不成功。
Ubuntu20.04开启 ip 转发ipv4/ip_forward=1。clash网络用的桥接+端口转发,host模式显示运行成功,网页控制台进不去,IP:7890的代理模式也进不去,请问有什么思路吗?多谢!