WSL2のUbuntuにリモートデスクトップ接続する。（その１：genieインストール）

:::note info
2023.02.03追記
WSL2のネイティブSystemdでxrdpを動作させる記事を書きました。
WSL2でSystemdが公式にサポートされるようになったため今後は以下の記事を参照してください。

- [WSL2をインストールしてネイティブなSystemdを使う。](https://qiita.com/sakai00kou/items/212f037600e202e07690)
- [WSL2のUbuntu 22.04.3 LTSにリモートデスクトップ接続する。（その２’：xrdpインストール）](https://qiita.com/sakai00kou/items/c3f2e4043765aad0651f)
:::

# はじめに
`WSL2`で`Ubuntu`を使用する場合、初期状態ではデスクトップ環境が使用できないため、`CLI`で操作することになります。

`WSL2`でそのまま`Linux GUI`を動作させるための`WSLg`というものもあるようですが、`Windows`の`Insider Preview`を利用しないとまだ使えないようで、ちょっと`GUI`を使いたい場合に使えるようにするために`xrdp`をインストールして使えるようにしたいと思います。

- 【次】[WSL2のUbuntuにリモートデスクトップ接続する。（その２：xrdpインストール）](https://qiita.com/sakai00kou/items/e2523b6c195693e8f184)

# 環境
以下環境のマシンにインストールします。

|リソース|スペック|
|:--|:--|
|CPU|AMD Ryzen 7 3700U 2.30 GHz|
|メモリ|16.0 GB|

OSバージョンなど。

|アプリケーション|バージョン|
|:--|:--|
|Windows 10 Home|21H1|
|Ubuntu|20.04|

# WSL2のプロセス起動について
通常の`Linux`では`Systemd`などのサービスが`PID 1`で起動し、各種サービスを管理しますが、`WSL2`では`PID 1`は`Windows`とやり取りするためにカスタマイズされた`initd`が動いているため、`Systemd`などのサービスが動きません。

そのため、`WSL`、`WSL2`の`Linux`では`systemctl`などのコマンドが使えないため、常用するとなると何かと不便です。

ただ、`WSL2`でも`PID 1`で`Systemd`を動作させることができるようになる`genie`というパッケージが存在するため、`genie`をインストールして通常の`Linux`と同じような使用感で使えるようにします。

# Ubuntu 20.04の入手
`Microsoft Store`から`Ubuntu 20.04`を入手してインストールします。

なお、既にインストール済みの仮想マシンを初期状態に戻したい場合は「**スタートメニュー**」を右クリック→「**アプリと機能**」→「**（ディストリビューション名）**」の「**詳細オプション**」から「**リセット**」を選択することで、インストール直後の状態に戻すことができます。

環境が汚れて元に戻したくなったら実行しましょう。

![capture_18072021_104340.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/569912/de227c51-faeb-8703-e567-f0b77f0d0bdf.jpeg)

# genieインストール準備
以下`genie`の`GitHub`ページの`Debian`項目を見ると以下のパッケージが`genie`インストール時の依存パッケージとなっております。

- [arkane-systems / genie](https://github.com/arkane-systems/genie)

|パッケージ|備考|
|:--|:--|
|daemonize|**未インストール**|
|dbus|インストール済み|
|dotnet-runtime-5.0|**未インストール**|
|gawk|インストール済み|
|libc6|インストール済み|
|libstdc++6|インストール済み|
|policykit-1|インストール済み|
|systemd|インストール済み|

但し、`daemonize`と`dotnet-runtime-5.0`以外は`WSL`の`Ubuntu 20.04`にインストール済みとなるので、不足しているパッケージのみ追加でインストールしていきます。

## daemonizeインストール
`daemonize`は`Ubuntu`の標準リポジトリからそのまま入手できるので、`apt`コマンドでインストールします。

```shell:daemonizeのインストール
sudo apt update
sudo apt upgrade
sudo apt install daemonize
```

## dotnet-runtime-5.0のインストール
`Microsoft`の公式ページに`Ubuntu`でのインストール手順が記載されているので、公式ページの手順通りにセットアップしていきます。

- [Install .NET on Linux](https://docs.microsoft.com/en-us/dotnet/core/install/linux)
- [Ubuntuインストール手順](https://docs.microsoft.com/en-us/dotnet/core/install/linux-ubuntu#2004-)

.Netランタイムが公開されているリポジトリの登録と、署名キーを入手します。

```shell:リポジトリ登録と署名キーの入手
wget https://packages.microsoft.com/config/ubuntu/20.04/packages-microsoft-prod.deb -O packages-microsoft-prod.deb
sudo dpkg -i packages-microsoft-prod.deb
rm packages-microsoft-prod.deb
```

リポジトリの情報を`update`コマンドで更新してから`.Net SDK`をインストールします。

```shell:.NetSDKのインストール
sudo apt-get update; \
  sudo apt-get install -y apt-transport-https && \
  sudo apt-get update && \
  sudo apt-get install -y dotnet-sdk-5.0
```

同じく`.Net runtime`もインストールします。

```shell:.Netランタイムのインストール
sudo apt-get update; \
  sudo apt-get install -y apt-transport-https && \
  sudo apt-get update && \
  sudo apt-get install -y aspnetcore-runtime-5.0
```

# genieのインストール
[genie](https://github.com/arkane-systems/genie#debian)の`GitHub`ページより、`genie`のインストールもリポジトリから取得することになるので、以下ページの通りリポジトリを登録します。

- [wsl-transdebian](https://arkane-systems.github.io/wsl-transdebian/)

尚、上記ページでは`root`で実行する前提で書かれていますが、`sudo`で`cat`コマンドを使用した**ヒアドキュメント**でファイル作成した場合、作られるファイルの権限は`root`ではなく実行ユーザ権限となるため、`root`権限が必要な場所には**ヒアドキュメント**でファイルを作成することができません。

そのため、いくつか書き換えた以下のコマンドを実行します。

```shell:genieリポジトリの登録
sudo wget -O /etc/apt/trusted.gpg.d/wsl-transdebian.gpg https://arkane-systems.github.io/wsl-transdebian/apt/wsl-transdebian.gpg
sudo chmod a+r /etc/apt/trusted.gpg.d/wsl-transdebian.gpg
sudo tee /etc/apt/sources.list.d/wsl-transdebian.list << EOF > /dev/null
deb https://arkane-systems.github.io/wsl-transdebian/apt/ $(lsb_release -cs) main
deb-src https://arkane-systems.github.io/wsl-transdebian/apt/ $(lsb_release -cs) main
EOF
sudo apt update
```

リポジトリの登録が完了したら後は`apt`コマンドで`genie`をインストールするだけです。

```shell:genieのインストール
sudo apt install -y systemd-genie
```

# genieインストール後のセットアップ
インストール直後の状態で`genie`を起動するとエラーがいくつか表示されたりするため、対処を行います。

いくつかの問題の対処は`genie`の`GitHub`ページにある`Wiki`に書かれているので、そちらの内容を取り込みます。

- [genieのGitHub Wiki](https://github.com/arkane-systems/genie/wiki)

## genie起動時に起動失敗するサービスの対処
`WSL2`の`Ubuntu 20.04`で`genie`を起動すると以下サービスの起動に失敗します。

- [Systemd units known to be problematic under WSL](https://github.com/arkane-systems/genie/wiki/Systemd-units-known-to-be-problematic-under-WSL)

|サービス|備考|
|:--|:--|
|auditd.service|未インストール|
|multipathd.service|**インストール済み**|
|ssh.service|**インストール済み**|
|systemd-modules-load.service|未インストール|
|systemd-remount-fs.service|**インストール済み**|

`auditd.service`と`systemd-modules-load.service`については本手順実施時にはインストールされていないため、インストール済みで対処が必要となるサービスのみ対処を行います。

上記表の`multipathd.service`はデフォルトのWSLカーネルではサポートされていないため、自動起動するためのリンクファイルを予め削除して起動しないようにしておきます。

```shell:multipathd.serviceの無効化
sudo rm /etc/systemd/system/multipath-tools.service
sudo rm /etc/systemd/system/sysinit.target.wants/multipathd.service
sudo rm /etc/systemd/system/sockets.target.wants/multipathd.socket
```

`ssh.service`は以下コマンドを予め実行しておくことでエラーが表示されなくなるため、以下実行します。

```shell:ssh-keygenコマンドの実行
sudo ssh-keygen -A
```

`systemd-remount-fs.service`は上記`Wiki`ページによると、通常の`Ubuntu`では`cloudimg-rootfs`というラベルが付いたパーティションをルートパーティションとして再マウントするようになっているが、`WSL`の場合は当てはまらないため失敗するので、ルートパーティションに`cloudimg-rootfs`をラベル付けすれば良いとのこと。

私の環境では`Wiki`ページに書かれているデバイス名ではなかったため、以下コマンドでルートパーティションのデバイス名に対してラベル付けできるようにします。

```shell:ルートパーティションへのラベル付け
sudo e2label $(df / | awk '/\//{print $1}') cloudimg-rootfs
```

ラベル付けがされたことを確認する場合は`blkid`コマンドで確認してください。

# /proc/sys/fs/binfmt_miscにアクセスできない問題の対処
`Ubuntu`で`genie`使用時、`/proc/sys/fs/binfmt_misc`にアクセスするとエラーが表示されるため、`/etc/rc.local`に該当のディレクトリを再マウントする処理を追加します。

- [Cannot access proc sys fs binfmt_misc under Ubuntu](https://github.com/arkane-systems/genie/wiki/Cannot-access--proc-sys-fs-binfmt_misc-under-Ubuntu)

`Wiki`に記載の方法では`rc.local`起動に失敗したため一部書き換えて以下実行

```shell:起動時remount実行
sudo tee /etc/rc.local << _EOF_ > /dev/null
#!/bin/bash
ls /proc/sys/fs/binfmt_misc > /dev/null 2>&1 || mount -t binfmt_misc binfmt_misc /proc/sys/fs/binfmt_misc
exit 0
_EOF_
sudo chmod +x /etc/rc.local
```

## genieの自動起動
`WSL2`の`Ubuntu`を起動したときにログインされるユーザの`.bashrc`に`genie`を自動実行するようにコマンドを仕込んでおきます。

`genie`を起動しない場合も考慮し、ログイン時に3秒猶予を持たせて、`n`の場合は`genie`を起動しないようにしています。

- [Automatically start genie on every shell session](https://github.com/arkane-systems/genie/wiki/Automatically-start-genie-on-every-shell-session)

```shell:ログイン時にgenie自動起動
cat << _EOF_ >> ~/.bashrc

# Are we in the bottle?
if [[ ! -v INSIDE_GENIE ]]; then
  read -t 3 -p "yn? * Preparing to enter genie bottle (in 3s); abort? " yn
  echo

  if [[ \$yn != "y" ]]; then
    echo "Starting genie:"
    exec /usr/bin/genie -s
  fi
fi
_EOF_
```

# genieの起動確認
以下コマンドを実行することで`genie`を起動できます。

起動時、timeoutやエラーが表示されなければ起動完了です。

```genieの起動
genie -s
```

# おわりに
今回は`xrdp`インストール前の準備として`genie`をインストールしました。

`genie`はボトルという疑似コンテナのような環境を構成することで`systemd`を`PID 1`で動かせるようにしているようなので、通常の`Ubuntu`とまったく同じとはいきませんが、ちょっと使う分には十分かと思います。

いちいち仮想マシンを別で起動しなくても`WSL`の軽量な環境で`Ubuntu`等のサーバが動かせるのはメリットなので、常用したい方は`genie`のインストールをお勧めします。