mattintosh note

どこかのエンジニアモドキの備忘録

X over SSH を使わずに X アプリケーションを呼び出す

X アプリケーションをリモートから呼び出すというと X over SSH が定番です(思ってます)が、非力な Raspberry Pi にとっては暗号化もそれなりに負荷になります。

ssh -X 192.168.1.254 chromium

「そもそも家で使うなら暗号化なぞ必要無いのでは?」ということで色々試してみました。

Mac OS <- Linux

前提として Mac OS 側に X 環境(XQuartz.app など)が必要です。

XQuartz.app を起動したあとに xterm などから ~/.Xauthority に記述されている COOKIE を送る必要があります。ここでは IP アドレスが以下のようになっているとして進めます。

ホスト名 OS IP アドレス ディスプレイ
mac Mac OS 192.168.1.2 :0
rpi Linux 192.168.1.254 none

まずは、XQuartz.app の「環境設定」で認証を有効にしておきます。はじめての場合は XQuartz.app を再起動します。

https://lh3.googleusercontent.com/-BDLEa1pRCy8/VpkG31Hc0wI/AAAAAAAANN0/r7_gBM1PJpI/s800-Ic42/35fc3c18776a60c18ba52253bfb309ea.png

COOKIE の登録

次に、Mac OS 側の COOKIE を X アプリケーションを実行するマシンへ送ります。

COOKIE の送り方(登録の仕方)はいくつかありますが、簡単なのは extract コマンドで標準入力から取り込む方法です。extract - で標準出力へ出力したものを merge - で受け取ります。

mac$ xauth extract - 192.168.1.2:0 | ssh 192.168.1.254 xauth merge -

xauth list で表示したものをコピーして送信先xauth add する方法もあります。

mac$ xauth list
192.168.1.2:0 MIT-MAGIC-COOKIE-1 0123456789ABCDEFGHIJKLMNOPQRSTUV
mac$ ssh 192.168.1.254
rpi$ xauth add 192.168.1.2:0 . 0123456789ABCDEFGHIJKLMNOPQRSTUV

list コマンドで確認して登録されていれば OK です。

rpi$ ssh 192.168.1.254 xauth list
192.168.1.2:0 MIT-MAGIC-COOKIE-1 0123456789ABCDEFGHIJKLMNOPQRSTUV

COOKIE を新たに作る場合は generate コマンドや mcookie コマンドで作成ができます。ディスプレイ名の次にはプロトコル名がきますが、 . にしておくと暗黙的に MIT-MAGIC-COOKIE-1 としてくれます。

generate の場合例

xauth generate :1 .

mcookie の場合の例

xauth add :1 . `mcookie`

COOKIE を送ったらサーバにログインしてアプリケーションを呼び出します。

SSH でログインして、DISPLAY 環境変数Mac OS のディスプレイを指定してアプリケーションを実行するだけです。ここでは gnome-system-monitor を起動します。トンネリングはしないので SSH オプションの -X-Y は必要ありません。

mac$ ssh 192.168.1.254
rpi$ DISPLAY=192.168.1.2:0 gnome-system-monitor

ssh の引数にコマンドを指定しても実行できます。

mac$ ssh 192.168.1.254 DISPLAY=192.168.0.2:0 gnome-system-monitor`

XQuartz.app の場合は Quartz ウィンドウマネージャが起動しているのでアプリケーションを実行するだけでいいのですが、ウィンドウマネージャが起動していない環境の場合はウィンドウマネージャも起動しておく必要があるかもしれません。

lnx$ ssh 192.168.1.254 'export DISPLAY=192.168.1.3:1; metacity & gnome-system-monitor'

Mac OS 側で Raspberry Pi の状況をグラフィカルにチェックすることができます。この程度の描写なら 1MB/s ですが、頻繁に動くものとなると 10MB/s を超えるのである程度帯域は必要です。

https://lh3.googleusercontent.com/-Xcg84r7sxBk/Vpj-70YPJgI/AAAAAAAANN0/c4Hv7LNereU/d-Ic42/5390fff9b99739dfadb45c932ff8a37d.png

ディスプレイは複数のマシンに共有させることができます。ここでは左に Raspberry Pi 2 Model B のシステムモニタ、右に Raspberry Pi Model B+ のシステムモニタを表示しています。

https://lh3.googleusercontent.com/-vewW9oy0onU/VpnfT5sTN2I/AAAAAAAANOo/H6hQ2-4wVkE/d-Ic42/88f6f37abb49b0b8e7470b8d0b20eeeb.png

Linux <- Linux

LinuxMac <- Linux と同じようにして接続ができますが、XQuartz.app とやりとりするよりは少しわかりづらいかもしれません。

例えば、COOKIE を正しく登録しても「Invalid MIT-MAGIC-COOKIE-1 key」と表示され、うまく接続できないことがあります。

rpi$ DISPLAY=192.168.1.2:1 xterm
Invalid MIT-MAGIC-COOKIE-1 keyxterm: Xt error: Can't open display: 192.168.1.2:1

これはうちの環境の話ですが、Xnest や Xephyr で新しく起動したウィンドウに接続できなくて困っていたのですが、KDE の場合は xauth を実行した際に ~/.Xauthority ではなく /tmp/kde-USERNAME/xauth-1000-_0 というファイルを使用していることが原因でした。

XAUTHORITY 環境変数がセットされている環境で Xnest や Xephyr にアプリケーションを呼び出す場合は -auth オプションでファイルを指定する必要があるかもしれません。

Xnest :1 -auth $XAUTHORITY
Xephyr :2 -auth $XAUTHORITY

もしくは -ac(disable access control restrictions)オプションで認証を無効にする方法もあります。この方法は COOKIE を登録する必要がありません(セキュリティには注意が必要です)。

Xnest :1 -ac
Xephyr :2 -ac

他のマシンにディスプレイを使わせるためには -listen tcp もセットする必要があるかもしれません。


ここまで ssh -X とすればいいだけの問題をわざわざ xauth を使ったりしていたのは Raspberry Pi の画面出力を Xnest や Xephyr で引っ張ってくるためでした。自分の環境は Intel チップの KDE 環境なんですが、なんか Raspberry Pi と相性悪い?のか、:0 に表示するより Xnest とかに表示した方が動きがいいんですよね…。

とりあえず艦これもそこそこ動くようになったので今回の作業はここまで。

ffmpeg \
    -video_size 1280x720 -framerate 30 -f x11grab -draw_mouse 0 -i :0+1446,100 -f pulse -i 0 \
    -c:v libx264 -q:v -1 -pix_fmt yuv420p -preset ultrafast -x264opts bframes=2:cabac=1:open_gop=1 \
    -c:a aac -strict experimental -b:a 320k \
    -movflags faststart out.mp4