返回更新列表
新发布Jul 24, 2026

radmin-vpn-linux v1.0.0-rc9

通过 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 兼容性问题(适配器命名、注册表权限)。最终成果是一个在 Wine 下原生运行的、功能完整的 Radmin VPN 客户端。

Linux 应用 ← TAP (radminvpn0) ← tap_bridge ← FIFO ← rvpnnetmp.sys (Wine 驱动) ← 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 安装程序(或使用 --installer 传入你自己的安装程序)。终端会显示进度,并且需要一次 sudo 密码提示来完成 TAP 设置。

持久化状态(wineprefix、MAC、日志)存储在 ~/.local/share/radmin-vpn-linux/ 中。

Radmin 自行关闭? 它自带的更新程序正在运行中的 prefix 内安装更新版本。 请以受控方式执行升级——这样可以保留你的 prefix 和 Radmin ID:

./RadminVPN-Linux-x86_64.AppImage --update

然后在 Radmin 设置中关闭“自动更新”,使其不再尝试。详情请参阅 Radmin 自带的自动更新程序

前置条件(源码构建 / 非 AppImage)

  • Wine >= 11.0(已在 Arch Linux 的 Wine 11.5 和 Ubuntu 24.04 的 Wine 11.6 上测试)
  • mingw-w64 交叉编译器(i686-w64-mingw32-gccx86_64-w64-mingw32-gcc)——用于从源码构建
  • iconv(glibc)——用于服务日志解析
  • sudo 权限——用于 TAP 设备创建和路由配置
  • TUN/TAP 内核支持——通常已内置,使用 modprobe tun 检查
  • Radmin VPN 安装程序——如果缺失则自动下载。本项目验证过的版本在 lib.sh 中的 RADMIN_VERSION 一处固定(当前为 2.1.4951.1;2.0.4899.9 也可用)。Radmin VPN 1.4 不受支持——它能够注册并打开适配器,但在 Wine 垫片下永远无法完成连接,导致 GUI 卡在“正在连接...”。

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

# 选项 A:从 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/

# 选项 B:从源码构建
make

# 从 https://www.radmin-vpn.com/ 下载 Radmin VPN 安装程序
./run.sh --installer ~/Downloads/Radmin_VPN_*.exe

后续运行时,只需:

./run.sh

命令行参数

参数描述
--installer <path>Radmin_VPN_*.exe 安装程序的路径(仅首次运行)。
--no-ui运行服务但不启动 Radmin GUI。
--update就地升级 Radmin 到固定版本。保留 prefix,因此向 Famatech 注册的 RID 得以保留。
--no-broadcast-routes不添加广播/组播 → TAP 路由。
--filter-ui启动可选的 GTK4 数据包过滤 UI(默认关闭)。
--fix-chat修补 Qt 的 qwindows.dll 以修复 Wine 下的聊天窗口崩溃问题(默认关闭)。

Radmin 自带的自动更新程序

Radmin 的 GUI 可以下载更新版本并在运行中的 prefix 内运行其安装程序, 这会杀死 GUI 并使运行中的服务出错(GUI 日志随后会显示 AppData\\Local\\Temp 下的安装程序)。两道防线:启动器附带当前已验证的构建版本,因此更新程序无内容可推送;并且 GUI 崩溃不再拖垮隧道——它会被重启一次,然后 VPN 继续以无头模式运行。要主动升级,请使用 ./run.sh --update,它会先停止所有内容。在 GUI 设置中关闭“自动更新”可以完全避免竞争条件。

--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   # 或:make install-datacenter-deps
./run_datacenter.sh --installer ~/Downloads/Radmin_VPN_*.exe
参数默认值描述
--vnc-port <n>5900x11vnc 服务器的端口。
--web-port <n>6080noVNC Web 端点的端口。
--vnc-password <pw>(无)VNC / Web 会话的密码。
--web-bind <addr>127.0.0.1noVNC 监听的地址。

默认情况下 noVNC 绑定到 127.0.0.1,因此只能通过 SSH 隧道访问:

ssh -L 6080:localhost:6080 your-vps    # 然后打开 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,可以从 Releases 获取预构建二进制文件(由 CI 在每个标记版本上构建)。

make          # 构建所有内容到 build/
make clean    # 移除构建产物

生成产物:

  • 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_reuseport.so — 原生 LD_PRELOAD 垫片,预加载到 wineserver
  • 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 的功能

  1. 首次运行:通过 Wine 安装 Radmin VPN(/VERYSILENT),移除真正的 NDIS 驱动程序(与 Wine 不兼容),注册我们的自定义驱动程序
  2. 每次运行:创建 TAP 设备,启动 TAP 到 FIFO 的桥接器,配置 Wine 注册表(适配器 GUID、驱动程序服务),启动 Radmin VPN 服务和 GUI
  3. 退出时(Ctrl+C 或关闭 GUI):终止 Wine,移除 TAP 设备,清理

