WSL2からアクセス制御(Xauthority)を有効にしたX Serverに接続する

>  この記事はWindows10のWSL2環境を対象として作成しました。Windows11のWSL2環境ではWayland + X11が統合されていますので、同一ホスト内でGUIアプリケーションを利用するためにXserverやWindow Managerをインストールする必要はありません。Windows11では何も考えずにGUIアプリケーションが実行できます。

# はじめに

WSL2からXserverに接続したいので、記事を検索してみると、xauthを無効にする方法だったり、挑戦したものの完全なガイドがないものが検索の上位にランクされているようでした。Windows10上で稼動するXserverとしては、VcXsrvの素性が一番良さそうだったので、これを利用しています。

学生になった頃はまだxauthオプションがデフォルトではなかったので、ずいぶん昔の話しだなぁと感じると同時に、現代に配布されているXserverがxauthを有効にせずに起動できるような状態である事に戦慄を感じたりもしています。

背景としては、シングルユーザー環境だから他人がローカルポートに接続するとかないし、firewallが標準化されてネットワーク経由で6000番台ポートにアクセスするとか無理だし、セキュリティ機構を無効化するの怖いとか感情的すぎ、という事なんだと思います。

とはいえ、設定が特別難しいわけでもなく、xauth (MIT-MAGIC-COOKIE-1) は文字列のやり取りで完結するシンプルな機構なので、使い方をまとめておくことにしました。

## 参考資料

* https://ja.stackoverflow.com/questions/66736/wsl2%E3%81%AE%E4%B8%AD%E3%81%AEx-client%E3%81%8B%E3%82%89-vcxsrv-%E3%81%AB-xauth-%E3%81%A7%E6%8E%A5%E7%B6%9A%E3%81%97%E3%81%9F%E3%81%84
* https://qiita.com/ryoi084/items/0dff11134592d0bb895c
* https://rin-ka.net/windows-x-server/
* https://x410.dev/cookbook/wsl/using-x410-with-wsl2/

# WSL2側の事前準備

初回のみ必要なパッケージを導入しておきます。

```bash:WSL2(Ubuntu)側であらかじめパッケージを導入しておく
$ sudo apt update
$ sudo apt upgrade
$ sudo apt install xauth x11-apps twm
```

この他にも、xfce4-terminalなどの動作を確認しています。適宜必要なコマンドを導入してください。
ただemacs-gtkやgimpは、VcXsrvのmulti windows環境ではまともに動作しませんでしたが、one large window環境ではtwmなどのWindow Managerとの組み合せで、少し反応が悪いような印象ですが、落ることなく動いています。

## Window Managerについて

X11ではウィンドウ制御や日本語入力機能もXserverからみれば、少し特殊なフラグの立ったクライアントアプリの一種です。ユーザーが自由に機能を切り替えられるように、各機能が独立して動作する設計になっています。非常に柔軟性に富んだ民主主義的な機能ですが、最近のコンピューティング環境からすると自由すぎてどう操作して良いか分かりにくくなっているかもしれません。

twmは操作が特殊過ぎるので、fvwmやsawfishをインストールすると直感的に使えると思います。その場合は```twm &```を実行しているところを、```fvwm &```や、```sawfish &```で置き換えてください。

# VcXsrvの起動

