ルート権限なしで Xvfb を実行するにはどうすればいいですか?

ルート権限なしで Xvfb を実行するにはどうすればいいですか?

ルート権限のないサーバーで望ましい結果:

1)Xvfb入力デバイスなしで実行する、または

2) とにかくXvfb走ろう

背景:

私には CentOS のほぼ同一のビルドを搭載した 2 台のマシンがあります。1 台はルート アクセスとインターネットがあり、もう 1 台はサンドボックス化 (ルート アクセスなし) されており、パッケージ マネージャー (yum なし) と Xserver はありません。私はXvfb(X仮想フレームバッファ)をターゲットマシンで実行して実験するヘッドレスFirefoxが動作しているときはXvfb、 を使用できますxvfb-run

私が試したこと:

Xvfbバイナリとユーザー共有ライブラリを次のように転送しました。この方法(回答の下のコメントを参照してください)。私はXvfbこのように実行できます

Xvfb :1 -nolisten tcp -screen 0 1680x1050x16

しかし、キーマップエラーが発生します(余談:また、設定した一時ディレクトリの問題にも対処したいと思いますexport TMPDIR=~/tmp:

_XSERVTransmkdir: Owner of /tmp/.X11-unix should be set to root
XKB: Failed to compile keymap
Keyboard initialization failed. This could be a missing or incorrect setup of xkeyboard-config.
(EE)
Fatal server error:
(EE) Failed to activate core devices.(EE)

物理的なキーボードやマウスのサポートはまったく必要ありません誰かが入力デバイスなしで実行する方法を説明してくれたらXvfb、ここで止めてもいいでしょう。何時間も検索しましたが、見つかりません。


xkb を動作させるために試した方法:

xkbcomp次に、共有ライブラリとともにソース マシンから移行しました。次に、次のようにソース マシンからキーマップ ファイルをエクスポートしました。

xkbcomp -xkb $DISPLAY xkbmap

を渡して次のコードを実行しようとしましたが、成功しませんでしxkbdirxkbmap

Xvfb :1 -xkbdir ~/X11/xkb -xkbmap xkbmap -nolisten tcp -screen 0 1680x1050x16

-xkbdir有効なパラメータですが-xkbmapマニュアルページXvfb は次のように述べています:

Xserver(1)マニュアルページで説明されている通常のサーバーオプションに加えて、Xvfbは次のコマンドラインスイッチを受け入れます。

そしてそのマニュアルページXserver の場合:

−xkbdir directory
    base directory for keyboard layout files. This option is not available for setuid X servers (i.e., when the X server’s real and effective uids are different).
    ...
−xkbmap filename
    loads keyboard description in filename on server startup.

-xkbdirを渡すだけで

$ export PATH=~/bin:$PATH; # all copied binaries are here, including xkbcomp
$ Xvfb :1 -xkbdir ~/X11/xkb -nolisten tcp -screen 0 1680x1050x16

それから私は

_XSERVTransmkdir: Owner of /tmp/.X11-unix should be set to root
    sh: /usr/bin/xkbcomp: No such file or directory <-- WHY THIS PATH?
    sh: /usr/bin/xkbcomp: No such file or directory
    XKB: Failed to compile keymap
    Keyboard initialization failed. This could be a missing or incorrect setup of xkeyboard-config.
    (EE)
    Fatal server error:
    (EE) Failed to activate core devices.(EE)

ここで私は何時間も行き詰まっています。ルート権限のないマシンでも

Xvfb1)入力デバイスなしで実行するにはどうすればよいですか?

2) どうすればXvfb走れるようになるのでしょうか?

答え1

部分的な回答: なしで Xvfb を実行する方法xkeycomp

あなたの説明によると、主な問題は非ルートとして実行することではなく(私のシステムでは問題なく動作します)、非ルートでは などの補助プログラムやその関連データ ファイルを、それらが期待される場所にXvfbインストールできないということのようです。xkeycompXvfb

サンドボックス化された CentOS 環境に何がインストールされていて何がインストールされていないかを正確に把握せずにシミュレートするのは困難です。ただし、依存関係を取り除く方法は次のとおりですxkeycomp

