Tailscale 越しの macOS 画面共有(VNC)を RDP に変換する備忘録
Windows の RDP クライアントから Tailscale 経由で Mac のデスクトップを使いたい、でも Mac 側で RDP サーバーを動かすのは面倒…という場合に、Linux サーバーを中継して VNC→RDP プロトコル変換を行う手順のメモ。
vnc2rdp
という C 製のシンプルなプロキシを使い、低リソースで安定したブリッジを構築します。
構成
登場人物は 3 台。すべて同じ Tailnet に参加していることが前提です。
役割 | OS | ソフトウェア | Tailscale IP (例) | 備考 |
---|---|---|---|---|
RDP クライアント | Windows | mstsc.exe | - | 最終的に操作する PC |
Linux ブリッジ | Ubuntu/Debian | vnc2rdp , systemd | 100.106.19.34 | RDP(3389)を受け、VNC(5900)へ中継 |
Mac VNC サーバー | macOS | 画面共有 | 100.103.59.97 | VNC を Listen |
Linux ブリッジのセットアップ手順
Ubuntu 24.04 を例に、vnc2rdp のビルドからサービス化までを行います。
1. 依存パッケージのインストール
ビルドに必要なツールとライブラリを導入します。
sudo apt update
sudo apt install -y git build-essential cmake libssl-dev \
libjpeg-dev libpng-dev zlib1g-dev
2. vnc2rdp のビルドと配置
GitHub からソースを取得し、make install
で/usr/local/bin
に配置します。
git clone https://github.com/leeyiw/vnc2rdp.git ~/vnc2rdp
cd ~/vnc2rdp
# 安定版のv0.2.0をチェックアウト
git checkout v0.2.0
cmake .
make -j$(nproc)
sudo make install
3. MagicDNS から IP を動的に取得するスクリプト
vnc2rdp
は接続先 VNC サーバーを IP アドレスでしか指定できません。Tailscale の MagicDNS 名を IP に解決するヘルパースクリプトを先に用意します。
/usr/local/sbin/vnc2rdp-pre.sh
:
#!/usr/bin/env bash
# MagicDNS名を解決し、結果を一時ファイルに書き出す
# ★ここに対象MacのMagicDNS名を入れる★
DNS_NAME="mbp142021.taild89985.ts.net"
IP=$(getent hosts "$DNS_NAME" | awk '{print $1}' | head -n1)
if [ -z "$IP" ]; then
echo "[vnc2rdp-pre] failed to resolve $DNS_NAME" >&2
exit 1
fi
# systemdのEnvironmentFileとして読み込ませる
printf 'MAC_TS_IP=%s\n' "$IP" > /run/vnc-ip.env
exit 0
実行権限を付与:
sudo chmod +x /usr/local/sbin/vnc2rdp-pre.sh
4. systemd サービス化
永続的に稼働させるため、systemd のユニットファイルと、設定を上書きする Drop-in ファイルを作成します。
まず、ベースとなるユニットファイルを作成します。
/etc/systemd/system/vnc2rdp-tailscale.service
:
[Unit]
Description=vnc2rdp bridge over Tailscale (Mac)
After=network-online.target tailscaled.service
Wants=network-online.target tailscaled.service
[Service]
# ここは空でも良いが、わかりやすさのため記載
ExecStart=/usr/local/bin/vnc2rdp
[Install]
WantedBy=multi-user.target
次に、具体的な挙動を定義する Drop-in ファイルを作成します。
/etc/systemd/system/vnc2rdp-tailscale.service.d/override.conf
:
[Service]
# vnc2rdpプロセスはnobodyユーザーで実行
User=nobody
Group=nogroup
# ★ここにMacのVNCパスワードを入れる★
Environment="MAC_VNC_PASS=0426"
EnvironmentFile=-/run/vnc-ip.env
# ExecStartPreだけroot権限で実行し、/runへの書き込みを許可
PermissionsStartOnly=true
ExecStartPre=/usr/local/sbin/vnc2rdp-pre.sh
# 既存のExecStartをクリアし、動的に取得したIPで上書き
ExecStart=
ExecStart=/usr/local/bin/vnc2rdp -l 0.0.0.0:3389 ${MAC_TS_IP}:5900 -p ${MAC_VNC_PASS} -n
# サービス停止時に一時ファイルを削除
ExecStopPost=/bin/rm -f /run/vnc-ip.env
Restart=on-failure
-n
オプションは、他の VNC クライアントが接続している場合にそれを切断して排他的に接続するモードです。macOS 標準 VNC との相性問題が減るため推奨です。
5. サービスの有効化と起動
sudo systemctl daemon-reload
sudo systemctl enable --now vnc2rdp-tailscale
# 起動確認
sudo systemctl status vnc2rdp-tailscale
active (running)
となっていれば成功です。
トラブルシューティング
よくある問題とその対処法です。
症状 | 原因と対策 |
---|---|
RDP 接続後、画面が真っ黒 | VNC サーバー側の解像度が高すぎるのが原因です。 vnc2rdp が古い RDP プロトコル(4/5)にしか対応していないため、扱える解像度に上限があります。 対策: Mac の「システム設定 > ディスプレイ」で解像度を1920x1080や1680x1050程度に下げてください。Retina ディスプレイの場合は、スケーリング設定を「スペースを拡大」側に 1〜2 段階ずらすと改善します。 |
RDP エラー 0x500d | 上記の解像度問題と同じ原因です。クライアントがプロトコルエラーとして接続を切断しています。 |
サービスが failed で起動しない | journalctl -u vnc2rdp-tailscale でログを確認。・Permission denied: PermissionsStartOnly=true が設定されているか確認。・Bad format of server address: vnc2rdp-pre.sh が IP を正しく取得できているか、getent hosts <MagicDNS名> で手動テスト。・VNC authentication failed: override.conf のMAC_VNC_PASS が正しいか確認。 |
RDP 接続自体ができない | ・Tailscale の接続確認: ブリッジサーバーから Mac へtailscale ping <MagicDNS名> が通るか確認。・ポートリスニング確認: ブリッジサーバーで ss -ltn | grep 3389 を実行し、vnc2rdp が待受中か確認。 |
Mac のスリープ | Mac がスリープすると VNC サーバーも停止します。「システム設定 > 省エネルギー」でスリープを無効化するのがおすすめです。 |