[VcXsrv(Sourceforge)](https://sourceforge.net/projects/vcxsrv/)が導入されている前提で進めていきます。

## WSL2側での~/.Xauthorityファイルの準備

この作業は利用の都度行なって、MIT-MAGIC-COOKIE-1 に設定する値を変更してください。

```bash:~/.Xauthorityファイルの生成
$ xauth add :0 MIT-MAGIC-COOKIE-1 $(openssl rand -hex 16)
$ xauth list 
YASUWIN7/unix:0  MIT-MAGIC-COOKIE-1  ed304b764652aaa7be43499ad4710397
```

"YASUWIN7"の部分は設定によって変化するはずです。とりあえず作成したファイルをWindows10側のホームディレクトリにコピーしておきます。

```bash:"user01"部分は適宜変更してください
$ cp ~/.Xauthority /mnt/c/Users/user01/Xauthority
```

## VcXsrvの起動

VcXsrvを起動し、適当にオプションを選択して進めていくと”Additional parameters for VcXsrv”の欄からXserverに引数を渡せるので、先ほどコピーしたXauthorityファイルを指定します。ホームディレクトリ以外のpath、ファイル名を指定するとエラーになります。

```text:"user01"は適宜変更
## Additional parameters for VcXsrv
-auth C:\Users\user01\Xauthority
```

VcXsrvでは次のようなオプションを選択しています。

1. Multiple windows OR One large window: on
2. Display number: 0
3. Start no client
4. Clipboard + Primary Selection: on
5. Native OpenGL: on


# WSL2からVcXsrvに接続するためのIPアドレスの入手とDISPLAY環境変数の設定

VcXsrvに接続するためWindows側からIPアドレスを確認する必要があります。IPアドレス自体は毎回変化するようなので、WSL2側から/etc/resolv.confに設定されているDNSサーバーのIPアドレスから探す方法も使えそうです。

```bash:/etc/resolv.confからIPアドレスを探す
$ awk '/nameserver/ {print $2}' /etc/resolv.conf
172.30.128.1
```

このIPアドレス(172.30.128.1)を元にWSL2側でxauthとDIPSLAY環境変数を設定します。

```bash:"172.30.128.1"の部分と乱数（ed304b764652aaa7be43499ad4710397）の部分は適宜変更すること
$ xauth list
YASUWIN7/unix:0  MIT-MAGIC-COOKIE-1  ed304b764652aaa7be43499ad4710397

$ xauth add 172.30.128.1:0 MIT-MAGIC-COOKIE-1  ed304b764652aaa7be43499ad4710397
$ export DISPLAY=172.30.128.1:0
$ xeyes
```

ここで最後にxeyesが表示されれば終りですが、表示されずにDISPLAYに接続できないメッセージが表示された場合には設定ミスがないかさらっと確認してから、firewallの設定を確認します。

ESETを利用している環境では、ESETが問答無用に遮断してしまいログではなく、最近ブロックされた通信リストから確認しないと遮断された事自体に気がつかない状況でした。

明示的に6000番ポート、TCP, 内向きのトラフィックを ```172.16.0.0/12``` ネットワークに対する許可ルールを追加してxeyesが表示されました。

場合によっては、利用しているfirewallの使い方について確認する必要がありそうです。

xeyesは一度Cntrl+cなどで終了させ、window managerを起動してから各種コマノドを実行します。

```bash:Window_managerと端末を起動させる例
$ twm &
$ xfce4-terminal &
```

端末が起動してしまえば、そこからコマンドを実行すればgimpやemacsなどのGUIアプリも環境変数を継承して特別な設定なしに起動できます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/78296/cc71afc9-b223-9371-f7b4-530ac1d80a73.png)

# 処理の効率化

ここまで作業してくると、いくつか面倒な作業があります。

1. Xauthorityファイルの初期化と配置
2. DISPLAY環境変数の設定と、MIT-MAGIC-COOKIE-1の設定
3. VcXsrv起動時の-auth C:\Users\...\Xauthorityファイルの設定

これらの作業が軽減できないか考えてみることにしました。

## Xauthorityファイルの初期化やDISPLAY環境変数の設定について

毎回これらの手順を実行するのは手間なので、WSL2上のbashで行なう作業はfunctionにしています。

ただし、DISPLAY番号は:0の決め打ちで、WindowsとWSL2のUserIDが一致している前提で構成しています。

```bash:WSL2側~/.bash_aliasesファイルへの設定例
function init-xauthority {
  rm ~/.Xauthority
  xauth add :0 MIT-MAGIC-COOKIE-1 "$(openssl rand -hex 16)"
  cp ~/.Xauthority /mnt/c/Users/${USER}/Xauthority
}

function setup-display {
  DN="$(awk '/nameserver/ {print $2}' /etc/resolv.conf)"
  xauth add ${DN}:0 $(xauth list | grep unix:0 | awk '{print $2,$3}')
  export DISPLAY="${DN}":0
}
```