stringsでの使用がXvfb示すように、 の呼び出しはxkeycompのようになり"%s%sxkbcomp" -w %d %s -xkm "%s" -em1 %s -emp %s -eml %s "%s%s.xkm"、対応するソースファイルはxkbInit.cそしてddxLoad.cざっと見たところ、 へのパスはxkbcomp固定されているように見えます。しかし、文字列はスクリプトの呼び出しに置き換えるのに十分な長さで、Xvfb次の記述をコンパイルしようとしていることがわかります。

xkb_keymap "default" {
    xkb_keycodes             { include "evdev+aliases(qwerty)" };
    xkb_types                { include "complete" };
    xkb_compatibility        { include "complete" };
    xkb_symbols              { include "pc+us+inet(evdev)" };
    xkb_geometry             { include "pc(pc105)" };
};

から提供された をstdinファイル にコピーします/tmp/server-1.xkm。したがって、Xとツールを備えたマシンでは、この記述を などのファイルにコピーしdefault.xkb、コンパイルします。

xkbcomp -xkm default.xkb 

に。次に、呼び出しを検索して、CentOS サンドボックス上のdefault.xkmのコピーにパッチを適用します。Xvfb

$ grep -FobUa '"%s%sxkbcomp' Xvfb
1648800:"%s%sxkbcomp

次のように呼び出してパッチを適用しますcp:

echo -n '/bin/cp /home/dirk/tmp/xvfb/default.xkm /tmp/server-1.xkm          ' | dd bs=1 of=Xvfb seek=1648800 conv=notrunc

(もちろん、あなたの位置と へのパスも考慮しますdefault.xkm)。

これは私のマシンでは問題なく動作しますが、サンドボックス化された CentOS マシンでは次の問題が発生する可能性があります。:-)

また、X API はキーボード マッピングを検査する機能を実際の入力デバイスから分離するため、入力デバイスがない場合でもキーボード マッピングが存在する必要があります。

答え2

ルート権限なしで Xvfb を実行することに成功しました。

結局、私はソースコードをダウンロードしましたhttps://www.x.org/wiki/Releases/Download/環境変数を挿入し、依存関係 (yum) をインストールし、Xvfbそのバイナリと共有ライブラリをコンパイルしてサンドボックスに転送しました。

重要なのは、[sources]/xkb/xkbInit.c815 行目あたりに次の行を追加したことです。

        if (++i >= argc)
            UseMsg();
        else
            XkbDfltRepeatInterval = (long) atoi(argv[i]);
        return 2;
    }
    /* End original code */


    // Change xkbcomp bin directory with an environment variable
    char *xkbBinDir = getenv("XKB_BINDIR");
    if (xkbBinDir) {
        XkbBinDirectory = Xstrdup(xkbBinDir);
    }

    // Change base xkb directory with an environment variable
    char *xkbBaseDir = getenv("XKBDIR");
    if (xkbBaseDir) {
        XkbBaseDirectory = Xstrdup(xkbBaseDir);
    }


    /* Original code */
    return 0;
}

環境変数をXKB_BINDIRバイナリxkbcompパス (サンドボックスにコピー) とファイルがあるXKBDIR場所に設定できますdefault.xkm

もう一度言いますが、私の成功した戦略は、ソースから変更を加えてコンパイルすることでしたXvfb。詳細な手順とステップバイステップの手順については、私のサイトに書きました。https://ericdraken.com/running-xvfb-on-a-shared-host-without-x/


@dirkt は、Xvfb バイナリをハックして文字列操作を行うという興味深いアプローチをとっています。これは、手早くてちょっといたずらっぽいので魅力的ですが、欠点もあります。1) サーバー番号が何であるかを事前に知ることができない [1 .. 99]、2) パスが長すぎるため、シンボリックリンクが必要になる。私は実際に、文字列の置換として NOP コマンド (:) と、 の手動コピーを試しましたserver-N.xkmが、ソース コード内で対処するロジック パス。その 1 つは、xkm ファイルがキャッシュされるときです。

答え3

同様のアプローチとして、サンドボックス化されたシステムで xserver-xorg-video-dummy が利用できる場合は、Xdummy を使用します。これは、いくつかのダミー ドライバーを使用し、ルート権限なしで実行できる X サーバーを提供します。xpra Web サイトに、いくつかの説明とサンプルの xorg.conf があります。https://xpra.org/trac/wiki/XdummyX をインストールする必要がありますが、X サーバーを実行する必要はありません。

(申し訳ありませんが、これをコメントとして投稿するには評判が足りません)

関連情報