
Radmin VPN を Linux で Wine 経由で実行 — カスタムドライバー、TAP ブリッジ、パケットロスゼロ
# Linux向けRadmin VPN
[Radmin VPN](https://www.radmin-vpn.com/)をWine経由でLinux上で実行します。VPNネットワークへの参加、ピアの確認、ゲームプレイが可能です——Windows VMは不要です。
> これはVMより簡単だから作ったわけではありません。VMより簡単だと思ったから作ったのです。
**AI支援コード。** 人間とClaude(Anthropic)の共同作業で構築されました。ドライバ、フック、ブリッジは、Ghidraを使用したRadmin VPNの非公開ドライバプロトコルの広範なAI支援リバースエンジニアリングによって作成されました。**動作はしますが、保証はありません。** Famatechとは提携関係にありません。Radmin VPNはプロプライエタリです——[radmin-vpn.com](https://www.radmin-vpn.com/)からご自身でダウンロードしてください。自己責任で使用してください。
## 仕組み
Radmin VPNのWindowsサービスは、仮想ネットワークアダプタ用にNDISミニポートドライバと通信します。WineはNDISをサポートしていないため、ドライバをLinux TAPデバイスにブリッジする独自実装に置き換えます。フックDLLがWineの互換性問題(アダプタ名、レジストリ権限)を処理します。結果として、Wine上でネイティブに動作する完全に機能するRadmin VPNクライアントが実現します。
```
Linux app ← TAP (radminvpn0) ← tap_bridge ← FIFO ← rvpnnetmp.sys (Wine driver) ← RvControlSvc.exe
```
## クイックスタート(AppImage、推奨)
[最新リリース](https://github.com/baptisterajaut/radmin-vpn-linux/releases/latest)から`RadminVPN-Linux-x86_64.AppImage`を取得してください。インストールは不要です——Wineが同梱されています。
> **リリース候補**(例:`v1.0.0-rc1`)はGitHubの*プレリリース*として公開されています。上記の`latest`リンクは常に最新の*安定版*ビルドを指すため、プレリリースはそこには表示されません——[完全なリリース一覧](https://github.com/baptisterajaut/radmin-vpn-linux/releases)から取得してください。
```bash
chmod +x RadminVPN-Linux-x86_64.AppImage
./RadminVPN-Linux-x86_64.AppImage
```
初回起動時に、検証済みのRadmin VPNインストーラをダウンロードします(または`--installer`で独自のものを指定)。進捗表示付きのターミナルが開き、TAPセットアップ用にsudoパスワードの入力が1回求められます。
永続状態(wineprefix、MAC、ログ)は`~/.local/share/radmin-vpn-linux/`に保存されます。
> **Radminが自動で終了する場合?** 独自のアップデータが実行中のプレフィックス内に新しいビルドをインストールしています。代わりに制御された方法でアップグレードしてください——プレフィックスとRadmin IDは保持されます:
> ```bash
> ./RadminVPN-Linux-x86_64.AppImage --update
> ```
> その後、Radminの設定で「自動更新」をオフにして、再試行を防いでください。詳細は[Radmin独自の自動アップデータ](#radmins-own-auto-updater)を参照してください。
## 前提条件(ソースビルド / 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インストーラ**——存在しない場合は自動ダウンロードされます。このプロジェクトが検証されているバージョンは、`lib.sh`内の`RADMIN_VERSION`という1箇所に固定されています(現在は**2.1.4951.1**;2.0.4899.9も動作します)。Radmin VPN **1.4はサポートされていません**——登録とアダプタのオープンは行われますが、Wineシムの下では接続が完了せず、GUIが「接続中...」で停止したままになります。
### Arch Linux
```bash
sudo pacman -S wine mingw-w64-gcc
```
### Ubuntu/Debian
```bash
sudo apt install wine64 wine32 gcc-mingw-w64
```
## ソースクイックスタート
```bash
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
```
以降の実行では、単に:
```bash
./run.sh
```
### コマンドラインフラグ
| フラグ | 説明 |
|------|-------------|
| `--installer <path>` | `Radmin_VPN_*.exe`インストーラへのパス(初回のみ)。 |
| `--no-ui` | Radmin GUIを起動せずにサービスを実行。 |
| `--update` | Radminを固定バージョンにその場でアップグレード。プレフィックスを保持するため、Famatechに登録されたRIDは維持されます。 |
| `--no-broadcast-routes` | ブロードキャスト/マルチキャスト→TAPルートを追加しない。 |
| `--filter-ui` | オプションのGTK4パケットフィルタUIを起動(デフォルトではオフ)。 |
| `--fix-chat` | Qtの`qwindows.dll`にパッチを適用してWineでのチャットウィンドウクラッシュを修正(デフォルトではオフ)。 |
### Radmin独自の自動アップデータ
RadminのGUIは新しいビルドをダウンロードし、*実行中のプレフィックス内*でインストーラを実行できます。これによりGUIが強制終了され、実行中のサービスに障害が発生します(GUIログには`AppData\\Local\\Temp`配下のインストーラが表示されます)。防御策は2つ:ランチャーが現在の検証済みビルドを同梱しているためアップデータがプッシュするものがないこと、そして終了したGUIがトンネルを道連れにしなくなったことです——一度再起動され、その後VPNはヘッドレスで実行を継続します。意図的にアップグレードするには、まずすべてを停止する`./run.sh --update`を使用してください。GUI設定で「自動更新」をオフにすると、競合を完全に回避できます。
`--filter-ui`と`--fix-chat`はどちらもオプトインです。フィルタUIには`rvpn_filter_ui`バイナリ(`make`でビルド)が必要です。チャット修正には`patch_qwindows_font.py`とPython 3インタプリタが必要です。
## ヘッドレス / サーバーモード
ローカルデスクトップなしでRadmin VPNを実行するための追加ランチャーが2つあります——VPSやデータセンターホスト用です。どちらも`run.sh`とまったく同じようにインストールおよび設定されます(同じwineprefix、同じ`--installer`初回フロー、同じTAPブリッジ)。GUIへのアクセス方法のみが異なります。
### `run_datacenter.sh` — ブラウザ経由のGUI
仮想ディスプレイ(Xvfb)上で実際のRadmin GUIを実行し、VNC + noVNC経由で提供します。ブラウザからネットワークを設定し、そのまま実行を継続できます。
```bash
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 Webエンドポイントのポート。 |
| `--vnc-password <pw>` | *(なし)* | VNC / Webセッションのパスワード。 |
| `--web-bind <addr>` | `127.0.0.1` | noVNCがリッスンするアドレス。 |
デフォルトではnoVNCは`127.0.0.1`にバインドされるため、SSHトンネル経由でのみ到達可能です:
```bash
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`、このリポジトリには同梱されていません)が1つ上のディレクトリに存在する場合は起動されます。それ以外の場合は、Ctrl+Cするまでサービスが実行されます。`--installer`のみ受け付けます。
```bash
./run_vps.sh --installer ~/Downloads/Radmin_VPN_*.exe
```
## ソースからのビルド
`mingw-w64`クロスコンパイラが必要です。ビルド済みバイナリは[Releases](https://github.com/baptisterajaut/radmin-vpn-linux/releases)から入手できます(各タグ付きバージョンでCIによってビルドされます)。mingwをインストールしたくない場合はそちらを使用してください。
```bash
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ドライバインストーラを置き換えるno-opスタブ(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のビルド
```bash
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-to-FIFOブリッジを起動、Wineレジストリを設定(アダプタGUID、ドライバサービス)、Radmin VPNサービスとGUIを起動
3. **終了時**(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が期待する名前にリネーム、WineのSCMバグ(サービスにSYSTEM SIDがない)を回避するために`RegSetKeySecurity`をno-op化、Wineの`advapi32`がエクスポートしない4つの`Perf{Increment,Decrement}ULong{,Long}CounterValue`ルックアップに応答。最後のは見た目だけの問題ではありません:Radmin 2.1は7つのperflibエントリポイントを全か無かのカスケードで解決し、結果のピアごとのカウンタオブジェクトをピアハンドシェイクのペイロードとして渡します——つまり4つの欠落したテレメトリエクスポートがデータパス全体を停止させます(issue #24、`docs/wine-perflib.md`)。 |
| `tap_bridge` | ネイティブLinuxバイナリ。TAPデバイスとWineドライバが読み書きする名前付きパイプ(FIFO)の間でイーサネットフレームを中継。 |
| `netsh.exe` / `netsh64.exe` | Wineのnetshスタブを置換(SysWOW64では32ビット、System32では64ビット)。Windowsの`netsh interface ip`コマンドをファイルベースのリレーを介してLinuxの`ip addr`/`ip link`コマンドに変換し、アドレスがrootリレーに到達する前に検証。 |
| `rvpn_launcher.exe` | `CreateRemoteThread` + `LoadLibrary`を介して`adapter_hook.dll`をRadminサービスプロセスに注入。 |
| `drvinst.exe` | Radminの実際のNDISドライバインストーラを置き換えるno-opスタブ。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クエリをブラックホールするホストでは、これが数分間停止し、サービスは登録されるもののreadyになりません(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はその要求をTCP用のUnixレベルのオプションに変換しません(`server/sock.c`、`SO_REUSEPORT`は`__APPLE__`専用にコンパイルされます)。そのためカーネルは2回目のバインドを拒否し、クライアントはすべてのピア接続で`WSAEACCES`を確認します(issue #24)。wineserver自身の競合ブックキーピングは引き続き実行されるため、Windowsが拒否するバインドは依然として拒否されます。 |
| `rvpn_filter_ui` | ブリッジを通過するパケットを検査およびフィルタリングするためのオプションのGTK4 UI。デフォルトではオフ。`--filter-ui`で起動。 |
## トラブルシューティング
**GUIが「アダプタを待機中」で停止**:ドライバがロードされていません。`/tmp/radmin_driver.log`が存在し、内容があることを確認してください。空の場合は、ドライバサービスの登録が欠落している可能性があります——wineprefixを削除して再実行してください。
**登録されたが「ready」にならない**:サービスが`Registered as #…`に到達して停止します。既知の原因は2つあり、どちらもタイムアウト時に表示される診断ブロックで報告されます。(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`を使用します(サービスを「ready」にしますが、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`など)が*当社の*プレフィックスで開くように書き換えられます。他のWindowsプログラムがRadminプレフィックス内で起動し、Radminの実際のNDISミニポート(`RvNetMP60`)がまだそこに登録されている場合、それらのすべてがそのndisスタブで中止されます。1.0.1は`winemenubuilder`をすべての場所で無効化し、Radminプレフィックス用に書き込まれたエントリを削除し、`system.reg`から`RvNetMP60`をオフラインで削除します——1.0.1を一度実行するだけで両方が修復されます。この状況では`echo $WINEPREFIX`が何も表示しないことに注意してください:ハイジャックは`~/.local/share/applications/*.desktop`にあり、環境変数にはありません。手動クリーンアップを希望する場合:
```bash
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`で諦めます。2つの独立したWineのギャップがあり、両方とも1.1.0で修正され、両方とも上記の`rvpn_reuseport.so`と`adapter_hook.dll`の行で説明されています:WineはTCPの`SO_REUSEADDR`にUnixレベルのオプションを設定しないため、2.1のポート再利用NATトラバーサルはすべてのピア接続で`WSAEACCES`を取得します。また、Wineの`advapi32`には4つのperflibエクスポートが欠落しており、これがないと2.1はピアハンドシェイクとしてnullペイロードを送信します。コード自体には情報が含まれていないことに注意してください——これはエラーカスケードの最後にある一般的な諦めコードであり、そこからサブシステムを読み取ろうとしないでください。修正方法はこのプロジェクトを1.1.0に更新することです。Radmin側で変更する必要はありません。
**サービスが即座に終了する**:`/tmp/radmin_service.log`でWineエラーを確認してください。一般的な原因:異なるWineバージョンからの古いwineprefix。`./wineprefix/`を削除して再実行してください。
**1つのピアでは0%のパケットロス、多数のピアでは高いロス**:これは元のバグでした——ドライバのMACベースのフレームルーティングで修正済み。最新ビルドを使用していることを確認してください。
**最初のpingが遅い(約1秒)**:最新バージョンはドライバが確認するすべてのIPパケットのMACアドレスをキャッシュします。ターゲットIPがドライバ実行中に少なくとも1つのパケットを送信した場合、MACはすでにキャッシュされており、ARP遅延はゼロです。完全にサイレントなピア(パケットを一度も送信したことがないもの)のみが初期ARP解決を必要とし、約1秒追加されます。
**LANゲームが他のピアを認識しない / 「自動検出」が壊れている**:ほとんどのLANゲームはブロードキャストプローブ(UDPから`255.255.255.255`)またはマルチキャスト(`224.0.0.0/4`)で互いを検出します。WindowsではRadmin TAPドライバがこれらのフローの優先インターフェースとして自身をアドバタイズします。Linuxではカーネルに明示的に指示する必要があります。`run.sh`はVPNが起動したときに2つの追加ルートをインストールするようになりました:
```
ip route append 255.255.255.255/32 dev radminvpn0 metric 0
ip route append 224.0.0.0/4 dev radminvpn0 metric 0
```
副作用:物理LAN上のmDNS / Bonjour / SSDP(Chromecast、AirPrint、Sonos、スマートTVなど)は、VPNが起動している間はVPN経由で送信されます。ローカルLAN検出とRadminを並行して使用する必要がある場合は、`--no-broadcast-routes`で実行してください:
```bash
./run.sh --no-broadcast-routes
```
ルートはTAPデバイスにスコープされているため、`run.sh`が終了時にデバイスを破棄すると自動的に削除されます。
## 既知の制限事項
- 同時に実行できるインスタンスは1つのみ(`/tmp/`内の共有FIFO)
- `26.0.0.0/8`のオンリンクルートは実行中システム全体に影響(終了時にクリーンアップ)
- デフォルトのブロードキャスト(`255.255.255.255/32`)およびマルチキャスト(`224.0.0.0/4`)ルートはVPNに転送されます——ローカルLANのmDNS / SSDPを並行して使用する必要がある場合は`--no-broadcast-routes`で無効化
- 古いWineバージョン(< 11.0)ではオーバーラップI/Oの動作が異なり、ドライバが壊れる可能性があります
## メモ
**Wineバグの回避策。** `RegSetKeySecurity`フックは、サービスがSYSTEM SID(S-1-5-18)を受け取らない[既知のWine制限](https://forum.winehq.org/viewtopic.php?t=37183)を回避します。これは将来のWineリリースでアップストリームで修正される可能性があります。
## クレジット
リバースエンジニアリングとWineシム:[ @baptisterajaut](https://github.com/baptisterajaut)。
- [@ayozetr](https://github.com/ayozetr) — 「登録されるがreadyにならない」ハングを、ホストリゾルバによってブラックホールされたプライベートアドレスの逆DNSルックアップまで追跡し、4つの誤った理論(私のものを含む)が破棄された後にベアlibc再現で証明し、`src/rvpn_dnsfix.c`と`contrib/run-in-netns.sh`のオリジナルを作成。
- [@gringoestrangeiro](https://github.com/gringoestrangeiro) — Linux安定性の作業:パケットフィルタ、ARPキャッシュ、クラッシュリカバリ、ヘッドレスおよびデータセンターモード。
- [@yuxiaole-bili](https://github.com/yuxiaole-bili) — WineのSCMが2番目のフックされていないサービスインスタンスを自動起動し、アダプタをめぐって注入されたインスタンスと競合することを発見。
- [@D1spell-tech](https://github.com/D1spell-tech)、[@Milkiway13](https://github.com/Milkiway13)、および完全な診断ブロックを貼り付けてくれたすべての人——バグを見つけられるようにするのは2つの独立したホストです。
## ライセンス
GPL-3.0。[LICENSE](https://github.com/baptisterajaut/radmin-vpn-linux/blob/main/LICENSE)を参照してください。
精神としては、このコードはパブリックドメインです——好きなように使用してください。GPLは法的な安全網としてここにあります:相互運用性のためのリバースエンジニアリングを明示的に保護します。これはこのプロジェクトが行っていることです。二重の安全策です。
Radmin VPNはFamatech Corp.のプロプライエタリソフトウェアです。このプロジェクトは相互運用性ツールのみを提供します——Famatechのコードは含まれておらず、配布もされていません。