## VcXsrv起動時のオプションの指定

起動プロセスの最後にsave configurationボタンが表示されるので、config.xlaunch などの名前で保存すると、XLaunchのメニューから選択することができるようになります。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/78296/75c362d0-e39b-9ea8-781b-d43b2db4fa76.png)

このconfig.xlaunchを選択すると直接VcXsrvが起動するので、手間の軽減が可能です。

## 最終的にWSL2からVcXsrvに接続するための手順

1. WSl2のbashからXauthorityファイルを生成する
  * ```$ init-xauthority```
2. DISPLAY環境変数を設定する
  * ```$ setup-display```
3. WindowsOS上で、VcXsrvに-auth .../Xauthorityを指定して起動する
  * VcXsrvのアイコンで右クリックし、config.xlaunchを起動する
4. WSL2上のbashに戻り、WindowManagerと端末を起動する
  * ```$ twm &```
  * ```$ xfce4-terminal```

この後は、xfce4-terminalからemacsなどのコマンドを実行する。

xfce4-terminalはWSL2環境で動いているので、WSL2のターミナルと同様にaptコマンドなどを利用してコマンドが導入など全ての操作ができます。

# その他

## 日本語入力について

これはWinodws11でも同様ですが、WSL2の標準環境では日本語を入力するためのパッケージは導入されていないので、emacs上にddskkを導入したり、uim等のInput Method(IM)パッケージを導入する必要があります。

下記にIMとしてuim、変換エンジンとしてはuim-skkを導入・設定する例を掲載します。
fcitx、fcitx-anthyなど他のパッケージを選択したい場合には、適宜変更してください。

```bash:UIMを導入し、必要な変数を~/.bash_aliasesに追加する例
$ sudo apt update
$ sudo apt install uim uim-skk
$ echo "export XMODIFIERS=@im=uim" | tee -a ~/.bash_aliases
$ echo "export GTK_IM_MODULE=uim" | tee -a  ~/.bash_aliases
$ echo "export QT_IM_MODULE=uim" | tee -a  ~/.bash_aliases
$ im-config
$ . ~/.bash_aliases
```

最後のim-configを実行するとInput Method Configurationのダイアログが表示されるので、``uim``を選択してOKを押して終わります。

環境変数を反映するため端末を再度起動するか、例のように~/.bash_aliasesを再度読み込み、環境変数が反映された端末(SHELL)からfirefoxなどのGUIアプリケーションを起動すると日本語入力が可能となります。

なお環境変数の保存場所として、~/.bash_aliases ファイルを流用しています。~/.bashrcや~/.profileファイルなどはシステムが/etc/skel/からコピーされるものですが、編集してしまうと不具合が発生した際に簡単に/etc/skel/から再度コピーするという手段が使えなくなるので、独立している~/.bash_aliasesを指定しています。

emacsではuimから日本語を入力することも可能ですが、異常終了などの不具合に遭遇する可能性もあるので、``env XMODIFIERS=@im=none emacs``などの方法でemacs-lispで記述されているddskkのようなemacs用の日本語入力機能を利用するのがお勧めです。

## X410試用版の感想

メニューをみる限りは、アクセス制御機能にアクセスする方法はなさそうで、公式CookbookのUsing X410 with WSL2をみると最初に”Enable 'Allow Public Access' option in X410”とあるのでWSL2やネットワークの外にあるコンピュータからGUIを手元に表示する目的ではちょっと使えないかなというのが感想です。

アクセス制御を無効にしてしまえば、日本語の取り扱いや表示品質については問題ないというか良いんじゃないかとは感じました。

公式サイトの検索エンジンで、xauthやXauthorityをキーにして何ひとつドキュメントがマッチしないというのがXserverを取り扱う企業の姿勢としてはどうなのかなとはちょっと思いました。

以上