Назад к обновлениям
New releaseAug 20, 2026

radmin-vpn-linux v1.1.0

Запуск Radmin VPN на Linux через Wine — собственный драйвер, TAP-мост, нулевая потеря пакетов

Поделиться

Radmin VPN для Linux

Запуск Radmin VPN на Linux через Wine. Подключайтесь к VPN-сетям, просматривайте пиров, играйте в игры — всё без Windows-виртуальной машины.

Я сделал это не потому, что это проще, чем виртуальная машина. Я сделал это, потому что думал, что это проще, чем виртуальная машина.

Код, созданный с помощью ИИ. Разработан совместно человеком и Claude (Anthropic). Драйвер, хуки и мост были написаны с использованием обширной обратной разработки с помощью ИИ недокументированного протокола драйвера Radmin VPN с использованием Ghidra. Это работает, но без каких-либо гарантий. Не связано с Famatech. Radmin VPN является проприетарным ПО — скачайте его самостоятельно с radmin-vpn.com. Используйте на свой страх и риск.

Как это работает

Служба Windows Radmin VPN взаимодействует с NDIS-минипорт-драйвером для своего виртуального сетевого адаптера. Wine не поддерживает NDIS, поэтому мы заменяем драйвер нашей собственной реализацией, которая связывается с Linux TAP-устройством. Hook-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, с которым проект проверен (или укажите свой с помощью --installer). Откроется терминал с прогрессом, и потребуется один запрос пароля sudo для настройки TAP.

Постоянное состояние (wineprefix, MAC, журналы) хранится в ~/.local/share/radmin-vpn-linux/.

Radmin закрывается сам по себе? Его собственный обновлятор устанавливает новую сборку внутри работающего префикса. Выполните обновление контролируемым способом — это сохранит ваш префикс и ваш Radmin ID:

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

Затем отключите «Автоматические обновления» в настройках Radmin, чтобы он перестал пытаться. Подробности в собственном автообновлении Radmin.

