プログラミング
FamilyWildでX11サーバーをホスト間で共有する
Sharing an X11 Server Across Hosts with FamilyWild (dobrowolski.dev)
要約
コンテナやSSH経由でX11アプリケーションを実行する際、しばしば「Authorization required, but no authorization protocol specified」というエラーに遭遇します。これは、X11の認証ファイル(.Xauthority)が、クライアントが実行されていると認識するホスト名と一致しないために発生します。この記事では、X11の「FamilyWild」というワイルドカードファミリーを利用して、ホスト名の制約を取り除き、認証ファイルを任意のホストで機能させる方法を解説しています。これにより、セキュリティを維持しつつ、X11サーバーの共有が容易になります。
全文翻訳
2026-08-02
FamilyWildでX11サーバーをホスト間で共有する
コンテナ内、chroot内、またはバインドマウントされた.Xauthorityを使用してSSH経由でX11アプリケーションを実行しようとした際に、「Authorization required, but no authorization protocol specified」という、いつも親切なメッセージに遭遇したことはありませんか?ファイルはそこ(クライアントが期待する場所に読み取り専用でマウントされている)にありますが、Xは接続を拒否します。理由は微妙であり、修正はsedの1行です。
なぜクッキーが拒否されるのか
.Xauthorityファイルはクッキーのリストであり、各エントリはファミリーとホスト名でキー付けされています。クライアントが接続する際、最初に見つかったクッキーを単に取得するわけではありません。クライアントが実行されていると信じているマシンと一致するホスト名を持つエントリを探します。これは、クライアントがクッキーが発行された場所とは異なる場所で実行された瞬間に壊れることです。コンテナ内ではホスト名が異なり、転送されていないソケット経由では、クライアントはまったく異なる名前を解決します。クッキーは存在し有効ですが、ホスト名が一致しないため、クライアントはそれを決して提供せず、Xは「no authorization protocol」にフォールバックします。ファミリー/ホスト名のキー付けは自分で確認できます。
$ xauth list
myhost/unix:0 MIT-MAGIC-COOKIE-1 a1b2c3d4e5f6...
この先頭のmyhost/unix:0が問題です。これはクッキーをmyhostにピン留めします。
FamilyWildの救済
Xにはワイルドカードファミリー、FamilyWildがあり、その数値値は0xffffです。このファミリーのクッキーは、任意のホスト名に一致します。したがって、クライアントのホスト名をクッキーに一致させようとする代わりに、クッキーをすべてのホストに一致するように書き換えます。xauth nlistは、最初のフィールドが4桁の16進数ファミリーである数値形式でエントリを出力します。それをffffで上書きし、結果を新しいファイルにマージします。
: > /tmp/portable.Xauthority && xauth nlist :0 | \
sed 's/^..../ffff/' | xauth -f /tmp/portable.Xauthority nmerge -
# :0を$DISPLAY値に置き換えてください
変更は単一のフィールドです
編集がいかに小さいかを見る価値があります。.Xauthorityエントリはパックされたバイナリレコードです。2バイトのファミリー、次に長さプレフィックス付きのアドレス、ディスプレイ番号、認証名、そしてクッキー自体です。元のファイルをダンプすると、ファミリーは最初の2バイトにあります。0100、つまりFamilyLocalです。
00000000: 0100 0006 6d79 686f 7374 0001 3000 124d ....myhost..0..M
00000010: 4954 2d4d 4147 4943 2d43 4f4f 4b49 452d IT-MAGIC-COOKIE-
00000020: 3100 10a1 b2c3 d4e5 f607 1829 3a4b 5c6d 1..........):K
m
00000030: 7e8f 90 ~..
今、作成したFamilyWildバージョンをダンプします。すべてがバイト単位で同一です。同じmyhostアドレス、同じクッキー。ただし、最初の2バイトはffffに反転しています。
00000000: ffff 0006 6d79 686f 7374 0001 3000 124d ....myhost..0..M
00000010: 4954 2d4d 4147 4943 2d43 4f4f 4b49 452d IT-MAGIC-COOKIE-
00000020: 3100 10a1 b2c3 d4e5 f607 1829 3a4b 5c6d 1..........):K
m
00000030: 7e8f 90 ~..
その1つのフィールドがトリック全体です。アドレスバイトはまだmyhostをスペルしていますが、ファミリー0xffffは無条件に一致するため、Xはもはや気にしません。/tmp/portable.Xauthorityをクライアントが実行される場所にバインドマウント(またはscp)し、XAUTHORITYをそれにポイントすると、ホスト名の不一致に関係なく接続が受け入れられます。
xhost +はどうですか?
あなたはしばしばxhost +が「とにかく動くようにする」答えとして提案されているのを見るでしょう、そしてそれは機能します。それはホストベースのアクセス制御を完全にオフにすることによってです。その後、すべてのホストからのすべてのクライアントが、クッキーなしであなたのディスプレイに接続できます。単一ユーザーマシンでは無害に聞こえますが、Xにはクライアント間に分離がありません。サーバーに到達できる人は誰でもあなたのキーストロークを読み取ったり、任意のウィンドウの内容を取得したり、合成入力を注入したりできます。xhost +は、その機能をすべてのローカルユーザーに渡し、サーバーがTCPでリッスンしている場合はネットワークにも渡します。より狭いxhost +local:でさえ、ボックス上のすべてのUIDを信頼します。FamilyWildクッキーは、ドアをロックしたままにします。クライアントはまだ秘密を提供する必要があります。その一方で、邪魔になっていたホスト名の制約のみを削除します。xhost +の代わりにそれを使用し、クッキーファイルを0600に保ちます。
1つの注意点
FamilyWildクッキーは、それが置き換えるものよりも意図的に具体性が低くなっています。あなたのXソケットに到達でき、このファイルを読み取ることができる人は誰でもあなたのディスプレイと通信できます。それを実際に必要とする環境にのみ渡し、共有マシンにコピーを残さないでください。このトリックは、より大きなセットアップの1つの小さな部分です。私はそれを特権のないLXCコンテナにXを転送するために使用しており、LXCでx11アプリケーションのセキュリティを強化するで詳細に記述しました。