m-ui 面板的客户端 · Windows / macOS / Linux / Android 四端一套界面 · 内嵌 sing-box · TUN 全机接管 · 默认关掉 IPv6
先看看再装? 在线演示 就是客户端里那一份界面跑在示例数据上:不用装、不连任何服务,连接、换节点、切模式、编规则都能点,刷新即恢复。
m-ui 面板的多平台客户端:内嵌 sing-box,TUN 模式,规则 / 全局 / 直连三态,DoH + fake-ip,默认禁 IPv6(v6 接进隧道再拒绝,并在连接期间停用各网卡的 IPv6 协议),开机自启;多订阅(刷新走"当前代理 → 自动选择 → 直连"回退链)、定时测速、可视化规则组、按进程 / 应用 / 设备直连、应用内升级、日志保留、诊断包。四端共用同一个守护进程和同一套界面(一份 HTML/JS/CSS,浅色深色跟随系统或手动切换)。
| 平台 | 状态 | 形态 |
|---|---|---|
| Windows 10 1809 及以上 / 11(x64、ARM64) | 可用 | 后台服务 + 托盘客户端(WebView2 窗口),安装包见 Releases |
| macOS 13 及以上(苹果芯片、英特尔芯片) | 可用 | launchd 服务 + .app 窗口;安装包里双击装,或 curl 一行装,免开发者证书 |
| Linux 桌面 / 服务器(systemd) | 可用 | 单一二进制,自带浏览器面板,一键安装脚本 |
| OpenWrt / iStoreOS 等软路由 | 可用(网关模式,容器实验室验证) | 同一二进制,procd 自启,ipk 包;局域网设备策略 |
| 梅林(Asuswrt-Merlin / Entware) | 开发中 | TProxy 模式,无真机待反馈 |
| Android 手机 / TV | 测试版(手机已真机验证;电视按真机反馈修过一轮,待复测) | WebView 承载同一套页面 + gomobile 引擎,VpnService 建隧道,按 ABI 分包的 APK。页面写法迁就老电视的 WebView(底线 Chrome 66),web/compat_test.go 把关 |
| 进程 | 身份 | 职责 |
|---|---|---|
godusevpn-svc.exe |
Windows 服务(SYSTEM,自动启动) | 内核、订阅、配置生成与干跑、TUN / 路由 / DNS、控制管道、诊断包 |
godusevpn.exe |
当前用户(登录自启) | 托盘与主窗口(Wails + WebView2) |
godusevpn-cli.exe |
当前用户 | 排障与脚本:状态、连接、模式、节点、订阅、日志、诊断 |
服务与客户端之间走命名管道 \.\pipe\godusevpn,一行一个 JSON;服务的访问控制允许普通用户查询、启动和停止它,托盘"退出"因此不用提权。数据在 %ProgramData%\godusevpn\:
settings.json(设置)、profiles\<id>.json(各订阅缓存)、config.json(最近生成的配置)、config.last-good.json(最近一次成功启动的配置)、cache.db(fake-ip 与节点选择)、rulesets\(本地规则集)、logs\、diag\(诊断包)。客户端自己的偏好(语言、外观)在 %APPDATA%\godusevpn\ui.json。
内嵌 sing-box 需要这几个构建标签:
go build -tags with_quic,with_utls,with_clash_api,with_gvisor -trimpath -ldflags "-s -w -X github.com/Maoyangui/godusevpn/internal/buildinfo.Version=0.3.0" ./cmd/godusevpn-svc
go build -trimpath -ldflags "-s -w" ./cmd/godusevpn-cli
go build -tags desktop,production -trimpath -ldflags "-s -w -H windowsgui" ./cmd/godusevpnmacOS 的图形界面要连 WebKit,得开 CGO,还得自己补上 Wails 没声明的 UniformTypeIdentifiers 框架;编好的二进制放进手工拼的 .app(模板在 cmd/godusevpn/build/darwin/Info.plist,图标用 sips + iconutil 现生成 icns):
CGO_ENABLED=1 CGO_LDFLAGS="-framework UniformTypeIdentifiers" go build -tags desktop,production -o godusevpn.app/Contents/MacOS/godusevpn ./cmd/godusevpn或直接 powershell -File build.ps1,产物在 dist\(amd64 与 arm64)。图标、清单与版本信息由 winres\*.json 经 go-winres 生成到各 cmd\*\rsrc_windows_*.syso,CI 按 tag 重新生成。
图标:go run ./tools/mkicons -logo cmd/godusevpn/build/logo.png -out cmd/godusevpn/build。logo.png 是透明底的原图;生成的应用图标会垫一块白色圆角底(和安卓的自适应图标一致),原图的透明边会先裁掉再放上去;另出一张 appicon-macos.png(四周留透明边,macOS 的 Dock 图标用它做 icns);托盘图标保持透明。
测试:go test -tags with_quic,with_utls,with_clash_api,with_gvisor ./...(含内嵌 sing-box 对生成配置的干跑校验、管道往返、状态机全路径、设置迁移)。
从 Releases 下载。资产统一叫 godusevpn-<版本>-<系统>-<架构>.<后缀>,发布页里同一系统的包挨在一起,SHA256SUMS 是全部包的校验和:
| 系统 | 包 | 说明 |
|---|---|---|
| Windows x64 | godusevpn-<版本>-windows-x64-setup.exe |
标准版,缺 WebView2 时联网安装运行时 |
| Windows x64 | godusevpn-<版本>-windows-x64-setup-offline.exe |
离线完整版,内嵌 WebView2 运行时,给精简系统与内网机器 |
| Windows ARM64 | godusevpn-<版本>-windows-arm64-setup.exe |
ARM64 设备 |
| Windows | godusevpn-<版本>-windows-<架构>-bin.zip |
三个裸 exe,手工替换与排障用 |
| macOS | godusevpn-<版本>-macos-<架构>.tar.gz |
arm64(苹果芯片)/ amd64(英特尔),内含守护进程、godusevpn.app、install.sh,以及给不用终端的人的「安装说明.html」「安装佛跳墙.command」「卸载佛跳墙.command」 |
| Linux | godusevpn-<版本>-linux-<架构>.tar.gz |
amd64 / arm64 / armv7 / mipsle / mips,内含二进制与 install.sh |
| OpenWrt / iStoreOS | godusevpn-<版本>-openwrt-<架构>.ipk |
opkg install 装完自动起服务并打印面板地址 |
| Android | godusevpn-<版本>-android-<ABI>.apk |
arm64(绝大多数手机 / 电视)、armv7(老设备)、x86_64(模拟器 / 少数盒子)、universal(全架构合一) |
系统要求:Windows 10 1809(内部版本 17763)或更高,x64 / ARM64。安装包会拦住更低的版本。Windows 7 / 8 用不了,而且不打算支持:Go 从 1.21 起就不再支持它们(内嵌的 sing-box 需要更高的 Go),微软也已停止为它们提供 WebView2。
安装包会注册后台服务(自动启动)、装托盘客户端与命令行,可勾选"登录时自动启动",并注册 godusevpn:// 协议供落地页一键导入(客户端每次启动也会自己确认一遍这个协议,老版本升上来不用重装)。程序未签名,SmartScreen 提示时点"更多信息 → 仍要运行"。
- 首次打开先填面板给的订阅链接才能进入。
地区是从节点名里认出来的:旗帜 emoji、中英文地名、独立的两位国家代码都认,认不出就画一个地球,不影响使用。旗帜是内置的 SVG(见 web/dist/flags/),不靠系统的 emoji 字体——Windows 至今没有旗帜字体。
- 首页中间是连接 / 断开的大按钮,连上之后按钮下面用大字走连接时长;再往下两张卡片:
- 出口卡片:地区旗帜 + 当前节点 + 这条线路真正的出口地址与国家、城市 + 延迟,点一下直接换节点。出口是经当前节点查来的:节点名写的是机房位置,真正的出口未必在那儿(节点自己再套一层就不是了)。先问
ipwho.is(免密钥,一次 JSON 给地址 / 国家 / 一级行政区 / 城市 / 运营商),不通就退到 Cloudflare 自家的cdn-cgi/trace(只给地址与国家代码,但几乎不会连不上);两个都不通就显示正在查出口,下一轮健康检查再来一次。两个端点回的都是对方看到的你是谁,不需要再拿这个 IP 去别处查一次归属地;请求走隧道,对方看到的是节点的出口地址,不是本机的。换节点立刻重测,自动选择模式下内核在后台切了也会重测,此外每 10 分钟复查一次。 - 速度卡片:实时上下行、本次连接累计流量,底下是最近一分钟的速度曲线。 最下面三格:模式(规则 / 全局 / 直连)、订阅(多订阅点击切换)、节点。
- 出口卡片:地区旗帜 + 当前节点 + 这条线路真正的出口地址与国家、城市 + 延迟,点一下直接换节点。出口是经当前节点查来的:节点名写的是机房位置,真正的出口未必在那儿(节点自己再套一层就不是了)。先问
- 节点面板:每行带地区旗帜与延迟条,名字里写了倍率(
2x/x2/0.5倍)会单独标出来;顶上按地区归堆成一排标签,点一下只看该地区,配合搜索框找节点。测速只改数字不重画列表,不会闪。 - 首次打开是一张引导页:只要一个订阅链接,旁边带粘贴键;下面写清楚也可以在落地页点「一键导入」,以及订阅地址只存在本机。
- 订阅管理:当前那条摊成一张大卡 —— 用量条、已用 / 总量、节点数与地区数、到期日,底下三个动作(刷新 / 编辑 / 删除);其余订阅各是一张小卡,点整行切换,底下同样是使用 / 刷新 / 编辑 / 删除。面板设置了「选购 / 续费」地址的,卡上会多一颗续费按钮,点开系统浏览器;快到期或流量快用尽时它变成橙色并写明还剩几天;已经到期、甚至到期后订阅已经拉不到了,按钮照样在(面板会把地址随那个 404 一起给)。
- 连接页顶上三个数(活动 / 经代理 / 直连)+ 三个筛选标签,每行是目标、走的哪个节点、协议与时长、上下行,右侧一个叉断开这一条。列表就地更新,两秒一轮不会闪。
- 日志页黑底等宽,时间 / 级别 / 正文三列对齐,警告与错误带底色;可以只看错误、暂停、复制全部,底下是导出诊断包。内核一栏能按去向筛选(走隧道 / 直连 / 拦截 / DNS,带条数),每条连接写成「去向 · 节点 + 进程 → 域名:端口(IP)」,一眼看出哪个程序连了哪、走的哪个节点;点连接号只看这一条连接的全部日志。
- 关于页居中放版本,有新版时那张卡整块点亮;下面是服务状态与修复、内核信息,以及诊断包、项目主页、退出三行。
- 左上角菜单:顶上一张状态卡(连接状态、时长、当前节点与出口、三种模式就地切换),下面是设置、订阅管理(新增 / 编辑 / 删除 / 刷新 / 续费)、路由规则、连接(活动连接与断开)、日志(服务与内核、导出诊断包)、关于(检查更新、修复服务、退出);底部一颗小按钮在"跟随系统 / 浅色 / 深色"之间循环。
- 路由规则:内置一组默认规则(局域网与私网直连、国内域名与 IP 直连、其余走代理),这三项各自可改(直连 / 代理 / 拒绝;"其余流量"只能选代理或直连),改乱了点"还原默认"一步回出厂。用户还可以可视化新增规则组:名称、出口(代理 / 直连 / 拒绝 / 自动选择 / 某个节点)、任意多条条件(域名后缀、完整域名、关键词、正则、IP 段、端口、进程名、geosite 类别、geoip 国家),组内任一条件命中即算命中;规则组自上而下依次匹配,排在默认规则之前,只在"规则"模式下生效,可启停、排序、编辑、删除。
- 刷新订阅不断线:刷新拿到的增删立刻反映在节点列表里,正在用的连接一点不动,不用点什么"应用"。列表里刚加进来的节点(内核还没有)或参数改了的节点,选中时会重建配置重连一次。只有正在用的那个节点被面板删掉或改了参数才自动重连。
- 全局禁直连(默认开):全局模式下只要还连着,任何流量都不许绕过隧道直连 —— 隧道没起来、内核在重启、节点不通、崩了在重试,统统只能等,不漏。放行的只有隧道自己(节点连接、订阅刷新的回退)、回环,以及「局域网直通」开着时的局域网。闸是持久的,服务被杀、崩溃、重启机器都还在,只有断开 / 切模式 / 关开关 / 卸载才撤;Windows 用系统过滤平台的持久规则,macOS 用 pf,Linux 用 nftables,Android 靠内核重启时不关 VPN 接口。断网了要恢复,托盘 / 开始菜单都有「恢复网络」,详见下文。
- 关窗口只收到托盘,连接不断;托盘"退出"会断开连接并停掉后台服务,TUN 网卡随之消失。
- 订阅刷新回退:经当前代理刷新失败时,改用"自动选择"组再试几次,仍失败就直连刷新。回退只作用于订阅刷新这一条请求,选中的节点和其它流量的路由都不受影响。
- 定时测速:设置里的"定时测速(分钟)",自动选择时每隔该周期测一轮全部节点并切到最快的;手动指定节点时不测。这个间隔不写进内核配置(由守护进程定时叫测),所以自动 / 手动之间切换、改这个间隔都是就地生效,不重连。
- 按进程直连:设置 → 分流,每行一个 exe 名(如
steam.exe),这些程序的流量不走代理。「全局禁直连」生效时(全局模式)不生效,这些程序也走隧道。 - 升级:客户端每小时自己查一次新版本,有新版本时首页顶栏「佛跳墙」旁亮一个红色 NEW(侧栏「关于」也带 NEW),点它直达升级;也可以 关于 → 检查更新 → 升级并重启。只替换程序,设置与订阅都保留。
- 日志保留:默认 7 天,超过的滚动日志与诊断包自动删除;设置 → 日志里可改,0 = 一直保留。
系统要求:macOS 13(Ventura)或更高,苹果芯片与英特尔芯片各有一个包(Go 1.27 编出来的程序就是 13 起步)。两种装法,都要输一次开机密码(管理员):
不用终端:到 Releases 下载 godusevpn-<版本>-macos-arm64.tar.gz(苹果芯片)或 -amd64(英特尔),双击解开,照文件夹里的「安装说明」双击「安装佛跳墙.command」,在弹出的终端里输开机密码(问能否访问「下载」文件夹时点「好」)。浏览器下载的文件带着隔离标记,这个脚本第一次会被 macOS 拦一次 —— macOS 13 / 14 右键 →「打开」,macOS 15 起到「系统设置 → 隐私与安全性」点「仍要打开」;放行之后它清掉整个文件夹的隔离标记,装好的佛跳墙不会再被拦。下错芯片的包会直接提示该下哪个。
用终端(不会被拦,也不用放行):
curl -fsSL https://raw.githubusercontent.com/Maoyangui/godusevpn/master/deploy/macos-install.sh | sudo sh已经解开了包的话,在那个文件夹里 sudo sh install.sh 也行。
为什么 curl 那条不会被拦:Gatekeeper 的"来自互联网"隔离标记是浏览器下载时打上的,curl 拿到的文件没有这个标记,所以不用买苹果开发者证书,也不用你去"系统设置 → 隐私与安全性"里点允许。要是已经用浏览器下过包,install.sh 会顺手把标记清掉。
装完是两样东西:/usr/local/bin/godusevpn 是守护进程兼命令行,注册成 launchd 服务(/Library/LaunchDaemons/com.maoyangui.godusevpn.plist)开机自启;/Applications/godusevpn.app 是图形界面,启动台里叫「佛跳墙」,页面与 Windows / Linux 是同一套。
- 数据在
/Library/Application Support/godusevpn/(设置、订阅缓存、config.json、日志、诊断包),界面偏好在~/Library/Application Support/godusevpn/ui.json。 - 隧道网卡是系统分配的
utunN(macOS 只认这个名字),协议栈固定 gvisor —— 系统协议栈在 macOS 上握不了手(内核收不到入站 TCP),设置页因此只给 gvisor 一个选项。 - DNS 会被接管:连上时把各网络服务的 DNS 改成一个走隧道的地址,断开时按连接前的原值还原(守护进程启动时也会还原一次,崩溃过也不会留下打不开网页的机器 —— 除非上次是在严格全局模式下连着的:那时先保留接管、等闸和隧道重建,否则那几十秒的解析会走物理网卡)。不这么做的话 macOS 一直问路由器(192.168.x.1),而私网段按"局域网直通"在隧道之外,解析记录就泄漏给本地网络了,fake-ip 与 AAAA 屏蔽也一并失效。
- 这一版没有菜单栏图标:Wails 与 systray 都要占着 Cocoa 主线程,凑一起要走外部事件循环,没有真机盯着调不准。所以关掉窗口只是关界面,隧道在后台服务里照常跑,从启动台再打开就回来了。
- 一键导入:落地页的
godusevpn://由.app的 Info.plist 向系统登记,点一下直接把订阅交给客户端。 - 升级:关于 → 检查更新 → 升级并重启,弹一次系统的管理员密码框,守护进程与
.app一起换掉。 - 卸载:双击安装包里的「卸载佛跳墙.command」;或者
sudo godusevpn uninstall撤掉服务,再删/Applications/godusevpn.app与/usr/local/bin/godusevpn。 - 验收:
sudo sh deploy/macos-test.sh <订阅地址>共 53 项;CI 每次提交都在 GitHub 的苹果芯片跑机上真跑一遍(装服务、拉订阅、建隧道、按规则跑流量、查 IPv6 是不是真被拦住且没绕过隧道、逐个调各功能页面的接口),另加一步把.app装进/Applications打开看它能不能活下来,再拿打上浏览器隔离标记的安装包走一遍双击安装 / 卸载(装好的程序不能再带隔离标记)。
同一套守护进程与页面跑在 Linux 上,一个静态二进制 godusevpn 既是服务也是命令行,自带浏览器面板(纯 HTTP)。root 执行:
curl -fsSL https://raw.githubusercontent.com/Maoyangui/godusevpn/master/deploy/install.sh | sh装完终端会打印面板地址(局域网 / 内网地址、云主机的公网地址、本机地址)和随机生成的初始密码。Linux 上面板默认监听 0.0.0.0:9800,局域网其它设备直接打开即可;云主机要在安全组 / 防火墙放行 TCP 9800。改密码 godusevpn passwd,只给本机看就 godusevpn settings webListen=127.0.0.1:9800。面板与 Windows 客户端是同一套页面,功能一致(订阅、三态、规则组、节点测速、日志、升级)。
- 数据布局与 Windows 一致:设置在
/etc/godusevpn/,缓存、规则集、日志在/var/lib/godusevpn/(梅林等 Entware 环境在/opt/etc与/opt/var/lib下)。 - 自启按初始化系统落地:systemd 单元、OpenWrt 的 procd 脚本、Entware 的 init.d 脚本;
godusevpn install | uninstall | start | stop | status。 - 本机模式(默认):TUN 只代理本机流量,与 Windows 相同;外部连进来的连接(SSH、面板)由连接跟踪认出来,回包走原来的路由,远程 SSH 不会被切断;只绑物理网卡地址往外连的(WebRTC)照样走隧道。
- 网关模式(OpenWrt / iStoreOS 等软路由):设置 → 网络 → 网络模式选"网关"(或
godusevpn settings netMode=gateway),局域网设备把网关和 DNS 指向这台机器即被代理,设备的 DNS 查询由内核接管(fake-ip、防泄漏)。菜单里多出"设备"页:自动发现在线设备(DHCP 租约 + 邻居表),每台可设跟随规则 / 强制代理 / 直连 / 拒绝上网,按 MAC 记住;命令行godusevpn devices、godusevpn device <MAC> <follow|proxy|direct|reject> [名字]。需要内核带 nftables(OpenWrt 22.03 起的 fw4 都有)。「全局禁直连」生效时(全局模式),设备的「直连」不生效,照样走隧道。 - 验收脚本
deploy/linux-test.sh,与 Windows 的检查项相同;网关模式在 Docker 里的 OpenWrt 23.05 + 一台 LAN 容器上验证过(设备被代理、fake-ip、IPv6 屏蔽、三种设备策略)。
测试版:手机上已经真机跑通(连接、分流、断开、升级),电视端目前只在模拟器上验证过;欢迎反馈。
- 安装:侧载
godusevpn-<版本>-android-<ABI>.apk(手机与电视基本都是 arm64;不确定就装 universal),首次安装要允许"未知来源"。最低 Android 8.0。 - 同一套界面与功能:守护进程(设置、多订阅与刷新回退链、规则组、状态机、定时测速)和页面与 Windows / Linux 是同一份代码,数据布局也一样(
settings.json、profiles/、config.json、logs/),只是放在应用私有目录。 - 隧道:第一次点"连接"会弹系统的 VPN 授权;之后 VpnService 按引擎给的参数建隧道(地址、路由、DNS、按应用直连),通知栏常驻状态并带"断开"。应用自身不排除在隧道之外(排除了的话本应用套接字的回包会从物理网卡漏走,真机实测 DNS 通、TCP 全断);内核自己连节点的套接字经 protect 不进 VPN。
- 按应用直连:Windows 的"按进程直连"在 Android 上就是应用包名(设置 → 分流),这些应用整个绕过 VPN。「全局禁直连」生效时(全局模式)不生效,这些应用也走 VPN。
- 开机自启:引擎按上次状态自动连;Android 12 起后台起前台服务受限,开机与升级完成的广播窗口里会先把服务拉起来。系统设置里也可以把它设为"始终开启的 VPN"。
- 升级:关于 → 检查更新 → 下载对应 ABI 的 APK、校验 SHA256 后拉起系统安装器;装完引擎按上次状态重新连接。每一版都用同一把签名密钥,否则系统不让覆盖安装。
- 电视:同一个包在 Android TV / 盒子上以横屏显示,遥控器方向键移动焦点;订阅链接建议用剪贴板粘贴。
- 诊断:日志 → 导出诊断包,经系统分享发出去。
构建:deploy\android-build.ps1(gomobile bind 出 AAR → Gradle 出 APK,需要 JDK 17 与 Android SDK / NDK);模拟器冒烟 deploy/android-emu-test.sh <订阅地址>。
以管理员身份:
godusevpn-svc install 注册服务并启动
godusevpn-cli profile https://面板/sub/用户名 设置订阅(自动补 format=json)
godusevpn-cli connect
godusevpn-cli status
godusevpn-cli mode global | rule | direct
godusevpn-cli nodes / select <节点> / test
godusevpn-cli settings ipv6=on tunStack=system probeMinutes=5 logDays=14
godusevpn-cli rules 列出规则组
godusevpn-cli logs 200 core
godusevpn-cli diag 打印诊断信息(订阅地址、凭据、访问记录已打码)
godusevpn-svc uninstall
- TUN:
auto_route+strict_route,协议栈 mixed(macOS 上固定 gvisor,系统协议栈在那儿握不了手),私网段直通;桌面端另开 127.0.0.1:2080 混合端口(Android 上不开:用不上,被占用却会让内核起不来)。 - DNS:远程 DoH 1.1.1.1 经代理,本地 DoH 223.5.5.5 直连,国内域名(规则模式下默认规则「国内」为直连时)与节点域名走本地;fake-ip 只分配 IPv4 段;53 端口与 DNS 协议一律劫持进内核。macOS 上还会在连接期间接管系统 DNS,否则解析绕过隧道直接问路由器。
- IPv6:默认关闭,四层同时堵:DNS
ipv4_only、无 IPv6 fake-ip 段、IPv6 目标一律拒绝;并且 TUN 照样声明 IPv6 地址,把 v6 流量接进隧道再丢掉 —— 不接进来的话它会绕过隧道从物理网卡直接出网,等于泄露(局域网的fc00::/7、fe80::/10、ff00::/8仍留在隧道外)。 - 网卡级停用 IPv6(设置 → 连接 → "连接时停用网卡 IPv6",默认开):上面那四层挡的都是"IPv6 数据包出网",挡不住"读取本机网卡配置"。运营商用路由器通告发下来的公网 IPv6 地址就配在物理网卡上,原生程序(不是网页,浏览器沙箱不给读)枚举一遍网卡就能读走,再经隧道报给自己的服务器 —— 数据包一点没漏,信息漏了,而那个前缀对应到具体一条宽带线路。所以连上时把各网卡的 IPv6 协议一并停用,让地址根本不存在:Windows 停用
ms_tcpip6绑定(等同于适配器属性里取消勾选「Internet 协议版本 6」),Linux 写net.ipv6.conf.<网卡>.disable_ipv6=1,macOS 用networksetup -setv6off逐个网络服务关。隧道自己那张网卡不动 —— 它要靠 v6 地址把 v6 接进来再拒绝。 改动前把每张网卡动手前的状态落盘,断开时按状态还原,守护进程启动时对账一次:上次不是连着关的机就还原回去(崩溃退出不会把 IPv6 永久关掉),上次连着关的机就接着关着 —— 它和「全局禁直连」的闸一样是持久的,连接状态读不出来时看闸还在不在;本来就是关闭状态的网卡记下来但不动、还原时也不去开(那是用户自己关的)。软路由的网关模式下同样会关,那正是希望整个局域网都没有 v6 出口的场景;要保留局域网 IPv6 就把这个开关关掉。Android 上做不到:应用没有权限改物理网卡的 IPv6 配置,那一端只有"接进 VPN 再拒绝"这一层,设置页也不显示这个开关。 - 模式:路由规则内置三套分支,内核 Clash API 切换,毫秒级不重启。
- 规则集:
geosite-cn、geoip-cn、geosite-category-ads-all随安装包内置(装完即用,内核启动不联网)。规则组里引用的其它 geosite / geoip 类别由守护进程在连上之后补下来,下次连接生效;本地没有的规则集会连同用到它的规则一起从配置里摘掉,而不是让内核去现下 —— 远程规则集是启动期的同步依赖,下不到会让整个内核起不来。查找顺序:rulesets\<tag>.srs(你自己放的)→rulesets\downloaded\→rulesets\builtin\。 - 用户规则组:每组渲染成一条路由规则(多种条件用 logical/or 组合),放在 clash_mode 分支之后、内置国内直连之前;出口选了节点而节点不在当前订阅里时回落到 proxy。
开关在设置 → 隐私,默认开。生效条件是三个同时成立:开关开、模式是全局、你没点断开。满足时除了隧道自己(节点连接、订阅刷新的回退、解析节点域名的那一次 DNS)、回环、「局域网直通」开着时的局域网(DNS 除外:Windows 与 macOS 上发往任何地址的 DNS 查询只许走隧道,隧道断开的空档里也不许发给路由器;Linux 见下表),任何流量都不允许绕过隧道 —— 隧道没起来、内核在重启(换订阅、切自动 / 手动)、节点不通、内核崩了在退避重试,统统只能等。
闸是持久的:它不跟着服务进程活——服务被强杀、崩溃、升级换文件、机器重启,闸都还在(Windows 上写进系统过滤平台的持久存储,另有一组开机过滤器堵住开机到防火墙引擎启动之间那几秒;macOS / Linux 的规则在内核里、重启就没了:闸开着时另存一份开机版,开机时由单独的开机单元先装上——Linux(systemd、OpenWrt)排在联网之前;macOS 由 launchd 开机拉起,不保证早于联网,只是把空档缩到最短;梅林(Entware)的 /opt 挂得比联网晚,做不到,开机到守护进程起来之间那几秒没有闸)。只有四件事会撤闸:点断开、切到规则 / 直连模式、关掉开关、卸载。服务每次启动先对账:上次是断开状态关的机就清掉残留,该在的立刻装上。
| 平台 | 做法 | 边界 |
|---|---|---|
| Windows | 系统过滤平台(WFP)里的一组持久规则:放行本服务进程(exe 路径之外还要求进程是 LocalSystem 或提权的管理员,别的账户用同一个 exe 起的进程不放行)、隧道地址、回环,拦 DNS(53 / 853)、UPnP 发现 / NAT-PMP / PCP(UDP 1900、5351、5350)与 v6 假地址段,都压在局域网放行之上,放行局域网、DHCP、邻居发现,以及开热点时本机当 DHCP 服务端与 DNS 代理的那几种包(「局域网直通」关着也放,只在局域网内往来),其余拦(运行期这组拦截带「否决」标志,别的软件的放行规则盖不过它);另一组开机规则(放行隧道地址、局域网、回环、DHCP、邻居发现,不放行进程)从开机堵到 BFE 起来。转发层也上闸:开热点 / 网络共享时经本机转发的流量同样只许进隧道接口,「局域网直通」开着时才放行去局域网的(和 Linux 网关模式的 forward 链一致);隧道接口查不到就宁可全拦,守护进程下一次同步或半分钟一次的巡检再补放行;TUN 关着(只用混合端口)时转发层没有可放行的接口,热点设备会断网,是设计如此 | 需要 BFE(基础筛选引擎)服务,它停了首页会标"禁直连未生效";服务依赖它,开机顺序不会错 |
| macOS | pf 的 com.apple/godusevpn 锚点:放行 root(守护进程)、隧道地址,拦 DNS(53 / 853)与 UPnP 发现 / NAT-PMP(UDP 1900 / 5351),放行局域网、DHCP 广播、邻居发现,其余拦。每次装闸都确认 pf 真开着;pf 被别的程序关掉时如实报"没开"并重装 |
pf 只能按用户放行、不认进程:守护进程要 root 才能管 utun / 路由 / pf,内核又在它里面,所以 root 下别的进程也会被放行 |
| Linux | nftables 的 inet godusevpn_guard 表:按标记放行本服务(内核出站带 route.default_mark,订阅回退与 DoH 打同一个标记),root 只放行回应入站连接的包(sshd、面板);拦 DNS(53 / 853)与 UPnP 发现 / NAT-PMP(UDP 1900 / 5351),放行局域网、DHCP、邻居发现,其余拦。DNS 先用策略路由接进隧道(发往 53 的包查一张只有"默认走隧道"的表),resolv.conf 直接写路由器的系统连着时照样能解析,空档里被拦。forward 链不分网关 / 本机模式:Docker、虚拟机 NAT、热点共享这些经本机转发的流量同样只许走隧道 |
内核不支持按端口的策略路由(4.17 以前)时 DNS 接不进隧道,闸就不拦 DNS,首页如实告警 |
| Android | 内核重启时不关 VPN 接口,接口本身就是闸(落进去的包被丢);只有点断开才关 | 进程被杀 VPN 接口就没了,应用自己做不到跨进程:设置页有入口跳到系统 VPN 设置,把佛跳墙设为「始终开启」+「阻止未经 VPN 的连接」,重启也管 |
UPnP 发现 / NAT-PMP 在严格全局下连局域网也拦(本机程序靠它们能向路由器问到宽带的真实公网地址),代价是这时局域网投屏、设备自动发现用不了,手动填地址访问照常。
桥接联网的虚拟机 / 容器不归闸管:VMware / VirtualBox 的桥接网卡、Hyper-V 外部交换机、Linux 的 br0 桥接,相当于局域网里另一台机器,包在二层直接从物理网卡出去、不经过本机协议栈,闸拦不到,网卡 IPv6 的停用也管不到它。要让它走隧道,改用 NAT 模式(NAT 模式的虚拟机、WSL2、Docker 默认网络都经本机转发,闸管得到)。
恢复网络(服务起不来、闸还在、机器断网的时候),四条路,都不需要服务活着。闸确实开着的时候,它们会先把「全局禁直连」开关关掉——不然服务一重连发现"闸不见了"又装回来,你刚恢复的网络几秒后再断;要再用去设置 → 隐私打开。闸本来就没开(比如你在规则模式下、只是想把被停用的网卡 IPv6 还原回来),两个开关一个都不会动:
- 托盘菜单「恢复网络(解除禁直连闸)」;
- 开始菜单「佛跳墙 → 恢复网络(解除禁直连闸)」(弹 UAC,做完弹个框告诉你结果);
- 命令行:Windows
"C:\Program Files\godusevpn\godusevpn-svc.exe" guard clear(会弹 UAC),macOS / Linuxsudo godusevpn guard clear;guard status看闸开没开; - 卸载程序先撤闸再删文件。
闸开着时还有几条:
- 节点域名的那一次解析不再明文问路由器 / 运营商:走「本地 DNS」那台 DoH(按地址直连,不用再解析它自己);「本地 DNS」设成 system 时,内核里给节点域名的解析器改用 223.5.5.5 的 DoH,隧道起来之前的那次预解析干脆不做(节点按域名规则也能匹配);DoH 服务器自己填的是域名的话,解析这个域名也走同一台加密 DoH,那次预解析同样不做。规则 / 直连模式不改 —— 那本来就不承诺不直连。
- 隧道还没起来时不做直连测速:节点列表的「重新测速」会提示先等隧道,而不是让测速包去撞闸。
- 撤闸失败不会假装已断开:状态里标「撤闸失败」并带原因,首页那颗盾还亮着。过滤器已经删干净、只是收尾没做完的不算失败,只进日志。
回退到旧版前先在本版里点「断开」(闸会连转发层一起撤掉),再装旧版:本版在系统过滤平台的转发层多了一组过滤器,0.6.24 及更早版本的撤闸与卸载不认识这一层,连着的时候直接手工换回旧文件会把它们留在系统里 —— 热点 / 网络共享一直不通,得重装本版再撤。
别手动删程序目录:规则在系统里、程序没了就没人能删它——真到那一步,Windows 重新装一遍再卸载即可;macOS / Linux 用 sudo pfctl -a com.apple/godusevpn -F all / sudo nft delete table inet godusevpn_guard。
hysteria2 / TUIC 出站是一条长会话,网页请求都是里面开的流。换网络、睡眠唤醒、路由器重启之后常见一种状态:会话在 QUIC 层还"活着"(对端没说关),但什么都投递不出去 —— 内核不会自己拆它,于是每个请求都卡到超时,而全局禁直连又不许任何流量绕过去,表现就是整机断网,别的设备同一节点却正常。
守护进程给这两种出站包了一层看护:
- 判废:握手窗口(20 秒)内流读写就出错、或一个字节都没收到就被应用放弃(活过握手窗口后被关掉),都算一次失败;40 秒内攒满 5 次、且最近 20 秒没有任何一条流收到过数据,就判这条会话废了,通知内核出站拆掉重建(等同于"网络变化"那条路),45 秒内不重复判。收到过数据的流出错不算 —— 那是会话活着的证据;服务端明确答复"目标连不上"、或把流重置的也不算,那恰恰证明会话活着,连着打开几个不通的网站不会把隧道判废。
- 重建后预热:拆掉之后如果这个节点正在用、用户也还想连着,后台对同一节点重新握手(失败等 1 秒、2 秒再试,最多 3 次),不等下一个请求来触发。
- 立刻体检:判废的同时敲状态机做一次健康检查,不再等三分钟一次的定时器;第一次不通节奏就收紧,确认"真的不对劲"只要再等一个短周期。
- 边界:全部动作都在隧道内部 —— 只对同一个节点重新握手,不换节点、不开任何直连、不碰闸和网卡。换节点仍然只有两条路:你手动选,或者状态机走到「临时换线」。
诊断包里的 state 多了一段 tunnel(rebuilds 重建次数、sick 判废次数、lastAt / lastNode / lastReason 最近一次的时间、节点与原因),只计当前在用的节点;godusevpn status 显示为「隧道:判废 N 次,重建 N 次」。断了网先看这里:判废次数在涨说明会话在坏、看护在修;一直不涨而网页照样打不开,就不是这一层的事。Android 上这一层只做"判废拆会话",预热与立刻体检暂只在桌面 / 路由器端。
GPL-3.0,与内嵌的 sing-box 一致。
第三方素材的出处与许可见 NOTICE:内嵌的 sing-box(GPL-3.0),以及节点列表里那套地区旗帜(flag-icons,MIT)。