Предварительные требования (сборка из исходников / не-AppImage)

  • Wine >= 11.0 (протестировано на Wine 11.5 Arch Linux и Wine 11.6 Ubuntu 24.04)
  • mingw-w64 кросс-компиляторы (i686-w64-mingw32-gcc, x86_64-w64-mingw32-gcc) — для сборки из исходников
  • iconv (glibc) — для разбора журналов службы
  • sudo доступ — для создания TAP-устройства и маршрутизации
  • Поддержка TUN/TAP в ядре — обычно встроена, проверьте с помощью modprobe tun
  • Установщик Radmin VPN — загружается автоматически, если отсутствует. Версия, с которой проверен этот проект, зафиксирована в одном месте, RADMIN_VERSION в lib.sh (в настоящее время 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

# Загрузите установщик Radmin VPN с https://www.radmin-vpn.com/
./run.sh --installer ~/Downloads/Radmin_VPN_*.exe

При последующих запусках просто:

./run.sh

Параметры командной строки

ФлагОписание
--installer <path>Путь к установщику Radmin_VPN_*.exe (только при первом запуске).
--no-uiЗапуск службы без запуска GUI Radmin.
--updateОбновление Radmin до зафиксированной версии на месте. Сохраняет префикс, поэтому RID, зарегистрированный в Famatech, сохраняется.
--no-broadcast-routesНе добавлять маршруты broadcast/multicast → TAP.
--filter-uiЗапуск дополнительного GTK4 интерфейса фильтрации пакетов (по умолчанию выключен).
--fix-chatПатч qwindows.dll из Qt для исправления сбоя окна чата под Wine (по умолчанию выключен).

Собственное автообновление Radmin

GUI Radmin может загрузить новую сборку и запустить её установщик внутри живого префикса, что убивает GUI и вызывает сбой работающей службы (журнал GUI затем показывает установщик в AppData\\Local\\Temp). Две защиты: лаунчер поставляет текущую проверенную сборку, поэтому обновлятору нечего устанавливать, а GUI, который умирает, больше не тянет за собой туннель — он перезапускается один раз, затем VPN продолжает работать в фоновом режиме. Для намеренного обновления используйте ./run.sh --update, который сначала останавливает всё. Отключение «Автоматических обновлений» в настройках GUI полностью исключает гонку.

Оба параметра --filter-ui и --fix-chat являются опциональными. Интерфейсу фильтрации нужен бинарник rvpn_filter_ui (собирается командой make); исправление чата требует patch_qwindows_font.py и интерпретатор Python 3.

Режимы без графического интерфейса / серверные режимы

Два дополнительных лаунчера запускают Radmin VPN без локального рабочего стола — для VPS или хостинга в дата-центре. Оба устанавливаются и настраиваются точно так же, как run.sh (тот же wineprefix, тот же процесс первого запуска с --installer, тот же TAP-мост); они отличаются только способом доступа к GUI.

run_datacenter.sh — GUI через браузер

Запускает настоящий GUI Radmin на виртуальном дисплее (Xvfb) и предоставляет к нему доступ через 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>5900Порт для сервера x11vnc.
--web-port <n>6080Порт для веб-интерфейса noVNC.
--vnc-password <pw>(нет)Пароль для сеанса VNC / веб-интерфейса.
--web-bind <addr>127.0.0.1Адрес, на котором слушает noVNC.

По умолчанию 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 — в противном случае любой, кто получит доступ к веб-порту, попадёт на неаутентифицированный рабочий стол с правами 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. Готовые бинарники доступны в Releases (собираются CI для каждой тегированной версии), если вы не хотите устанавливать mingw.

make          # собрать всё в build/
make clean    # удалить артефакты сборки

Результат:

  • build/rvpnnetmp.sys — драйвер ядра Wine (64-битный PE)
  • build/adapter_hook.dll — Hook-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 — заглушка no-op, заменяющая реальный установщик NDIS-драйвера Radmin (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 интерфейс фильтрации пакетов (--filter-ui)

Сборка AppImage

make
./packaging/build-appimage.sh       # → packaging/dist/RadminVPN-Linux-x86_64.AppImage

При первом запуске загружает сборку Kron4ek Wine-Staging amd64-wow64 (~100 МБ) и appimagetool, кэширует обе в packaging/dist/. Требуются curl и ImageMagick (convert).

Что делает run.sh

  1. Первый запуск: устанавливает Radmin VPN через Wine (/VERYSILENT), удаляет реальный NDIS-драйвер (несовместим с Wine), регистрирует наш пользовательский драйвер
  2. Каждый запуск: создаёт TAP-устройство, запускает мост TAP-to-FIFO, настраивает реестр Wine (GUID адаптера, служба драйвера), запускает службу и GUI Radmin VPN
  3. При выходе (Ctrl+C или закрытие GUI): убивает Wine, удаляет TAP-устройство, выполняет очистку

Wineprefix хранится в ./wineprefix/ (запуск из исходников) или ~/.local/share/radmin-vpn-linux/wineprefix/ (AppImage). Постоянный MAC-адрес генерируется при первом запуске и сохраняется в wineprefix.

Архитектура

КомпонентОписание
rvpnnetmp.sysДрайвер ядра Wine. Эмулирует NDIS-минипорт Radmin. Обрабатывает IOCTL (VERSION, STATUS, SETUP, PEERMAC), кодирование/декодирование TLV-кадров, очередь IRP для перекрытого ввода-вывода, маршрутизацию кадров на основе MAC для поддержки нескольких пиров.
adapter_hook.dllКомпаньон-DLL, загружаемая вместе с RvControlSvc.exe. IAT-хуки: переименовывает TAP-адаптер в ожидаемое Radmin имя, превращает RegSetKeySecurity в no-op для обхода бага SCM в Wine, где службам не хватает SYSTEM SID, и отвечает на четыре запроса Perf{Increment,Decrement}ULong{,Long}CounterValue, которые Wine advapi32 не экспортирует. Последнее не косметическое: Radmin 2.1 разрешает семь точек входа perflib в одном каскаде «всё или ничего», затем передаёт полученный объект счётчика на пира как полезную нагрузку рукопожатия пира — поэтому четыре отсутствующих телеметрических экспорта разрушают весь путь данных (issue #24, docs/wine-perflib.md).
tap_bridgeНативный Linux-бинарник. Передаёт ethernet-кадры между TAP-устройством и именованными каналами (FIFO), которые читает/пишет Wine-драйвер.
netsh.exe / netsh64.exeЗаменяет заглушку netsh в Wine (32-битную в SysWOW64, 64-битную в System32). Преобразует Windows-команды netsh interface ip в Linux-команды ip addr/ip link через файловый ретранслятор, проверяя адрес до того, как он достигнет корневого ретранслятора.
rvpn_launcher.exeИнжектирует adapter_hook.dll в процесс службы Radmin через CreateRemoteThread + LoadLibrary.
drvinst.exeЗаглушка no-op, заменяющая реальный установщик NDIS-драйвера Radmin. Radmin запускает его во время выполнения для загрузки NetMP60_1_1_64.sys, который прерывает Wine 11.x через NdisInitializeReadWriteLock (issue #12); поскольку наш драйвер уже заменяет этот адаптер, реальный никогда не должен загружаться.
rvpn_dnsfix.soНативная LD_PRELOAD-прокладка, инжектируется только при запуске службы. Замыкает обратный DNS (getnameinfo/gethostbyaddr) для частных IPv4/IPv6 на уровне glibc. Radmin выполняет PTR-разрешение для каждого собранного локального адреса-кандидата; на хосте, чей резолвер блокирует PTR-запросы RFC1918, это зависает на минуты, и служба регистрируется, но никогда не становится готовой (issue #16). Запрос выполняется Unix-стороной Wine, вне досягаемости любых хуков внутри adapter_hook.dll.
rvpn_reuseport.soНативная LD_PRELOAD-прокладка, предзагружается в wineserver (не в службу — Unix-сокеты принадлежат wineserver). Устанавливает SO_REUSEPORT на каждом TCP-сокете при создании. Radmin 2.1 выполняет NAT-траверс с повторным использованием TCP-портов: он привязывает слушатель к uplink:PORT, рекламирует это сопоставление, затем привязывает свои исходящие пир-сокеты к тому же локальному порту с SO_REUSEADDR, что разрешено в Windows. Wine преобразует этот запрос в отсутствие Unix-уровневой опции для TCP (server/sock.c, SO_REUSEPORT компилируется только для __APPLE__), поэтому ядро отказывает во второй привязке, и клиент видит WSAEACCES при каждом подключении к пиру (issue #24). Собственный учёт конфликтов wineserver всё ещё работает, поэтому привязки, которые Windows отказала бы, по-прежнему отклоняются.
rvpn_filter_uiДополнительный GTK4-интерфейс для просмотра и фильтрации пакетов, пересекающих мост. По умолчанию выключен; запускается с --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) Резолвер, который блокирует обратные запросы частных адресов (обычный триггер — docker0 на 172.17.0.1). rvpn_dnsfix.so обрабатывает это, но это 64-битная прокладка: системный Wine, собранный как old-wow64, игнорирует её. Обходной путь — добавьте строку для адреса в /etc/hosts или используйте contrib/run-in-netns.sh (который доводит службу до состояния «готов», но держит VPN внутри namespace: хост-приложения не могут достичь 26.0.0.0/8, прочитайте предупреждение в его заголовке).

Ваши другие Wine-приложения сломались после запуска Radmin (unimplemented function ndis.sys.NdisInitializeReadWriteLock): версии до 1.0.0 позволяли запускаться winemenubuilder.exe из Wine, который переписывает файловые ассоциации Windows на хосте (.exe, .msi, .lnk, .reg, .chm, …), чтобы они открывались в нашем префиксе. Другие Windows-программы затем запускаются внутри префикса Radmin, и если реальный NDIS-минипорт Radmin (RvNetMP60) всё ещё зарегистрирован там, каждая из них прерывается на этой ndis-заглушке. Версия 1.0.1 отключает winemenubuilder везде, очищает записи, которые он создал для префикса Radmin, и удаляет RvNetMP60 из system.reg в автономном режиме — просто запустите 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): это Radmin 2.1 на сборке старше 1.1.0. Журнал службы выглядит здоровым вплоть до подключений к пирам, которые затем завершаются с ошибкой в цикле с этим кодом и в итоге сдаются с node offline. Два независимых пробела Wine, оба исправлены в 1.1.0 и оба объяснены выше в строках rvpn_reuseport.so и adapter_hook.dll: Wine не устанавливает Unix-уровневую опцию для TCP SO_REUSEADDR, поэтому NAT-траверс с повторным использованием портов в 2.1 получает WSAEACCES при каждом подключении к пиру; и в Wine advapi32 отсутствуют четыре perflib-экспорта, без которых 2.1 отправляет нулевую полезную нагрузку как рукопожатие пира. Обратите внимание, что сам код не несёт информации — это общий отказ в конце каскада ошибок, поэтому не пытайтесь вычитать из него подсистему. Исправление — обновить этот проект до 1.1.0; на стороне Radmin ничего менять не нужно.

Служба умирает сразу: проверьте /tmp/radmin_service.log на ошибки Wine. Частая причина: старый wineprefix от другой версии Wine. Удалите ./wineprefix/ и запустите заново.

0% потери пакетов с одним пиром, высокая потеря со многими: это была исходная ошибка — исправлена маршрутизацией кадров на основе MAC в драйвере. Убедитесь, что используете последнюю сборку.

Первый ping медленный (~1с): последняя версия кэширует MAC-адреса для каждого IP-пакета, который видит драйвер. Если целевой IP отправил хотя бы один пакет, пока драйвер работал, MAC уже кэширован, и задержка ARP нулевая. Только полностью молчаливые пиры (те, кто никогда не отправлял пакет) требуют начального ARP-разрешения, что добавляет ~1 секунду.

LAN-игры не видят других пиров / «автообнаружение» сломано: большинство LAN-игр обнаруживают друг друга с помощью broadcast-зондов (UDP на 255.255.255.255) или multicast (224.0.0.0/4). В Windows TAP-драйвер Radmin рекламирует себя как предпочтительный интерфейс для этих потоков; в 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 в вашей физической LAN (Chromecast, AirPrint, Sonos, умные ТВ, ...) будут проходить через VPN, пока он активен. Если вам нужны локальное LAN-обнаружение и Radmin параллельно, запускайте с --no-broadcast-routes:

./run.sh --no-broadcast-routes

Маршруты привязаны к TAP-устройству, поэтому они автоматически удаляются, когда run.sh завершает работу устройства при выходе.

Известные ограничения

  • Одновременно может работать только один экземпляр (общие FIFO в /tmp/)
  • Маршрут on-link 26.0.0.0/8 влияет на всю систему, пока работает (очищается при выходе)
  • Маршруты по умолчанию для broadcast (255.255.255.255/32) и multicast (224.0.0.0/4) направляются в VPN — отключите с помощью --no-broadcast-routes, если нужны локальные mDNS / SSDP в LAN параллельно
  • Старые версии Wine (< 11.0) могут иметь другое поведение перекрытого ввода-вывода, которое ломает драйвер

Примечания

Обход бага Wine. Хук RegSetKeySecurity обходит известное ограничение Wine, где службы не получают SYSTEM SID (S-1-5-18). Это может быть исправлено в апстриме в будущем релизе Wine.

Благодарности

Обратная разработка и Wine-прокладка: @baptisterajaut.

  • @ayozetr — отследил зависание «регистрируется, но никогда не готов» до обратного DNS-запроса частного адреса, блокируемого резолвером хоста, доказал это с помощью воспроизведения на голой libc после того, как четыре неверные теории были отброшены (включая мою), и написал оригинал src/rvpn_dnsfix.c и contrib/run-in-netns.sh.
  • @gringoestrangeiro — работа над стабильностью Linux: фильтры пакетов, ARP-кэш, восстановление после сбоев, режимы без графического интерфейса и для дата-центра.
  • @yuxiaole-bili — обнаружил, что SCM в Wine автоматически запускает второй, не-хукнутый экземпляр службы, который борется с инжектированным за адаптер.
  • @D1spell-tech, @Milkiway13 и все, кто вставил полный диагностический блок — два независимых хоста — вот что делает баг находимым.

Лицензия

GPL-3.0. См. LICENSE.

По духу этот код является общественным достоянием — делайте с ним что хотите. GPL здесь как юридическая страховка: она явно защищает обратную разработку для совместимости, что и делает этот проект. Ремень и подтяжки.

Radmin VPN — проприетарное ПО компании Famatech Corp. Этот проект предоставляет только инструменты совместимости — код Famatech не включён и не распространяется.

Категории