サーバでsudoが使えないときのwaylandアプリ転送
TL;DR
- 前提となる環境:学校のサーバなどで管理者権限がない、しかしdokcerは使える
- 目標:学校のサーバで動かしたwaylandバックエンドのGUIアプリをクライアントに転送したい
- やったこと:クライアントPCでwaypipe client、サーバでwaypipe serverコンテナを動かして実現した
やりたいこと
サーバにsshで接続してGUIアプリを動かしたくなったら、X11転送をすることが考えられますが、wayland対応のGUIアプリを転送する際にはX11転送のwayland版であるwaypipeを使用する必要があります。
接続先のサーバにおいてsudo権限がなく、waypipeをそのままインストールできなかったので、今回はwaypipeのサーバとなるコンテナを立ち上げ、それをクライアントPCからwaypipe clientとしてlistenする形にしました。設定に苦戦したので備忘録として残します。
クライアントPC: Ubunut24.04
大学のサーバ: Ubuntu22.04.5
ちなみにクライアントPCではwayland client、サーバではwayland serverとGUIアプリのターミナルを同時に開く必要がある(後半ではバックグラウンド化も行います)ので、tmuxなどを必要に応じて使用することをおすすめします。
クライアント
waypipeをインストールします。以下を実行し、waypipe clientとしてlisten状態にします[1]。
-cは圧縮の種類を設定するオプションで、今回はlz4を選択しています。
waypipe -c lz4 client新たなターミナルを開き、以下のコマンドでサーバにsshします。
ssh -R /tmp/waypipe-remote.sock:/tmp/waypipe-client.sock username@hogeRオプションは、UNIXドメインソケットを使ってポートフォワーディングを行うオプションです。これを用いると、クライアントのwaypipeがlistenしているsockファイルは、サーバの/tmp/waypipe-remote.sockとリンクされます。
サーバ
以下のDockerfile及びentrypoint.shを書き、dockerイメージとしてビルドします。
FROM ubuntu:24.04
RUN apt-get update && apt-get install -y \
waypipe \
gedit \
libwayland-client0 \
&& rm -rf /var/lib/apt/lists/*
ENV XDG_RUNTIME_DIR=/tmp/waypipe-share
COPY entrypoint.sh /entrypoint.sh
ENTRYPOINT ["/entrypoint.sh"]set -e
rm -f "$XDG_RUNTIME_DIR"/wayland-0 "$XDG_RUNTIME_DIR"/wayland-0.lock
exec waypipe -c lz4 --socket /tmp/waypipe-remote.sock \
--display wayland-0 --no-gpu \
server -- sleep infinitydocker build -t waypipe .ビルドできたら次のコマンドでコンテナを起動します。このコンテナはwaypipe serverとして、/tmp/waypipe-share/を通じて接続してきたGUIアプリの偽waylandコンポジタとなります。このwaypipe serverがwapipe clientにGUIアプリの描画内容を渡し、クライアントPCの本物のwaylandコンポジタで描画されるという仕組みです。
docker run -d --init --rm --name waypipe-server \
-v /tmp/waypipe-remote.sock:/tmp/waypipe-remote.sock \
-v /tmp/waypipe-share:/tmp/waypipe-share \
waypipeこれで準備はほぼ完了です。
XDG_RUNTIME_DIRという環境変数を/tmp/waypipe-share/に設定後、geditを起動すると、クライアントPCで起動するはずです。
トラブルシューティング
特にソケット管理が大変なので、うまく起動しないときは以下のことを確認しましょう。
/tmp/waypipe-remote.sockが無効になる
/tmp/waypipe-remote.sockはssh経由でUNIXドメインソケットを使用しており、接続が切れるとサーバにある/tmp/waypipe-remote.sockは不始末なソケットとして残り続け、また接続してきたときにConnection refusedとなるエラーが発生する場合があります。その場合はいったんこのソケットファイルを削除し、再度sshしなおしましょう。
/tmp/waypipe-remote.sockが有効なソケットかどうかはncコマンドを使って確かめます。
nc -U /tmp/waypipe-shareこのコマンドをサーバで実行してみて、Connection refusedとでたらソケットが壊れています。
[1]: WSL環境の方はこの時点でエラーがでることがある...