V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
Chingim
V2EX  ›  Apple

VRouter: 一个虚拟路由器, 旨在实现 OS X/macOS 上的透明代理

  Chingim · 2017-06-28 09:40:30 +08:00 · 20763 次点击
这是一个创建于 2706 天前的主题,其中的信息可能已经有所发展或是发生改变。

VRouter

解决的需求


OS X 上没有 linux 的 iptables, 无法直接将流量转发给本地的端口. 所有应用想走代理, 必须要先进行设置, 问题在于:

  • 有些应用不支持设置代理
  • 命令行软件虽然可以用 export http_proxy 的方式使用代理, 但有时并不管用. 需要进一步折腾 Proxifier 或者 Privoxy

所以为了实现透明代理, 通常有以下选择:

  • 用 surge 之类的软件
  • 在路由器设置代理

用 surge 最方便, 但是不便宜. 在路由器设置:

  • 一来受限于路由器的性能, 运行 kcptun 之类的软件资源吃紧
  • 二来路由器通常固定, 离开家 /公司需要使用代理时不方便

VRouter 是另一种透明代理的思路, 把路由器变成虚拟机, 接管系统流量, 它有以下特点:

  • 性能不受局限
  • 安装在系统上, 没有便携性的问题
  • 可配置性强, 毕竟是个 linux 发行版

缺点是:

  • 需要先安装 virtualbox
  • 无法服务局域网的其他设备

一些截图


111 条回复    2018-12-12 17:41:33 +08:00
1  2  
oott123
    1
oott123  
   2017-06-28 09:46:28 +08:00
支持,不过 VirtualBox 还是太重了吧,要是能用 HyperKit 之类的就好了……
foursking
    2
foursking  
   2017-06-28 09:47:40 +08:00
请问怎么安装
Chingim
    3
Chingim  
OP
   2017-06-28 09:49:12 +08:00
@oott123 其实虚拟的 openwrt 很轻量, 占用磁盘 30MB 以内, 运行内存 100MB 以内.

外面用 electron 套的壳倒是比核心大得多, 不过设置完就可以把界面关掉了
madeye
    4
madeye  
   2017-06-28 09:49:43 +08:00
赞!有计划开源吗?
madeye
    5
madeye  
   2017-06-28 09:50:09 +08:00
看到代码了~
taresky
    6
taresky  
   2017-06-28 09:50:24 +08:00 via iPhone
在本机装一个软路由… 太重了吧,功能优势很小。
Chingim
    7
Chingim  
OP
   2017-06-28 09:50:30 +08:00
@foursking 正文内有链接
下载运行, 填些代理参数就 OK
madeye
    8
madeye  
   2017-06-28 09:51:29 +08:00   ❤️ 6
不妨做成跨平台的方案,Windows 上的需求其实更大,特别是 Steam 上的各类联机游戏。
Chingim
    9
Chingim  
OP
   2017-06-28 09:53:28 +08:00
@madeye 后续计划吧, 欢迎大神提交 PR
xratzh
    10
xratzh  
   2017-06-28 09:53:58 +08:00 via iPhone
linux 也需要⁄(⁄ ⁄ ⁄ω⁄ ⁄ ⁄)⁄那个 qt-ss 基本都是残废
wwqgtxx
    11
wwqgtxx  
   2017-06-28 09:54:24 +08:00 via iPhone
同意 @madeye 的观点,我现在经常都用虚拟机开个 openwrt x64 来全局 fq
taresky
    12
taresky  
   2017-06-28 09:54:47 +08:00
感觉可以单独做成一个软路由系统,给 ikuai 之类的做二级路由使用。
@madeye Windows 的想法非常好!
Chingim
    13
Chingim  
OP
   2017-06-28 09:55:34 +08:00
@taresky 虽然是虚拟机, 但资源占用跟一般软件差不多, 全天候内存占用都在 100MB 以下:

![]( )
oott123
    14
oott123  
   2017-06-28 09:58:24 +08:00
@Chingim #3 VirtualBox 本身是个重量级的虚拟机方案,用来跑软路由,太重了,即使镜像很轻量……

