
radmin-vpn-linux v1.0.0
通过 Wine 在 Linux 上运行 Radmin VPN — 自定义驱动、TAP 桥接、零丢包
适用于 Linux 的 Radmin VPN
通过 Wine 在 Linux 上运行 Radmin VPN。加入 VPN 网络、查看对等节点、玩游戏——无需 Windows 虚拟机。
我构建这个项目,并不是因为它比虚拟机更简单。我构建它,是因为我当时觉得它比虚拟机更简单。
AI 辅助代码。 由人类与 Claude(Anthropic)协作构建。驱动程序、钩子和桥接层借助 Ghidra 对 Radmin VPN 未文档化的驱动协议进行了大量 AI 辅助逆向工程后编写而成。该方案可用,但不提供任何保证。 与 Famatech 无关联。Radmin VPN 是专有软件——请自行从 radmin-vpn.com 下载。使用风险自负。
工作原理
Radmin VPN 的 Windows 服务通过 NDIS 微端口驱动程序与其虚拟网络适配器通信。Wine 不支持 NDIS,因此我们用自己的实现替代该驱动,桥接到 Linux TAP 设备。一个钩子 DLL 负责处理 Wine 兼容性问题(适配器命名、注册表权限)。最终结果是:一个功能完整的 Radmin VPN 客户端在 Wine 下原生运行。
Linux app ← TAP (radminvpn0) ← tap_bridge ← FIFO ← rvpnnetmp.sys (Wine driver) ← RvControlSvc.exe
快速开始(AppImage,推荐)
从最新发布版获取 RadminVPN-Linux-x86_64.AppImage。无需安装任何东西——Wine 已内置其中。
候选发布版(例如
v1.0.0-rc1)以 GitHub 预发布 形式发布。上面的latest链接始终指向最新的 稳定 版本,因此预发布版不会出现在那里——请从完整发布列表获取这些版本。
chmod +x RadminVPN-Linux-x86_64.AppImage
./RadminVPN-Linux-x86_64.AppImage
首次启动时会提示提供 Radmin VPN 安装程序(请先从 radmin-vpn.com 下载 Radmin_VPN_*.exe)。会打开一个终端显示进度,并且设置 TAP 时需要一次 sudo 密码提示。
持久化状态(wineprefix、MAC、日志)保存在 ~/.local/share/radmin-vpn-linux/ 中。
前置要求(源码构建 / 非 AppImage)
- Wine >= 11.0(在 Arch Linux 的 Wine 11.5 和 Ubuntu 24.04 的 Wine 11.6 上测试通过)
- mingw-w64 交叉编译器(
i686-w64-mingw32-gcc、x86_64-w64-mingw32-gcc)——用于从源码构建 - iconv(glibc)——用于服务日志解析
- sudo 权限——用于 TAP 设备创建与路由配置
- TUN/TAP 内核支持——通常已内置,可用
modprobe tun检查 - Radmin VPN 安装程序——从 radmin-vpn.com 下载。必须是 2.0.x 构建版本(针对 2.0.4899.9 开发)。不支持 Radmin VPN 1.4——在 Wine 垫片下它会注册并打开适配器,但永远无法完成连接,导致 GUI 一直卡在“Connecting...”(正在连接...)状态。
Arch Linux
sudo pacman -S wine mingw-w64-gcc
Ubuntu/Debian
sudo apt install wine64 wine32 gcc-mingw-w64
源码快速开始
git clone https://github.com/baptisterajaut/radmin-vpn-linux.git
cd radmin-vpn-linux
# Option A: download pre-built binaries from GitHub Releases
mkdir -p build
TAG=$(curl -sI https://github.com/baptisterajaut/radmin-vpn-linux/releases/latest | grep -i location | grep -oP 'v[\d.]+')
curl -sL "https://github.com/baptisterajaut/radmin-vpn-linux/releases/download/${TAG}/radmin-vpn-linux-${TAG}.tar.gz" \
| tar xz -C build/
# Option B: build from source
make
# Download Radmin VPN installer from https://www.radmin-vpn.com/
./run.sh --installer ~/Downloads/Radmin_VPN_*.exe
后续运行时,只需:
./run.sh
命令行参数
| 标志 | 说明 |
|---|---|
--installer <path> | Radmin_VPN_*.exe 安装程序的路径(仅首次运行)。 |
--no-ui | 运行服务但不启动 Radmin GUI。 |
--no-broadcast-routes | 不添加广播/组播 → TAP 路由。 |
--filter-ui | 启动可选的 GTK4 数据包过滤 UI(默认关闭)。 |
--fix-chat | 修补 Qt 的 qwindows.dll,修复 Wine 下聊天窗口崩溃问题(默认关闭)。 |
--filter-ui 和 --fix-chat 均需显式启用。过滤 UI 需要 rvpn_filter_ui 二进制(由 make 构建);聊天修复需要 patch_qwindows_font.py 和 Python 3 解释器。
无头 / 服务器模式
另外两个启动器可在没有本地桌面环境的情况下运行 Radmin VPN——适用于 VPS 或数据中心主机。两者的安装和配置方式与 run.sh 完全相同(相同的 wineprefix、相同的 --installer 首次运行流程、相同的 TAP 桥接);唯一区别在于 GUI 的访问方式。
run_datacenter.sh — 通过浏览器访问 GUI
在虚拟显示器(Xvfb)上运行真实的 Radmin GUI,并通过 VNC + noVNC 提供服务,因此你可以从浏览器配置网络,然后让它保持运行。
sudo apt install -y xvfb x11vnc websockify novnc # or: make install-datacenter-deps
./run_datacenter.sh --installer ~/Downloads/Radmin_VPN_*.exe
| 标志 | 默认值 | 说明 |
|---|---|---|
--vnc-port <n> | 5900 | x11vnc 服务器的端口。 |
--web-port <n> | 6080 | noVNC Web 端点的端口。 |
--vnc-password <pw> | (无) | VNC / Web 会话的密码。 |
--web-bind <addr> | 127.0.0.1 | noVNC 监听的地址。 |
默认情况下 noVNC 绑定到 127.0.0.1,因此只能通过 SSH 隧道访问:
ssh -L 6080:localhost:6080 your-vps # then open http://localhost:6080/vnc.html
若要公开暴露,请将 --web-bind 0.0.0.0 与 --vnc-password 一起传递——否则任何访问该 Web 端口的人都会进入一个未经身份验证、且具备 root 能力的桌面。如果在没有密码的情况下公开绑定,脚本会打印一条醒目的警告。
run_vps.sh — 仅服务模式,固定 GUID
以无头模式启动服务,使用硬编码的 TAP GUID(无需 Wine WMI),完全不启动 GUI。如果上一级目录中存在自定义网络枚举器(rv_net_enum.exe,不随本仓库分发),则会启动它;否则服务一直运行直到你按 Ctrl+C。仅接受 --installer 参数。
./run_vps.sh --installer ~/Downloads/Radmin_VPN_*.exe
从源码构建
需要 mingw-w64 交叉编译器。如果你不想安装 mingw,可以从发布页获取预构建二进制文件(由 CI 在每个标签版本上构建)。
make # build everything to build/
make clean # remove build artifacts
构建产物:
build/rvpnnetmp.sys— Wine 内核驱动程序(64 位 PE)build/adapter_hook.dll— 钩子 DLL(32 位 PE)build/rvpn_launcher.exe— DLL 注入器(32 位 PE)build/netsh.exe— netsh 替代品(32 位 PE,安装到 SysWOW64)build/netsh64.exe— netsh 替代品(64 位 PE,安装到 System32)build/drvinst.exe— 无操作存根,替代 Radmin 真正的 NDIS 驱动安装程序(issue #12)build/tap_bridge— 原生 Linux TAP 桥接器build/rvpn_dnsfix.so— 原生 LD_PRELOAD 垫片,仅预加载到服务中build/rvpn_filter_ui— 可选的 GTK4 数据包过滤 UI(--filter-ui)
构建 AppImage
make
./packaging/build-appimage.sh # → packaging/dist/RadminVPN-Linux-x86_64.AppImage
首次运行时下载 Kron4ek Wine-Staging amd64-wow64 构建(约 100 MB)和 appimagetool,并将两者缓存在 packaging/dist/ 中。需要 curl 和 ImageMagick(convert)。
run.sh 的作用
- 首次运行:通过 Wine(
/VERYSILENT)安装 Radmin VPN,移除真正的 NDIS 驱动(与 Wine 不兼容),注册我们的自定义驱动 - 每次运行:创建 TAP 设备,启动 TAP 到 FIFO 的桥接,配置 Wine 注册表(适配器 GUID、驱动服务),启动 Radmin VPN 服务和 GUI
- 退出时(Ctrl+C 或关闭 GUI):终止 Wine,移除 TAP 设备,清理现场
wineprefix 存储在 ./wineprefix/(源码运行)或 ~/.local/share/radmin-vpn-linux/wineprefix/(AppImage)中。首次运行时会生成一个持久 MAC 地址并保存在 wineprefix 中。
架构
| 组件 | 说明 |
|---|---|
rvpnnetmp.sys | Wine 内核驱动程序。模拟 Radmin NDIS 微端口。处理 IOCTL(VERSION、STATUS、SETUP、PEERMAC)、TLV 帧编解码、用于重叠 I/O 的 IRP 队列、基于 MAC 的多对等节点帧路由。 |
adapter_hook.dll | 与 RvControlSvc.exe 一起加载的伴生 DLL。IAT 钩子:将 TAP 适配器重命名为 Radmin 期望的名称,并将 RegSetKeySecurity 变为无操作,以绕开 Wine SCM 中服务缺少 SYSTEM SID 的 bug。 |
tap_bridge | 原生 Linux 二进制程序。在 TAP 设备与 Wine 驱动读写的命名管道(FIFO)之间中继以太网帧。 |
netsh.exe / netsh64.exe | 替代 Wine 的 netsh 存根(32 位在 SysWOW64,64 位在 System32)。通过基于文件的中继将 Windows netsh interface ip 命令转换为 Linux ip addr/ip link 命令,并在地址到达 root 中继前进行校验。 |
rvpn_launcher.exe | 通过 CreateRemoteThread + LoadLibrary 将 adapter_hook.dll 注入 Radmin 服务进程。 |
drvinst.exe | 无操作存根,替代 Radmin 真正的 NDIS 驱动安装程序。Radmin 在运行时调用它以加载 NetMP60_1_1_64.sys,该驱动会通过 NdisInitializeReadWriteLock 中止 Wine 11.x(issue #12);由于我们的驱动已经替代了该适配器,真正的驱动绝不能加载。 |
rvpn_dnsfix.so | 原生 LD_PRELOAD 垫片,仅注入服务启动过程。在 glibc 层直接短路对私有 IPv4/IPv6 的反向 DNS 查询(getnameinfo/gethostbyaddr)。Radmin 会对其收集到的每个本地候选地址进行 PTR 解析;如果主机解析器将 RFC1918 PTR 查询黑洞化,会停滞数分钟,服务虽已注册但永远不就绪(issue #16)。该查询由 Wine 的 Unix 侧发起,adapter_hook.dll 中的任何钩子都无法触及。 |
rvpn_filter_ui | 可选的 GTK4 UI,用于检查和过滤穿过桥接的数据包。默认关闭;使用 --filter-ui 启动。 |
故障排除
GUI 卡在“Waiting for adapter”(等待适配器):驱动程序未加载。检查 /tmp/radmin_driver.log 是否存在且有内容。如果为空,可能是缺少驱动服务注册——删除 wineprefix 并重新运行。
已注册但从未“就绪”:服务到达 Registered as #… 后就此停住。已知两种原因,超时打印的诊断信息块都会报告。(a)具有自身路由策略的透明代理或隧道(sing-box、clash/mihomo、v2ray 等)拦截出站连接——这类协议栈在本地应答 TCP 握手,因此套接字读到的状态是 ESTABLISHED,但实际上没有任何数据被中继。将其路由中的 26.0.0.0/8 排除;如果可以直接访问,也排除 *.radminte.com。(b)解析器将私有地址的反向查询黑洞化(172.17.0.1 处的 docker0 是常见触发源)。rvpn_dnsfix.so 可以处理这种情况,但它是 64 位垫片:以 old-wow64 方式构建的系统 Wine 会忽略它。此场景的解决办法——在 /etc/hosts 中为该地址添加一行,或使用 contrib/run-in-netns.sh(该脚本能让服务达到“就绪”,但会将 VPN 保留在命名空间内:主机应用程序无法访问 26.0.0.0/8,请阅读其文件头部的警告)。
服务立即退出:检查 /tmp/radmin_service.log 中的 Wine 错误。常见原因:来自不同 Wine 版本的旧 wineprefix。删除 ./wineprefix/ 并重新运行。
单个对等节点 0% 丢包,多个对等节点高丢包:这是最初的 bug——已通过驱动中基于 MAC 的帧路由修复。请确保你使用的是最新构建版本。
首次 ping 很慢(约 1 秒):最新版本会为驱动看到的每个 IP 数据包缓存 MAC 地址。如果目标 IP 在驱动运行期间至少发送过一个数据包,MAC 就已经被缓存,ARP 延迟为零。只有完全静默的对等节点(从未发送过数据包的节点)才需要初始 ARP 解析,这大约增加 1 秒。
局域网游戏看不到其他对等节点 / “自动发现”失效:大多数局域网游戏通过广播探测(UDP 发往 255.255.255.255)或组播(224.0.0.0/4)发现彼此。在 Windows 上,Radmin TAP 驱动会将自己宣称为这些流量的首选接口;在 Linux 上,你必须显式告知内核。run.sh 现在会在 VPN 启动时安装两条额外路由:
ip route append 255.255.255.255/32 dev radminvpn0 metric 0
ip route append 224.0.0.0/4 dev radminvpn0 metric 0
副作用:VPN 运行期间,物理局域网上的 mDNS / Bonjour / SSDP(Chromecast、AirPrint、Sonos、智能电视等)会走 VPN。如果你需要本地局域网发现与 Radmin 并行,请使用 --no-broadcast-routes 运行:
./run.sh --no-broadcast-routes
这些路由的作用域限定在 TAP 设备上,因此当 run.sh 在退出时拆除设备后会自动移除。
已知限制
- 同一时间只能运行一个实例(
/tmp/中的共享 FIFO) - 运行期间,
26.0.0.0/8的 on-link 路由会影响整个系统(退出时清理) - 默认广播(
255.255.255.255/32)和组播(224.0.0.0/4)路由会被导向 VPN——如果需要本地局域网 mDNS / SSDP 并行,请使用--no-broadcast-routes禁用 - 较旧的 Wine 版本(< 11.0)可能有不同的重叠 I/O 行为,导致驱动失效
备注
Wine bug 变通方案。 RegSetKeySecurity 钩子绕过了已知的 Wine 限制,即服务无法获得 SYSTEM SID(S-1-5-18)。这在未来 Wine 版本的上游中可能会被修复。
致谢
逆向工程与 Wine 垫片:@baptisterajaut。
- @ayozetr —— 将“已注册但永不就绪”的挂起问题追踪到主机解析器将私有地址的反向 DNS 查询黑洞化这一根因;在排除了四个错误理论(包括我的)之后,用 bare-libc 复现程序证明了这一点,并编写了
src/rvpn_dnsfix.c和contrib/run-in-netns.sh的原始版本。 - @gringoestrangeiro —— Linux 稳定性工作:数据包过滤器、ARP 缓存、崩溃恢复、无头模式和数据中心模式。
- @yuxiaole-bili —— 发现 Wine 的 SCM 会自动启动第二个未挂钩的服务实例,与注入的实例争夺适配器。
- @D1spell-tech、@Milkiway13 以及所有粘贴了完整诊断信息块的人——两个独立主机才能让 bug 可被定位。
许可证
GPL-3.0。参见 LICENSE。
从精神上讲,这段代码属于公有领域——你可以随心所欲地使用它。GPL 在这里充当法律安全网:它明确保护为互操作性而进行的逆向工程,这正是本项目的所作所为。双保险。
Radmin VPN 是 Famatech Corp. 的专有软件。本项目仅提供互操作性工具——不包含也不分发任何 Famatech 代码。