Clash支持使用redir参数搭配iptables进行透明代理设置,但是问题在于,我认为clash客户端的一大优势在于其基于规则转发流量的工作模式,而这种模式在使用iptables进行透明代理时却是失效的。
系统环境:
Ubuntu 18.04 x64
Clash v0.13.0
Clash配置文件:
port: 7890
socks-port: 7891
redir-port: 7892
allow-lan: false
mode: Rule
log-level: info
external-controller: "127.0.0.1:9090"
secret: ""
cfw-bypass:
- localhost
- 127.*
- 10.*
- 172.16.*
- 172.17.*
- 172.18.*
- 172.19.*
- 172.20.*
- 172.21.*
- 172.22.*
- 172.23.*
- 172.24.*
- 172.25.*
- 172.26.*
- 172.27.*
- 172.28.*
- 172.29.*
- 172.30.*
- 172.31.*
- 192.168.*
- <local>
cfw-latency-timeout: 3000
Proxy:
...
Proxy Group:
...
dns:
enable: true
listen: 127.0.0.1:53
enhanced-mode: redir-host
nameserver:
- 114.114.114.114
- 223.5.5.5
fallback:
- 'tls://1.1.1.1:853'
- 'tcp://1.1.1.1'
- 'tcp://208.67.222.222:443'
- 'tls://dns.google'
Rule:
规则省略
iptables配置如下:
# Generated by iptables-save v1.6.1 on Sat Apr 6 01:06:59 2019
*nat
:PREROUTING ACCEPT [4:355]
:INPUT ACCEPT [4:355]
:OUTPUT ACCEPT [624:44412]
:POSTROUTING ACCEPT [258:16016]
:SS-TCP - [0:0]
-A PREROUTING -s 192.168.0.0/16 -p tcp -j SS-TCP
-A OUTPUT -p tcp -j SS-TCP
-A POSTROUTING -s 192.168.0.0/16 -j MASQUERADE
-A SS-TCP -d 0.0.0.0/8 -j RETURN
-A SS-TCP -d 127.0.0.0/8 -j RETURN
-A SS-TCP -d 10.0.0.0/8 -j RETURN
-A SS-TCP -d 169.254.0.0/16 -j RETURN
-A SS-TCP -d 172.16.0.0/12 -j RETURN
-A SS-TCP -d 192.168.0.0/16 -j RETURN
-A SS-TCP -d 224.0.0.0/4 -j RETURN
-A SS-TCP -d 240.0.0.0/4 -j RETURN
-A SS-TCP -d my_server -j RETURN
-A SS-TCP -p tcp -j REDIRECT --to-ports 7892
COMMIT
# Completed on Sat Apr 6 01:06:59 2019
# Generated by iptables-save v1.6.1 on Sat Apr 6 01:06:59 2019
*filter
:INPUT ACCEPT [2370539:820800027]
:FORWARD ACCEPT [0:0]
:OUTPUT ACCEPT [2311295:519200391]
COMMIT
# Completed on Sat Apr 6 01:06:59 2019
这样配置,需要经过clash代理的流量能正常发出,但是clash规则中设为DIRECT的流量又会匹配到上面规则中的-A SS-TCP -p tcp -j REDIRECT --to-ports 7892规则,再被发回clash……这样就形成了死循环。
当然,为了避免这样的情况出现,我们可以使用ipset来指示iptables绕开大陆IP,那么问题在于,如果这样做了,使用clash作为透明代理还有意义吗?(为什么不直接使用ss-redir?)
是否有办法解决这一问题并同时享受到clash的基于规则的先进之处呢?或者说,[基于规则的透明代理]本身就是个悖论?
这个问题很好解决,但依靠cash本身不能,需要其他软件,譬如Stunnel,创建一个http/socks5作为出口,
在Proxy添加:
- { name: "Stunnel.HTTP.direct", type: http, server: 127.1.0.1, port: 8080 }
然后把Rule中的DIRECT替换为Stunnel.HTTP.direct即可
用一个单独的用户启动,使用 iptables的 owner 模块,在 iptables 筛选 这个用户的流量不过代理即可
-m owner --uid-owner 1000 -j RETURN
LazyZhu notifications@github.com 于 2019年4月6日周六 06:17写道:
这个问题很好解决,但依靠cash本身不能,需要其他软件,譬如Stunnel,创建一个http/socks5作为出口,
在Proxy添加:
- { name: "Stunnel.HTTP.direct", type: http, server: 127.1.0.1, port: 8080 }
然后把Rule中的DIRECT替换为Stunnel.HTTP.direct即可
—
You are receiving this because you are subscribed to this thread.
Reply to this email directly, view it on GitHub
https://github.com/Dreamacro/clash/issues/158#issuecomment-480439515,
or mute the thread
https://github.com/notifications/unsubscribe-auth/ABBMq5wC0GgCWzz5FHiQf-XTLwhn0Fwgks5vd8twgaJpZM4cfXqt
.
好吧 看错问题了
建议使用 uid/cgroup 来 处理回环问题
让 clash 运行在 某个 uid/cgroup 下
配合 iptables 的 owner/cgroup 模块
即可防止回环
个人建议使用 cgroup
这样还能 让某些进程绕过 透明代理
具体 Google
cgroup net_cls
之前的回答
你可能需要配置 DNS 指向 clash
无论是 iptables 重定向
还是 /etc/resolve.conf
最 practical 的做法是 Clash 支援給流量打上 fwmark, 這樣可以不用到 owner module
最 practical 的做法是 Clash 支援給流量打上 fwmark, 這樣可以不用到 owner module
長見識了,謝謝指教。
On Sun, May 5, 2019 at 10:41 PM Kr328 notifications@github.com wrote:
最 practical 的做法是 Clash 支援給流量打上 fwmark, 這樣可以不用到 owner module
- fwmark 可能 只是 你认为的 最佳实践
但却不是 go 语言的最佳实践
因为这个实现 是 平台相关(Linux Only) 的- fwmark 的使用 会破坏 最小权限原则
给 socket 打 fwmark 仅仅能够在 ROOT/CAP_NET_ADMIN 权限下- 相对的 使用 uid/cgroup 不会 需要在 clash 的 go 代码上 增加任何 的 平台相关代码
也能够将权限限制在最小(甚至 nobody)—
You are receiving this because you commented.
Reply to this email directly, view it on GitHub
https://github.com/Dreamacro/clash/issues/158#issuecomment-489432691,
or mute the thread
https://github.com/notifications/unsubscribe-auth/AB6FI76RQ62HAJH6LSH2MMDPT3WZ7ANCNFSM4HD5PKWQ
.
我不知道 @fourstring iptables 是怎么配置的,但是执行
iptables -t nat -N clash
iptables -t nat -A PREROUTING -p tcp -j clash
iptables -t nat -A clash -p tcp -j REDIRECT --to-ports 7892
是没有问题、不会出现回环的。
問題在 OP 的這條吧 -A OUTPUT -p tcp -j SS-TCP
在路由器上配置,如果不给 OUTPUT 链加 REDIRECT 的话,是不会出现回环的。
但是路由器本身就不能通过 REDIRECT 使用代理了。

@comzyh @BirkhoffLee
我去重新学习了一遍 iptables。
Close because of the issue resolved.
v2ray也是给流量打标签的,看起来挺简洁优雅的
附注:如果需要使用到一些会更改 cgroups 的服务(例如 Docker 或 KVM),则建议使用 uid/group 来过滤(例如 iptables -A SS-TCP -m owner --gid-owner 514 -j RETURN)而不是 cgroups (例如 iptables -t nat -A SS-TCP -m cgroup --path "bypass.slice" -j RETURN)来处理回环问题,原因是 cgroups 过滤器在它们启动时可能会失效,而且在它们关闭后也不会恢复为有效状态 (目前我尚不清楚原因) 。
更新:原因是 Docker 启用了 net_cli 和 net_prio 两个控制器,导致 cgroup 过滤不能工作。参见 springzfx/cgproxy#3。
mark
Most helpful comment
用一个单独的用户启动,使用 iptables的 owner 模块,在 iptables 筛选 这个用户的流量不过代理即可
-m owner --uid-owner 1000 -j RETURN
LazyZhu notifications@github.com 于 2019年4月6日周六 06:17写道: