cproxy: 使用简单的 Linux per app 透明代理

2021-02-24 22:29:45 +08:00
 iceorange

刚开源了我的新项目 cproxy: https://github.com/NOBLES5E/cproxy

解决的问题和 proxychains 一样,就是对单独进程走代理,而不需要进程本身支持代理。

使用上和 proxychains 一样简单,但是可以代理 TCP, UDP 并且对静态链接的程序(比如像 docker 这样的 Go 程序) 和已经在运行的程序也可以进行代理。

之前也用过 graftcp 等等软件,大部分情况下挺好用。不过 graftcp 每次要起两个程序,而且最近有代理 DNS 请求的需求了,只好自己动手了。

既然开源出来了,还是希望更多人能知道,对大家产生帮助,也收集一下建议。欢迎讨论~

15194 次点击
所在节点    程序员
29 条回复
tia
2021-02-24 22:37:01 +08:00
支持一下
cathedrel
2021-02-24 22:57:46 +08:00
大佬,能不能写个“Linux all app 透明代理”? 所有流量,tcp,udp,icmp,全部自动走?功能和配置都简单一点,类似 proxifier 设置好代理地址就能代理整个系统的?在 github 上找到两个,但是都有点复杂,在 alpine linux 上都跑不起来......您要是做了这个,功德无量啊~~~
holyzhou
2021-02-24 22:57:52 +08:00
好像有点意思 star 一个
generic
2021-02-25 00:09:08 +08:00
@cathedrel 全部流量那你 vpn 呀。
Kobayashi
2021-02-25 00:42:13 +08:00
@cathedrel 试试 clash,不确定 UDP 、ICMP 是否支持。
Jirajine
2021-02-25 01:09:23 +08:00
还以为是又发明了什么新的魔法,一看是操作防火墙的。
而且是通过调用 iptables 命令操作,十分不合适。
没有原子性、性能也不好,并发启动很可能出问题。
正确的做法应该是通过 libnftnl 这样的库。
而且你这样没必要用 rust 啊,直接用 shell 脚本更合适。
iceorange
2021-02-25 01:36:32 +08:00
@Jirajine 谢谢,

1. 修改 iptables 不觉得哪里 low 了,请问是解决不了什么问题?
2. 关于是调用库还是调用 iptables 命令这个问题我一开始思考过。在这种场景下,原子性没有影响,因为子进程是所有 iptables rule apply 完再 spawn 的,子进程退出后才会进行 iptables 的清空操作。说到性能问题就莫名其妙了,调用几行 iptables 命令的开销在这个使用场景中值得考虑?并发启动没看出问题,请教一下。
3. 不用 libnftnl 可能的好处:不需要整个程序 uid 0,同时支持 nftables 和 iptables 。
4. 能用 rust 更好地组织代码干嘛非得写个 shell ?

最后,希望能以一个正常讨论的态度对话,谢谢。
Jirajine
2021-02-25 02:10:51 +08:00
@iceorange 想象一下用户用你的工具并发启动多个进程,多个进程同时操作 iptables 会怎样。
nftables 一大亮点就是提供了多个程序并发操作防火墙的原子性。
因为你的核心逻辑基本是 shell 命令实现的,每次都需要需要启动多个外部进程,开销不小。
既然用 shell 命令实现,为啥不用 shell 脚本呢。
iceorange
2021-02-25 02:17:57 +08:00
@Jirajine
1. 多个进程同时操作 iptables 没有问题啊,子进程只有在该子进程需要的 rule apply 后才会 spawn 。不同进程使用的 rule 是不同的。
2. 为什么非要纠结 iptables 调用的开销呢,一般所代理的程序运行开销远高于 iptables 调用,所以不能 justify 使用 libnftables 更好,详见上述使用 libnftables 带来的问题
3. 使用了外部程序就得用 shell 这个逻辑实在是不通。写 shell 光那一堆错误检查得写很多行。parse 命令得写很多行。安装 signal handler 得写很多行。懂得都懂。
iceorange
2021-02-25 02:24:58 +08:00
@Jirajine
其实是有一个 fundamental 的认知问题,工具的重点是能够解决新的痛点问题,而不是用了什么魔法。
v2webdev
2021-02-25 03:13:02 +08:00
这个项目在 Hacker News 上火了呢。
cathedrel
2021-02-25 04:46:45 +08:00
@Kobayashi 我说的在 alpine linux 上跑不起来的两个之一就是 clash,alpine 上面装了 tun,装了 glibc,也试过 chroot 的 arch 里跑,全部失败
gleport
2021-02-25 09:06:22 +08:00
回应一下楼主说的 graftcp 每次要起两个程序的问题:graftcp-local 是设计为守护进程方式使用的,"sudo systemctl --now enable graftcp-local.service" 后使用方式和 proxychains 基本一致。
iceorange
2021-02-25 09:26:26 +08:00
@gleport 是的,只需要代理 tcp 的话 graftcp 已经很好用了
我平时用 graftcp 的时候主要有两个需求解决不了,一个是代理 DNS 。另一个是像是已经运行起来的 docker,经常需要走代理 docker pull 些内网私有 image,用 graftcp 的话我得每次先修改 docker.service 让他套上 graftcp 然后重启 service,用完再改回去,没法直接让现有 docker 进程代理
gfreezy
2021-02-25 09:28:30 +08:00
@cathedrel 可以看下我写的这个 https://github.com/gfreezy/seeker
yanqiyu
2021-02-25 09:29:28 +08:00
让我想起这个项目 https://github.com/springzfx/cgproxy,不过 cgproxy 是一个 daemon,监听 cgroup 然后对于设置的 slice 等应用代理
muxueqz
2021-02-25 09:53:30 +08:00
@iceorange 嗯,这个思路挺有趣的,不过用 shell 实现也有个好处:依赖更少,不需要编译。目前的实现已经很接近 shell 了

哈,不过当然是想用什么实现就用什么实现了
iceorange
2021-02-25 10:19:28 +08:00
@yanqiyu
诶 这个使用和系统要求不同,但是在实现原理上和 cproxy 非常接近。我一会把它补充到 readme 里。
nmap
2021-02-25 11:17:53 +08:00
技术原理是什么呢?
iceorange
2021-02-25 11:22:49 +08:00
@nmap 简单说其实就是为需要代理的程序创建一个独立的 cgroup,通过 netfilter 把这个 cgroup 的网络流量全部重定向。

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/755999

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX