Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Clash作为透明代理是否有意义? #158

Closed
fourstring opened this issue Apr 5, 2019 · 18 comments
Closed

Clash作为透明代理是否有意义? #158

fourstring opened this issue Apr 5, 2019 · 18 comments

Comments

@fourstring
Copy link

@fourstring fourstring commented Apr 5, 2019

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的基于规则的先进之处呢?或者说,[基于规则的透明代理]本身就是个悖论?

@LazyZhu
Copy link

@LazyZhu LazyZhu commented Apr 5, 2019

这个问题很好解决,但依靠cash本身不能,需要其他软件,譬如Stunnel,创建一个http/socks5作为出口,
Proxy添加:

  - { name: "Stunnel.HTTP.direct", type: http, server: 127.1.0.1, port: 8080 }

然后把Rule中的DIRECT替换为Stunnel.HTTP.direct即可

Loading

@comzyh
Copy link
Contributor

@comzyh comzyh commented Apr 5, 2019

Loading

@Kr328
Copy link
Collaborator

@Kr328 Kr328 commented Apr 17, 2019

好吧 看错问题了
建议使用 uid/cgroup 来 处理回环问题
让 clash 运行在 某个 uid/cgroup 下
配合 iptables 的 owner/cgroup 模块
即可防止回环

个人建议使用 cgroup
这样还能 让某些进程绕过 透明代理

具体 Google
cgroup net_cls


之前的回答

你可能需要配置 DNS 指向 clash
无论是 iptables 重定向
还是 /etc/resolve.conf

Loading

@BirkhoffLee
Copy link
Collaborator

@BirkhoffLee BirkhoffLee commented May 5, 2019

最 practical 的做法是 Clash 支援給流量打上 fwmark, 這樣可以不用到 owner module

Loading

@Kr328
Copy link
Collaborator

@Kr328 Kr328 commented May 5, 2019

最 practical 的做法是 Clash 支援給流量打上 fwmark, 這樣可以不用到 owner module

  1. fwmark 可能 只是 你认为的 最佳实践
    但却不是 go 语言的最佳实践
    因为这个实现 是 平台相关(Linux Only)
  2. fwmark 的使用 会破坏 最小权限原则
    给 socket 打 fwmark 仅仅能够在 ROOT/CAP_NET_ADMIN 权限下
  3. 相对的 使用 uid/cgroup 不会 需要在 clash 的 go 代码上 增加任何 的 平台相关代码 也能够将权限限制在最小(甚至 nobody)

Loading

@BirkhoffLee
Copy link
Collaborator

@BirkhoffLee BirkhoffLee commented May 5, 2019

Loading

@SukkaW
Copy link

@SukkaW SukkaW commented May 5, 2019

我不知道 @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

是没有问题、不会出现回环的。

Loading

@BirkhoffLee
Copy link
Collaborator

@BirkhoffLee BirkhoffLee commented May 5, 2019

問題在 OP 的這條吧 -A OUTPUT -p tcp -j SS-TCP

Loading

@comzyh
Copy link
Contributor

@comzyh comzyh commented May 6, 2019

在路由器上配置,如果不给 OUTPUT 链加 REDIRECT 的话,是不会出现回环的。
但是路由器本身就不能通过 REDIRECT 使用代理了。

Loading

@SukkaW
Copy link

@SukkaW SukkaW commented May 6, 2019

image

@comzyh @BirkhoffLee

我去重新学习了一遍 iptables。

Loading

@Dreamacro
Copy link
Owner

@Dreamacro Dreamacro commented Jun 6, 2019

Close because of the issue resolved.

Loading

@Dreamacro Dreamacro closed this Jun 6, 2019
@tony1016
Copy link

@tony1016 tony1016 commented Jun 6, 2019

v2ray也是给流量打标签的,看起来挺简洁优雅的

Loading

@outloudvi
Copy link

@outloudvi outloudvi commented Jul 27, 2020

附注:如果需要使用到一些会更改 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

Loading

@fbion
Copy link

@fbion fbion commented Jul 29, 2020

mark

Loading

@iamwwc
Copy link

@iamwwc iamwwc commented Jan 23, 2021

用一个单独的用户启动,使用 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 <#158 (comment)>, or mute the thread https://github.com/notifications/unsubscribe-auth/ABBMq5wC0GgCWzz5FHiQf-XTLwhn0Fwgks5vd8twgaJpZM4cfXqt .

uid模式,非 root 用户没有 CAP_NET_BIND_SERVICE权限,你是怎么启动的呢?

Loading

@aleung
Copy link

@aleung aleung commented Feb 26, 2021

uid模式,非 root 用户没有 CAP_NET_BIND_SERVICE权限,你是怎么启动的呢?

setcap 命令赋予权限。

如果是用systemd启动服务,在 service 配置中加上
AmbientCapabilities=CAP_NET_BIND_SERVICE CAP_NET_ADMIN

Loading

@matthuo333
Copy link

@matthuo333 matthuo333 commented Mar 5, 2021

OUTPUT

大神,如何能让路由器本身流量经clash出海呢?

Loading

@winkee01
Copy link

@winkee01 winkee01 commented Nov 30, 2021

看完了我还是有点困惑,到底会不会循环?我本机一直没有使用上面评论中所说 --uid-owner 这种方式,但是也可以正常上网。请问如果发生如题主所说的死循环,会有什么症状吗?

Loading

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Linked pull requests

Successfully merging a pull request may close this issue.

None yet