wineprefix 存储在 ./wineprefix/(源码运行)或 ~/.local/share/radmin-vpn-linux/wineprefix/(AppImage)中。首次运行时会生成一个持久的 MAC 地址并保存在 wineprefix 中。

架构

组件描述
rvpnnetmp.sysWine 内核驱动程序。模拟 Radmin NDIS 微型端口。处理 IOCTL(VERSION、STATUS、SETUP、PEERMAC)、TLV 帧编解码、用于重叠 I/O 的 IRP 队列、基于 MAC 的帧路由以支持多对等节点。
adapter_hook.dll与 RvControlSvc.exe 一起加载的伴随 DLL。IAT 钩子:将 TAP 适配器重命名为 Radmin 期望的名称,将 RegSetKeySecurity 变为无操作以绕过 Wine SCM 的一个 bug(服务缺少 SYSTEM SID),并应答 Wine 的 advapi32 未导出的四个 Perf{Increment,Decrement}ULong{,Long}CounterValue 查找。最后一项并非装饰性:Radmin 2.1 在一个全有或全无的级联中解析七个 perflib 入口点,然后将生成的每对等节点计数器对象作为对等节点握手的负载传递——因此四个缺失的遥测导出会导致整个数据路径瘫痪(issue #24,docs/wine-perflib.md)。
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 + LoadLibraryadapter_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_reuseport.so原生 LD_PRELOAD 垫片,预加载到 wineserver 中(而非服务中——Unix 套接字属于 wineserver)。在创建时为每个 TCP 套接字设置 SO_REUSEPORT。Radmin 2.1 执行 TCP 端口复用 NAT 穿越:它将监听器绑定到 uplink:PORT,通告该映射,然后将其出站对等套接字以 SO_REUSEADDR 绑定到同一本地端口,Windows 允许这样做。Wine 将该请求转换为无 Unix 级 TCP 选项(server/sock.cSO_REUSEPORT 仅编译为 __APPLE__),因此内核拒绝第二次绑定,客户端在每个对等连接上看到 WSAEACCES(issue #24)。Wineserver 自身的冲突簿记仍然运行,因此 Windows 会拒绝的绑定仍然会被拒绝。
rvpn_filter_ui可选的 GTK4 UI,用于检查和过滤穿过桥接器的数据包。默认关闭;使用 --filter-ui 启动。

故障排除

GUI 卡在“正在等待适配器”:驱动程序未加载。检查 /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,请阅读其头部的警告)。

运行 Radmin 后你的其他 Wine 应用损坏(unimplemented function ndis.sys.NdisInitializeReadWriteLock:1.0.0 之前的版本允许 Wine 的 winemenubuilder.exe 运行,它会重写主机的 Windows 文件关联(.exe.msi.lnk.reg.chm 等)以在我们的 prefix 中打开。其他 Windows 程序随后会在 Radmin prefix 内启动,如果 Radmin 真正的 NDIS 微型端口(RvNetMP60)仍在那里注册,它们每个都会在该 ndis 存根上中止。1.0.1 在所有位置禁用 winemenubuilder,清除它为 Radmin prefix 写入的条目,并离线从 system.reg 中移除 RvNetMP60——只需运行一次 1.0.1,两者都会被修复。注意,在这种情况下 echo $WINEPREFIX 不显示任何内容:劫持位于 ~/.local/share/applications/*.desktop 中,而非你的环境中。如果你愿意,可以手动清理:

grep -rl 'WINEPREFIX=[^"]*radmin' ~/.local/share/applications --include='*.desktop' | xargs -r rm
rm -rf ~/.local/share/applications/wine/Programs/"Radmin VPN"
update-desktop-database ~/.local/share/applications

在线且在你的网络中,但没有对等节点能连接(error: 0x700000000:这是 1.1.0 之前构建上的 Radmin 2.1。服务日志在对等连接之前看起来正常,然后以该代码循环失败,最终以 node offline 放弃。两个独立的 Wine 缺口,均在 1.1.0 中修复,且都在上面的 rvpn_reuseport.soadapter_hook.dll 行中解释过:Wine 不为 TCP SO_REUSEADDR 设置 Unix 级选项,因此 2.1 的端口复用 NAT 穿越在每个对等连接上得到 WSAEACCES;且 Wine 的 advapi32 缺少四个 perflib 导出,没有它们 2.1 会发送空负载作为其对等握手。注意该代码本身不携带任何信息——它是错误级联末尾的通用放弃信号,所以不要试图从中解读出子系统。修复方法是将此项目更新到 1.1.0;Radmin 侧无需任何更改。

服务立即死亡:检查 /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

副作用:物理局域网上的 mDNS / Bonjour / SSDP(Chromecast、AirPrint、Sonos、智能电视等)在 VPN 运行期间会走 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 查找,在四个错误理论(包括我的)被排除后,用裸 libc 复现证明了这一点,并编写了 src/rvpn_dnsfix.ccontrib/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 代码。

分类