所以为什么没有把这些功能全集成到镜像里,而是选择下载镜像安装呢(这样就可以提供镜像让用户自己虚拟机装了
wwqgtxx
    15
wwqgtxx  
   2017-06-28 09:59:22 +08:00 via iPhone
@taresky 单独的软路由系统倒是必要性不大,koolshare 的 lede x64 已经做的挺完美的了
clavichord93
    16
clavichord93  
   2017-06-28 10:00:34 +08:00 via iPhone
能耗怎么样?
Chingim
    17
Chingim  
OP
   2017-06-28 10:02:01 +08:00
@oott123 避免分发镜像是因为担心有安全隐患, 另外用了清华的 openwrt 源, 构造时间只需要几分钟, 也就不在乎分不分发镜像了.
osss
    18
osss  
   2017-06-28 10:04:00 +08:00
windows 下虚拟机可以用 hyperV,win8 以上都是自带组件
missdeer
    19
missdeer  
   2017-06-28 10:15:51 +08:00
好思路!赞!
Tunar
    20
Tunar  
   2017-06-28 10:20:25 +08:00 via Android
卡死到安装 dnsmasp-full 那步
demov2
    21
demov2  
   2017-06-28 10:20:50 +08:00
觉得是很独特而又很棒的思路。
miniers
    22
miniers  
   2017-06-28 10:22:11 +08:00
换成 docker 是不是更轻量点😂
oott123
    23
oott123  
   2017-06-28 10:22:52 +08:00
同 20# 卡死在装 dnsmasq-full
wwqgtxx
    24
wwqgtxx  
   2017-06-28 10:22:56 +08:00 via iPhone
@osss hv 最头疼的地方在于不能和其他 vm 并存,这点非常蛋疼
coderfox
    25
coderfox  
   2017-06-28 10:30:04 +08:00
我其实很好奇的是网络这里是怎么做的,方便讲解一下或者说一下在源码的哪个位置吗?

另外,不知道有没有用 Docker 实现的可能性。Docker 比 VirtualBox 要轻量一点。
johnlui
    26
johnlui  
   2017-06-28 10:30:44 +08:00
感觉很给力的样子!

话说,本地 TCP 代理实测 Nginx 配置、使用最简单。。。
tyhunter
    27
tyhunter  
   2017-06-28 10:32:16 +08:00
@madeye win 上可以试试 sstap
cloudyplain
    28
cloudyplain  
   2017-06-28 10:35:51 +08:00   ❤️ 1
切换报错
![]( )
yangyaofei
    29
yangyaofei  
   2017-06-28 10:36:10 +08:00
话说,支持 UDP 么.玩游戏没 UDP 很蛋疼..
tyhunter
    30
tyhunter  
   2017-06-28 10:36:41 +08:00
很棒,surge 不支持 ssr 一直是很蛋疼的一件事情
Yien
    31
Yien  
   2017-06-28 10:48:37 +08:00 via iPhone
厉害👍
madeye
    32
madeye  
   2017-06-28 10:51:07 +08:00
@tyhunter Not an open source solution.
achaocha
    33
achaocha  
   2017-06-28 10:56:07 +08:00
好货!
ekousp
    34
ekousp  
   2017-06-28 11:02:33 +08:00
可以 Docker 否?虚拟机不常开,docker 现在倒是一直开着。
paradoxs
    35
paradoxs  
   2017-06-28 11:05:19 +08:00
@Chingim surge for mac 那个 enhanced mode 很难实现吗?
ovear
    36
ovear  
   2017-06-28 11:07:45 +08:00
先支持一波,战略性 mark
Chingim
    37
Chingim  
OP
   2017-06-28 11:08:03 +08:00   ❤️ 1
@miniers
@ekousp
docker 折腾过了, 没法接管宿主流量, 放弃了.

@coderfox 原理在于虚拟机设置两块网卡, 一块 hostonly 一块 bridge. 想了解的话可以参考之前写的博客:
https://icymind.com/virtual-openwrt/
Chingim
    38
Chingim  
OP
   2017-06-28 11:12:11 +08:00
@yangyaofei
目前 UDP 只转发 DNS 查询, 稍作配置可以转发其他 UDP 流量, 但目前还没提供这个配置入口.
GPU
    39
GPU  
   2017-06-28 11:14:41 +08:00
讲真 MacOS 除了楼主的还有 Surge 选择性好多 ,Windows 上面毛都没有。

如果能支持 SSR 更好。
xys7326
    40
xys7326  
   2017-06-28 11:14:44 +08:00
看了下,docker 应该目前还不能实现同样的效果。主要是 docker 依然不开放虚拟网卡控制权,我觉得楼主可以关注下 xhyve,一个基于 Hypervisor.Framework 的 OS X 虚拟机实现,比较轻量。
Windows 的话毫无疑问当然是 Hyper-V 是最好的。
Chingim
    41
Chingim  
OP
   2017-06-28 11:17:43 +08:00
@paradoxs 不清楚 surge 怎么实现. 但是估计也是走 extension network 接口, 想要使用这个接口应该要挺多钱的. 不然开源的 Specht 怎么那么久都没人签发来造福大众
pubby
    42
pubby  
   2017-06-28 11:18:08 +08:00
转发流量可以用 PF 的吧
只不过 ss-redir 只支持 linux,所以转发了也没用
paradoxs
    43
paradoxs  
   2017-06-28 11:19:00 +08:00
@Chingim extension network 已经是免费的了. 有个叫 NEKIT 的 在 github, 你看看?
yexm0
    44
yexm0  
   2017-06-28 11:19:09 +08:00 via iPhone
@madeye @GPU 其实 windows 上用 sstap 也挺好的吧
Chingim
    45
Chingim  
OP
   2017-06-28 11:20:36 +08:00
@pubby PF 可以转发的呀? 我折腾了很久都没实现...不然就不会做这个了.

比如说, 某个代理软件运行在本地的 7788 端口, pf 可以将本机的所有出口数据包转发到这个端口上吗?
wwqgtxx
    46
wwqgtxx  
   2017-06-28 11:22:54 +08:00
@tyhunter
@yexm0
刚试了一下 sstap 的确是个好东西,不过如果在配置让他往本地的 socks5 代理灌数据的话,很容易导致回环死锁,而他自己之前 ss 服务器就么有任何问题,这个还有有一些烦人的
pubby
    47
pubby  
   2017-06-28 11:23:30 +08:00 via Android   ❤️ 1
@Chingim 反正 freebsd 的 pf 可以转发,但是 ss-redir 依赖 linux 下 netfilter 模块的,你在 mac 下转发过去也没用,没有足够信息让它知道转发前的原始目标地址
maemual
    48
maemual  
   2017-06-28 11:26:06 +08:00
这个思路有点意思,支持一下
Chingim
    49
Chingim  
OP
   2017-06-28 11:26:23 +08:00
@paradoxs 我看过 NEKit, 它主页上说没有用 network extension, 所以只能监听某个端口, 没法接管主机的所有流量(如果理解有误, 请指正).

"NEKit does not depend on Network Extension framework. You can use NEKit without Network Extension entitlement to build a rule based proxy in a few lines."

作者的另一个项目 https://github.com/zhuhaow/Specht 倒是用了 network extension, 我理解 specht 应该能实现 surge 一样的功能. 但是没人签发.

"Specht is a simple proxy app built with NEKit.

Unless you have a developer ID with Network Extension entitlement, you cannot use Specht (Why?). Please use SpechtLite instead."
Chingim
    50
Chingim  
OP
   2017-06-28 11:31:35 +08:00
@cloudyplain bug 提交 issue 吧, 这个好像是获取 ip 地址的功能 bug 了.
bazingaterry
    51
bazingaterry  
   2017-06-28 11:34:15 +08:00 via iPhone
好棒啊,我之前都是手动配置,没想到今天有人弄带 GUI 的了!
n6DD1A640
    52
n6DD1A640  
   2017-06-28 11:51:10 +08:00
先装 virtual box。。。太重了

anyway,思路不错,赞一个
luoqeng
    53
luoqeng  
   2017-06-28 11:55:53 +08:00
大学时就这么做过,不过用的 RouterOS。宿舍所有人都通过我的笔记本上网,省了几年网费,虽然现在看来也没多少钱……
livexia
    54
livexia  
   2017-06-28 12:21:59 +08:00 via Android
docker 可以实现么
luoqeng
    55
luoqeng  
   2017-06-28 12:32:50 +08:00
忘了说当时用的 VMware,然后分配的 16MB 内存 单核,带 8 人无压力。
missdeer
    56
missdeer  
   2017-06-28 12:55:22 +08:00
有个疑问,只是做网关的话,虚拟机只需要一块桥接的网卡就够了吧,跟宿主机在同一个网络即可。
Cavolo
    57
Cavolo  
   2017-06-28 12:55:37 +08:00 via iPhone
Mac 有 surge 已经很不错了,win 还什么都没有呢
freestyle
    58
freestyle  
   2017-06-28 13:17:35 +08:00
@livexia 我就是用 docker 跑 kcptun 的, 开机自启, 然后在 shadowsocks 里配置一个本地的 127.0.0.1:8388 就可以了
```
docker rm -f kcptun; docker run -d -p 8388:8388 --restart always --name kcptun xtaci/kcptun client -r "remoteServer:port" -l ":8388" -mode fast2
```
freestyle
    59
freestyle  
   2017-06-28 13:26:06 +08:00
docker 里的 mac --net host 一直有问题 https://github.com/docker/for-mac/issues/68
tony1016
    60
tony1016  
   2017-06-28 13:28:34 +08:00
我怎么没有明白原理? Guest 系统是如何强奸 Host 系统的网络流量的??
ivyliner
    61
ivyliner  
   2017-06-28 13:36:06 +08:00
" OS X 上没有 linux 的 iptables, 无法直接将流量转发给本地的端口 " OS X 上面有类似 iptables 的 pf 比 iptables 简单
tony1016
    62
tony1016  
   2017-06-28 13:38:41 +08:00
@pubby
@Chingim
pf 这个我之前研究过啊,感觉此路不通啊

https://www.v2ex.com/t/250591
tyhunter
    63
tyhunter  
   2017-06-28 13:40:01 +08:00
试用了下,希望 LZ 能在下一个版本加入 SSR 支持和 UDP 转发
Chingim
    64
Chingim  
OP
   2017-06-28 13:50:09 +08:00
@ivyliner
@tony1016
按照我的理解, pf 没法把"从本地出去的数据包"转发到本地的某个端口的, 转发"进来的数据包"倒是可以. 这里 https://forums.freebsd.org/threads/49422/ 有个网友说的:
"PF can not redirect traffic that originates from the host itself because the routing decision for the traffic has been already made by the time it gets to the filter. It's a FreeBSD specific limitation that does not exist on OpenBSD's PF for example."

vrouter 没有用 pf, 就是单纯地把网关改为虚拟机的 hostonly 网卡地址, 改了之后数据就流向虚拟机了.

vrouter 还有个虚拟的 bridge 网卡, 该网络可以从上游路由器获取 IP, vrouter 的数据通过 bridge 网卡流向上游路由器.
firefox12
    65
firefox12  
   2017-06-28 14:03:59 +08:00 via iPhone
我装一个 virtual 里面装一个 ubunt 上面开启 iotables ss 不是一样的效果?
tony1016
    66
tony1016  
   2017-06-28 14:06:06 +08:00
@Chingim 参见我研究结论的第二条,可以绕道把发出去的数据包转到本地某个端口上

2.pf 的 rdr 只能对 incoming 做 redirect,所以,需要先 route-to,把对外网的请求,变成对内网的请求,再把它重定向到 redsocks。我以 twitter.com 为目标做了测试

rdr pass log on lo0 inet proto tcp from any to 104.244.0.0/16 -> 127.0.0.1 port 1080
pass out on en0 route-to lo0 inet proto tcp from en0 to 104.244.0.0/16
Chingim
    67
Chingim  
OP
   2017-06-28 14:17:12 +08:00
@tony1016 没入门 pf, 帮你 at 高手解答: @pubby
Chingim
    68
Chingim  
OP
   2017-06-28 14:18:09 +08:00
@firefox12 是的一样的, 什么发行版都可以. 设置好网络就行
pubby
    69
pubby  
   2017-06-28 14:34:00 +08:00
@Chingim
@tony1016
抱歉,确实只能对入口流量做重定向。之前都是在做路由的机器上搞,没想到本机发出的流量 -_-
Artail
    70
Artail  
   2017-06-28 14:41:51 +08:00
- -我接管流量失败了。然后把它关掉。它修改了的 DNS 却没还原回去。。。我排查了半天。。才发现。。- -
kikyous
    71
kikyous  
   2017-06-28 14:57:10 +08:00
@Artail #70 同样的问题
cielpy
    72
cielpy  
   2017-06-28 15:02:53 +08:00
建议添加运行日志,方便查找问题。

失败后没有恢复默认 DNS 我也遇到了
galenzhao
    73
galenzhao  
   2017-06-28 15:03:48 +08:00
@wwqgtxx 可以啊,hv,vm 是可以的
xiubin
    74
xiubin  
   2017-06-28 15:19:18 +08:00
Surge 为什么可以让所有 APP 都走代理呢?
GPU
    75
GPU  
   2017-06-28 15:20:35 +08:00
@yexm0 #44 好像还可以,但是界面不好看。
mmtromsb456
    76
mmtromsb456  
   2017-06-28 15:23:23 +08:00 via iPhone
@Chingim 有两个问题问一下 dalao.第一个比如说像 surge 规则里面 geoip,cn,rediret 这样的中国 ip 即直连的规则.要怎么设置呢?国内就算网站不被墙..速度也很慢.不如都走代理.第二个是有支持 SSR 的计划吗
flicker317
    77
flicker317  
   2017-06-28 15:49:02 +08:00   ❤️ 4
@Chingim surge mac 没有用到 network extension. 在 mac 上如果要使用 network extension 必须走 mac app store 渠道
@xiubin surge mac 创建了一个 utun,并且路由表中配置了所有 240.0.0.0/8 网段走这个虚拟网卡,然后通过内部 dns 把所有查询结果映射到这个网段,然后通过内部 TCP/IP 协议栈处理网络连接。大概就这个样子
Chingim
    78
Chingim  
OP
   2017-06-28 16:55:22 +08:00
@Artail
@kikyous
@cielpy 能麻烦去 github 提交 issue 吗? 谢谢
不清楚这个 bug 问题出在哪...
运行日志是很有必要, 后面会加上


@mmtromsb456 目前只能是, 把你需要走代理的 IP 添加到自定义黑名单, 然后代理模式选择"仅黑名单", 鉴于 ssr 受众很大, 后续应该会加上
tony1016
    79
tony1016  
   2017-06-28 17:09:06 +08:00 via Android
@pubby 可以的,看我的做法
ziyuan
    80
ziyuan  
   2017-06-28 17:13:23 +08:00
这个和我自己在 mac 上装 ssr client 有啥区别?
cielpy
    81
cielpy  
   2017-06-28 17:59:53 +08:00
@Chingim issue 已提,两个 issue 都是我提的(逃
wwqgtxx
    82
wwqgtxx  
   2017-06-28 18:31:42 +08:00 via iPhone
@galenzhao 你真的试过么。我这里根本没办法同时运行 hv 和 vmware 虚拟机
geekdada
    83
geekdada  
   2017-06-28 18:35:32 +08:00
思路独特,不错
wph95
    84
wph95  
   2017-06-28 18:56:07 +08:00
vbox 是有点重了
可以用 xhyve https://github.com/mist64/xhyve 呀 轻量级多了
mmtromsb456
    85
mmtromsb456  
   2017-06-28 18:59:36 +08:00 via iPhone
http://showerlee.blog.51cto.com/2047005/1221285
https://github.com/cjheath/geoip
期待 geo ip 的实现.这样子我个人认为功能上已经不输于 surge 了.希望这些链接对你有帮助^_^
pagxir
    86
pagxir  
   2017-06-28 19:18:40 +08:00
ixinshang
    87
ixinshang  
   2017-06-28 19:21:58 +08:00 via Android
神器啊
flowerwrong
    88
flowerwrong  
   2017-06-28 19:24:16 +08:00 via iPhone
@pagxir 再补充两个,gotun2socks,kone
Chingim
    89
Chingim  
OP
   2017-06-28 20:07:28 +08:00
@pagxir
@flowerwrong

不知道这类工具能不能根据不同域名来决定是否使用代理? 印象中 TUN virtual network interface 需要添加一堆路由到系统路由表, 而且都是基于 ip 的
pagxir
    90
pagxir  
   2017-06-28 20:20:27 +08:00
@Chingim 当然可以了,你去看看 Kone 的实现,估计就带有这个功能了。
flowerwrong
    91
flowerwrong  
   2017-06-28 20:30:06 +08:00
@Chingim
@pagxir
可以的,fake dns,像 telegram 那种 ip 的还是需要路由表才可以,[kone]( https://github.com/xjdrew/kone/blob/master/example.ini#L51)下载大文件有点问题,一直不知道为什么。
Chingim
    92
Chingim  
OP
   2017-06-28 20:41:06 +08:00
@flowerwrong kone 看起来不错, 但是基本没文档, 不知道基于什么考虑只支持了 linux.
@flicker317 不知道你了不了解 kone, surge 的实现是类似 kone 吗
isbase
    93
isbase  
   2017-06-28 20:49:06 +08:00
Collected errors:
* verify_pkg_installable: Only have 76kb available on filesystem /overlay, pkg python3-decimal needs 131
* opkg_install_cmd: Cannot install package python3.

默认分配的空间太小了,支持用户自定义就好了
pagxir
    94
pagxir  
   2017-06-28 21:01:06 +08:00   ❤️ 1
@flowerwrong

func (nat *Nat) clearExpiredSessions(now int64) {
if now-nat.lastCheck < NatSessionCheckInterval {
return
}

if nat.count() < nat.checkThreshold {
return
}

nat.lastCheck = now
for index, session := range nat.sessions {
if session != nil && now-session.lastTouch >= NatSessionLifeSeconds { #### 这行写错了,你需要修改这行应该就 OK 了。
nat.sessions[index] = nil
nat.tbl.Unmap(session.srcIP, session.srcPort)
}
}
}
pagxir
    95
pagxir  
   2017-06-28 21:05:42 +08:00
@Chingim kone 确实只支持 linux 的。原理跟 https://github.com/cachefiles/proxyvpn 差不多,都是基于 user mode 的 NAT 实现。
flowerwrong
    96
flowerwrong  
   2017-06-28 21:11:18 +08:00
@pagxir 我加了一个有点限制的 mac 版本 pr https://github.com/xjdrew/kone/pull/11 用起来正常。
chocolatesir
    97
chocolatesir  
   2017-06-28 21:16:53 +08:00
这名字,我以为锐速又出路由器了
Mistwave
    98
Mistwave  
   2017-06-28 22:35:42 +08:00
挺有趣的,支持一下
so898
    99
so898  
   2017-06-28 23:41:20 +08:00
VB 和 VM 还有 Parallels 有比较严重的兼容性问题
我的电脑只开 VB 都有概率 Kernal Panic ……
感觉要是能有 Docker 的方案可能会更好
yangyaofei
    100
yangyaofei  
   2017-06-28 23:51:51 +08:00
@Chingim 哦~~这个还挺需要的,毕竟很多游戏需要~
1  2  
关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   875 人在线   最高记录 6679   ·     Select Language
创意工作者们的社区
World is powered by solitude
VERSION: 3.9.8.5 · 83ms · UTC 21:33 · PVG 05:33 · LAX 13:33 · JFK 16:33
Developed with CodeLauncher
♥ Do have faith in what you're doing.