自宅サーバー構築譚：Ubuntu 22.04 LTS on ZFS in Hyper-V（第2世代）

# 能書き

[自宅サーバー構築譚：基本構想](https://qiita.com/katz_engineer/items/cb592be44daa28a51d9b)に基づく自宅サーバー構築、[Ubuntu22.04LTSインストールその2](https://qiita.com/katz_engineer/items/033471b69143bf76650e)の続きです。

そろそろ Ubuntu クライアントが欲しくなってきたのですが、とりあえず Windows マシンの Hyper-V に構築する事にしました。私の普段使いの実機が Windows マシンなものでして。

Ubuntu で Hyper-V というと WSL2 がありまして、これは非常に出来が良く、それを流用というのも考えたのですが。Ubuntu デスクトップを実機にインストールする前の手順確認を兼ねて、Hyper-V にインストールする事を決めたのでした。

そして Ubuntu の Hyper-V へのインストールは[以前](https://qiita.com/katz_engineer/items/b6ccc3a4f1e03cf8415a)も試みています。今回はサーバーではなくてデスクトップを入れてみます。また、第1世代(BIOS)ではなくて第2世代(UEFI)での構築を試してみます。

## 参考文献

- [自宅サーバー構築譚：Ubuntu on ZFS in Hyper-V （第1世代）](https://qiita.com/katz_engineer/items/b6ccc3a4f1e03cf8415a)
- [Ubuntu 22.04 Root on ZFS - OpenZFS Documentation - OpenZFS](https://openzfs.github.io/openzfs-docs/Getting%20Started/Ubuntu/Ubuntu%2022.04%20Root%20on%20ZFS.html)

# 環境

## ホストマシン

Windows10Pro です。[以前の記事](https://qiita.com/katz_engineer/items/a4693679c2dce84cd211#%E7%92%B0%E5%A2%83)を参照。これで使えるHyper-Vにインストールを試みます。

## ゲストマシン

- Hyper-V。上述の通り。
- 第2世代（UEFI起動）
- メモリ: 1024MB、動的メモリを有効にする
- 仮想プロセッサの数: 1
- ハードドライブ: 16GB を1台。実機と違い、ブートローダは仮想 HDD にパーティションを区切って入れる事にしました。
- チェックポイント: どーでもいいんですが、自動チェックポイントは使用しない方向で。

大事なポイント。セキュアブートは無効にしておきます。

参考文献：[Hyper-Vで仮想マシンが起動しない時の対処法](https://qiita.com/nkojima/items/01f423a17eb250624aa3)

# インストール環境の整備

暗号化はしない方針です。家庭用なので。

## デスクトップインストーラーを起動しsshの環境整備

デスクトップ版のisoを使用します。Ubuntuのサイトからダウンロードします。これはホストマシンに置いておき、ゲストマシンから参照するようにして起動。

GUI インストーラーが立ち上がって Welcome という画面が表示されたら、 TAB キーを押して Try Ubuntu ボタンにフォーカスを移動して（ボタンにオレンジの枠がつきます） Enter キーを押します。

ウィンドウ環境に切り替わったらターミナルを起動しますが、マウス操作またはショートカットキー Ctrl+Alt+T でどうぞ。

主な作業はsshで接続して行いたいので、そのように準備します。sshで接続するのはコマンドをコピペできるから。

ターミナルで下記のコマンドを実行。

```console
sudo apt update
```

OpenSSHサーバーと、フルのvimをインストール。

```console
sudo apt install --yes openssh-server vim
```

ssh接続用にユーザー ubuntu のパスワードを設定。

```console
passwd
```

ssh接続先のIPアドレスを確認します。

```console
ip a
```
## 別のマシンから対象のサーバーに ssh してインストール作業を続行

ssh はほとんどのOSで利用可能でしょう。Windows10でもコマンドプロンプトからsshコマンドを実行できます。

```console
ssh ubuntu@接続先のIPアドレス
```

インストール作業を同じマシンでやり直してたりすると、ここでエラーが出る事があります。そんな時には ```.ssh\known_hosts``` を削除してから、sshコマンドを実行します。

```console
del %USERPROFILE%\.ssh\known_hosts
```

rootユーザーになります。

```console
sudo -i
```

debootstrapとZFSを Live CD 環境にインストールします。

```console
apt install --yes debootstrap gdisk zfsutils-linux
```

```console
systemctl stop zed
```

# ディスクのフォーマット

フォーマット対象ディスクを確認します。

```console
lsblk
```

今回は下記のように表示されます。

```console
root@ubuntu:~# lsblk
NAME  MAJ:MIN RM   SIZE RO TYPE MOUNTPOINTS
loop0   7:0    0   2.1G  1 loop /rofs
loop1   7:1    0    62M  1 loop /snap/core20/1587
loop2   7:2    0     4K  1 loop /snap/bare/5
loop3   7:3    0 163.3M  1 loop /snap/firefox/1635
loop4   7:4    0 400.8M  1 loop /snap/gnome-3-38-2004/112
loop5   7:5    0  91.7M  1 loop /snap/gtk-common-themes/1535
loop6   7:6    0   284K  1 loop /snap/snapd-desktop-integration/14
loop7   7:7    0  45.9M  1 loop /snap/snap-store/582
loop8   7:8    0    47M  1 loop /snap/snapd/16292
sda     8:0    0    16G  0 disk
sr0    11:0    1   3.6G  0 rom  /cdrom
```

```loop0```～```loop8```はインストーラによる設定でしょうか。
```sda```が内蔵HDDです。
```sr0```はCR-ROMドライブと思われます。インストーラが入っています。

ディスクの指定にはIDを使います。

```console
ls -l /dev/disk/by-id
```

これを変数に設定するのがubuntu流らしいですが、ここは私の流儀で取得する事にします。

```console
DISK=$(cd /dev/disk/by-id; ls wwn-* | while read d; do if [ "$(readlink -f $d)" = "/dev/sda" ]; then echo "/dev/disk/by-id/$d"; fi; done)
```

スワップパーティションが使用されていない事を確認します。

```console
swapoff --all
```

仮想 HDD のパーティションを全削除します。

```console
wipefs -a $DISK
```

パーティションテーブルをクリアします。

```console
sgdisk --zap-all $DISK
```

ブートローダー パーティションを作成します。

```console
sgdisk -n1:1M:+512M -t1:EF00 $DISK
```

スワップについて。
[参考文献](https://openzfs.github.io/openzfs-docs/Getting%20Started/Ubuntu/Ubuntu%2022.04%20Root%20on%20ZFS.html#step-2-disk-formatting)によると、zvolにスワップを置くとデッドロックの危険性があるので非推奨だそうです。バグレポートが上がっているらしい。
しかし Linux ではスワップを有効にした方が、メモリ管理の都合上、良いらしいです。今回はメモリが不足しているという意味もあります。

```console
sgdisk -n2:0:+4G -t2:8200 $DISK
```

ブートプールパーティションを作成します。

```console
sgdisk -n3:0:+2G -t3:BE00 $DISK
```

ルートプールパーティションを作成します。

```console
sgdisk -n4:0:0 -t4:BF00 $DISK
```

設定を確認するコマンドは下記になります。

```console
sgdisk -p $DISK
```

いよいよzfsフォーマットします。ここが今回最大のコピペポイント！これをコピペする為にssh経由で接続していると言っても過言ではありません。

因みにこのzpool名は```bpool```固定らしい。変更したい場合は```update-grub```後に```/etc/grub.d/10_linux_zfs```を修正すればいいらしいのですが、試していません。

※なおインストール2回目以降でエラーが出る際には、コマンドの末尾かどこかに ```-f``` オプションを付加します。

```console
zpool create \
    -o ashift=12 \
    -o autotrim=on \
    -o cachefile=/etc/zfs/zpool.cache \
    -o compatibility=grub2 \
    -o feature@livelist=enabled \
    -o feature@zpool_checkpoint=enabled \
    -O devices=off \
    -O acltype=posixacl -O xattr=sa \
    -O compression=lz4 \
    -O normalization=formD \
    -O relatime=on \
    -O canmount=off -O mountpoint=/boot -R /mnt \
    bpool ${DISK}-part3
```

エラー「not in specified 'compatibility' feature set.」（指定された「互換性」機能セットにない）は無視します。

そしてルートプールを作成します。
こちらのzpool名は何でも良いそうです。zfsの伝統に則って```tank```にしてみました。

```console
zpool create \
    -o ashift=12 \
    -o autotrim=on \
    -O acltype=posixacl \
    -O xattr=sa -O dnodesize=auto \
    -O compression=lz4 \
    -O normalization=formD \
    -O relatime=on \
    -O canmount=off -O mountpoint=/ -R /mnt \
    tank ${DISK}-part4
```

作成したプール一覧の確認は下記。このコマンドはコピペではなくて ```zpool list``` ```zpool status```と手打ちでお願いします。別に良いよねこの位は。

```console
root@ubuntu:~# zpool list
NAME    SIZE  ALLOC   FREE  CKPOINT  EXPANDSZ   FRAG    CAP  DEDUP    HEALTH  ALTROOT
bpool  1.88G   552K  1.87G        -         -     0%     0%  1.00x    ONLINE  /mnt
tank      9G   504K  9.00G        -         -     0%     0%  1.00x    ONLINE  /mnt
root@ubuntu:~# zpool status
  pool: bpool
 state: ONLINE
status: One or more features are enabled on the pool despite not being
        requested by the 'compatibility' property.
action: Consider setting 'compatibility' to an appropriate value, or
        adding needed features to the relevant file in
        /etc/zfs/compatibility.d or /usr/share/zfs/compatibility.d.
config:

        NAME                                            STATE     READ WRITE CKSUM
        bpool                                           ONLINE       0     0     0
          wwn-0x600224809452ff2c57172f8cc7e51667-part3  ONLINE       0     0     0

errors: No known data errors

  pool: tank
 state: ONLINE
config:

        NAME                                            STATE     READ WRITE CKSUM
        tank                                            ONLINE       0     0     0
          wwn-0x600224809452ff2c57172f8cc7e51667-part4  ONLINE       0     0     0

errors: No known data errors
```

# システムのインストール

## ディレクトリ構造に合わせたデータセット作成

Linuxのディレクトリ構造については、[大昔にちょっと調べただけ](https://qiita.com/katz_engineer/items/3c4bafd3aeb32aa2eaf0)で実はあんまり良く分かっていません。その為なるべく[参考文献](https://openzfs.github.io/openzfs-docs/Getting%20Started/Ubuntu/Ubuntu%2022.04%20Root%20on%20ZFS.html)通りにしています。

コンテナとして機能するファイルシステムデータセットを作成します。

```console
zfs create -o canmount=off -o mountpoint=none tank/ROOT
zfs create -o canmount=off -o mountpoint=none bpool/BOOT
```

ルートおよびブート ファイル システムのファイル システム データセットを作成します。

[参考文献](https://openzfs.github.io/openzfs-docs/Getting%20Started/Ubuntu/Ubuntu%2022.04%20Root%20on%20ZFS.html)はUUID（っぽいランダムな6文字）を付加したデータセット名にしていますが、これをやると後々とっても扱いづらくなります。ubuntu以外はインストールしないし、複数インストールもしない予定なので、UUIDは無しの方向にしました。

```console
zfs create -o mountpoint=/ \
    -o com.ubuntu.zsys:bootfs=yes \
    -o com.ubuntu.zsys:last-used=$(date +%s) tank/ROOT/ubuntu

zfs create -o mountpoint=/boot bpool/BOOT/ubuntu
```

データセットを作成します。

```console
zfs create -o com.ubuntu.zsys:bootfs=no -o canmount=off tank/ROOT/ubuntu/usr
zfs create -o com.ubuntu.zsys:bootfs=no -o canmount=off tank/ROOT/ubuntu/var
zfs create tank/ROOT/ubuntu/var/lib
zfs create tank/ROOT/ubuntu/var/log
zfs create tank/ROOT/ubuntu/var/spool

zfs create -o canmount=off -o mountpoint=/ tank/USERDATA
zfs create -o com.ubuntu.zsys:bootfs-datasets=tank/ROOT/ubuntu \
    -o canmount=on -o mountpoint=/root tank/USERDATA/root
chmod 700 /mnt/root
```

[参考文献](https://openzfs.github.io/openzfs-docs/Getting%20Started/Ubuntu/Ubuntu%2022.04%20Root%20on%20ZFS.html#step-3-system-installation)から、今回必要なデータセットのオプションを選んで設定します。

```console
zfs create tank/ROOT/ubuntu/var/lib/apt
zfs create tank/ROOT/ubuntu/var/lib/dpkg
zfs create -o com.ubuntu.zsys:bootfs=no tank/ROOT/ubuntu/srv
zfs create tank/ROOT/ubuntu/var/lib/AccountsService
zfs create tank/ROOT/ubuntu/var/lib/NetworkManager
zfs create tank/ROOT/ubuntu/var/lib/docker
zfs create tank/ROOT/ubuntu/var/www
```

```/run```に tmpfs をマウントします。

```console
mkdir /mnt/run
mount -t tmpfs tmpfs /mnt/run
mkdir /mnt/run/lock
```

なお```/home```はユーザー追加時に作成します。

## debootstrap

Ubuntu 22.04 LTS 通称 jammy をインストール。

```console
debootstrap jammy /mnt
```

終わったら以下のコマンドを実行します。

```console
mkdir /mnt/etc/zfs
cp /etc/zfs/zpool.cache /mnt/etc/zfs/
```

# システム構成

## マシン名

まずはホスト名を決めます。

```console
hostname ホスト名
```

```console
hostname >/mnt/etc/hostname
```

## ネットワーク関連

hostsファイルを修正。

```console
sed -i -e"/^127.0.0.1/a 127.0.1.1\t$(hostname)" /mnt/etc/hosts
```

netplan のネットワーク設定ファイル```/mnt/etc/netplan/01-netcfg.yaml```を作成します。まずはネットワークインターフェイス名を確認。どうやら```eth0```のようですな。

```console
root@ubuntu:~# ip addr show
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
    inet 127.0.0.1/8 scope host lo
       valid_lft forever preferred_lft forever
    inet6 ::1/128 scope host
       valid_lft forever preferred_lft forever
2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc mq state UP group default qlen 1000
    link/ether 00:15:5d:38:01:02 brd ff:ff:ff:ff:ff:ff
    inet 172.16.2.19/16 brd 172.16.255.255 scope global dynamic noprefixroute eth0
       valid_lft 84107sec preferred_lft 84107sec
    inet6 fe80::be5e:7b3d:412:aedc/64 scope link noprefixroute
       valid_lft forever preferred_lft forever
```

[以前の記事](https://qiita.com/katz_engineer/items/04396d58add14cb63573#%E3%83%87%E3%82%B9%E3%82%AF%E3%83%88%E3%83%83%E3%83%97%E3%83%91%E3%82%BD%E3%82%B3%E3%83%B3)の通りにIPアドレスを割り振ります。今回はDHCPにします。

参考文献：[固定IPアドレスの割当(IPv4、IPv6) - Netplanの使い方 - komeの備忘録](https://www.komee.org/entry/2018/06/12/181400#%E5%9B%BA%E5%AE%9AIP%E3%82%A2%E3%83%89%E3%83%AC%E3%82%B9%E3%81%AE%E5%89%B2%E5%BD%93IPv4IPv6)

```console
cat > /mnt/etc/netplan/01-netcfg.yaml <<___
network:
  version: 2
  ethernets:
    eth0:
      dhcp4: true
___
```

## パッケージソース

```console
cat >/mnt/etc/apt/sources.list <<___
deb http://archive.ubuntu.com/ubuntu jammy main restricted universe multiverse
deb http://archive.ubuntu.com/ubuntu jammy-updates main restricted universe multiverse
deb http://archive.ubuntu.com/ubuntu jammy-backports main restricted universe multiverse
deb http://security.ubuntu.com/ubuntu jammy-security main restricted universe multiverse
___
```

## chroot

Live CD 環境の仮想ファイルシステムをバインドマウントして、上記でセットアップした環境に chroot します（ --bind ではなく --rbind を使っていることに注意）。

```console
mount --make-private --rbind /dev  /mnt/dev
mount --make-private --rbind /proc /mnt/proc
mount --make-private --rbind /sys  /mnt/sys
```

```console
chroot /mnt /usr/bin/env DISK=$DISK bash --login
```

chroot 環境内の apt のインデクスを更新します。

```console
apt update
```

## ロケール

en_US.UTF-8 と ja_JP.UTF-8 と、後は個人的な好みで。私は ja_JP.EUC-JP を入れます。

```console
locale-gen --purge en_US.UTF-8 ja_JP.UTF-8 ja_JP.EUC-JP
```

## エディタ

個人的な好みで vi です。

```console
apt install --yes vim
```

## タイムゾーン

[参考文献](https://openzfs.github.io/openzfs-docs/Getting%20Started/Ubuntu/Ubuntu%2022.04%20Root%20on%20ZFS.html)には書かれていませんが、タイムゾーンを設定します。
日本なら Asia/Tokyo です。

```console
ln -sf /usr/share/zoneinfo/Asia/Tokyo /etc/localtime
```

```console
dpkg-reconfigure -f noninteractive tzdata
```

## EFI ファイルシステム

EFI ファイルシステムを作成します。

```console
apt install --yes dosfstools
```

```console
mkdosfs -F 32 -s 1 -n EFI ${DISK}-part1
mkdir /boot/efi
echo /dev/disk/by-uuid/$(blkid -s UUID -o value ${DISK}-part1) /boot/efi vfat defaults 0 0 >> /etc/fstab
mount /boot/efi
```

```/boot/grub```を設定します。

```console
mkdir /boot/efi/grub /boot/grub
echo /boot/efi/grub /boot/grub none defaults,bind 0 0 >> /etc/fstab
mount /boot/grub
```

## カーネルイメージなど

Linux のカーネルイメージと ZFS を chroot 環境にインストールします。

```console
apt install --yes grub-efi-amd64 grub-efi-amd64-signed linux-image-generic shim-signed zfs-initramfs zsys
```

Windowsなど他のOSを入れる予定は無いので、os-proberを削除します。

```console
apt purge --yes os-prober
```

ここで下記のエラーが出ますが、これは無視して良さそうです。多分。

```console
ERROR couldn't connect to zsys daemon: connection error: desc = "transport: Error while dialing dial unix /run/zsysd.sock: connect: no such file or directory"
```

## rootパスワード

パスワードを設定します。

```console
passwd
```

## スワップを構成

下記コマンドを実行します。

```console
mkswap -f ${DISK}-part2
echo /dev/disk/by-uuid/$(blkid -s UUID -o value ${DISK}-part2) none swap discard 0 0 >> /etc/fstab
swapon -a
```

## tmpfs

次回起動時に tmpfs を /tmp にマウントするようにします。

```console
cp /usr/share/systemd/tmp.mount /etc/systemd/system/
systemctl enable tmp.mount
```

## システムグループ

無くてもいいかなと思ったけれど、一応Ubuntuなので、念の為に作成しておきます。

```console
addgroup --system lpadmin
addgroup --system lxd
addgroup --system sambashare
```

## SSH

SSH をインストールします。

```console
apt install --yes openssh-server
```

ここでも下記のエラーが出ますな。無視。

```console
ERROR couldn't connect to zsys daemon: connection error: desc = "transport: Error while dialing dial unix /run/zsysd.sock: connect: no such file or directory"
```

rootログインできるように設定。

```console
sed -i -e"/^#PermitRootLogin /a PermitRootLogin yes" /etc/ssh/sshd_config
```


# GRUB のインストール

## ZFSの認識

ZFS のブートファイルシステムが認識されていることを確認します。```zfs``` と出力されれば OK です。

```console
grub-probe /boot
```

## initrd更新

initrdファイルを更新します。

```console
update-initramfs -c -k all
```

## 設定ファイル

メモリのゼロ化を無効にします。

```console
sed -i -e'/^GRUB_CMDLINE_LINUX_DEFAULT=/s/"$/ init_on_alloc=0"/' /etc/default/grub
```

ブート構成を更新します。
```console
update-grub
```

## ブートローダーをインストール

UEFI 用に GRUB をインストールします。

```console
grub-install --target=x86_64-efi --efi-directory=/boot/efi --bootloader-id=ubuntu --recheck --no-floppy
```

ZFS のモジュールがインストールされていることを確認します。

```console
ls /boot/grub/*/zfs.mod
```

```grub-initrd-fallback.service```を無効にします。

```console
systemctl mask grub-initrd-fallback.service
```

## ファイルシステムのマウント順序を修正

```zfs-mount-generator```を有効にする必要があります。これによりsystemdは個別のマウントポイントを認識します。これは```/var/log```や```/var/tmp```などにとって重要です。また、```rsyslog.service```は```local-fs.target```を介して```var-log.mount```に依存し、systemdの```PrivateTmp```機能を使用するサービスは自動的に```After=var-tmp.mount```を使うようになります。
……との事。

```console
mkdir /etc/zfs/zfs-list.cache
touch /etc/zfs/zfs-list.cache/bpool
touch /etc/zfs/zfs-list.cache/tank
zed -F &
```

これらが空でない事をチェックして、キャッシュが更新された事を確認します。
空だった場合の対応は[参考文献](https://openzfs.github.io/openzfs-docs/Getting%20Started/Ubuntu/Ubuntu%2022.04%20Root%20on%20ZFS.html)を参照。

```console
cat /etc/zfs/zfs-list.cache/bpool
```

```console
cat /etc/zfs/zfs-list.cache/tank
```

キャッシュにデータが含まれたら```zed```を停止します。

```console
fg
(Ctrl-C)
```

パス```/mnt```を除去するように修正します。

```console
sed -Ei "s|/mnt/?|/|" /etc/zfs/zfs-list.cache/*
```

## chroot終了

chroot環境を終了して LiveCD 環境に戻ります。

```console
exit
```

## 初回のブート

LiveCD 環境で次のコマンドを実行して、すべてのファイルシステムをアンマウントします。

```console
mount | grep -v zfs | tac | awk '/\/mnt/ {print $3}' | xargs -n 1 -r umount -lf
```

```console
zpool export -a
```

なぜかエラーが出ます。原因不明。仕方が無いので放置します。

```console
root@ubuntu:~# zpool export -a
cannot export 'tank': pool is busy
```

そのままシャットダウン。

```console
shutdown -h now
```

その後、インストールメディアを取り出して、それからマシンの電源を入れます。

## grub

案の定、grubでエラーが出ます。
ここで慌てず騒がず、grubのプロンプトで普通にzpoolをimportします。

```console
zpool import -f tank
exit
```

今度はちゃんと起動します。

## rootログイン

root ユーザーでパスワードを入力してログインします。それから```ip a```コマンドで IP アドレスを確認。

```console
# ip a
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
    inet 127.0.0.1/8 scope host lo
       valid_lft forever preferred_lft forever
    inet6 ::1/128 scope host
       valid_lft forever preferred_lft forever
2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc mq state UP group default qlen 1000
    link/ether 00:15:5d:38:01:02 brd ff:ff:ff:ff:ff:ff
    inet 172.16.2.19/16 metric 100 brd 172.16.255.255 scope global dynamic eth0
       valid_lft 85993sec preferred_lft 85993sec
    inet6 fe80::215:5dff:fe38:102/64 scope link
       valid_lft forever preferred_lft forever
```

SSH サーバを入れたので```ssh```で接続できます。取得した IP アドレスに ssh 接続、root ユーザーでパスワードを入力してログインします。

```console
del %USERPROFILE%\.ssh\known_hosts
ssh root@172.16.2.19
```

## ユーザーアカウントの作成

ユーザーを作成します。

```console
username=ユーザー名
```

```console
zfs create -o com.ubuntu.zsys:bootfs-datasets=tank/ROOT/ubuntu -o canmount=on -o mountpoint=/home/$username tank/USERDATA/$username
adduser $username
```

```console
cp -a /etc/skel/. /home/$username
chown -R $username:$username /home/$username
usermod -a -G adm,cdrom,dip,lpadmin,lxd,plugdev,sambashare,sudo $username
```

# フルのソフトウェアインストール

ミニマムインストールをアップグレードします。

```console
apt dist-upgrade --yes
```

デスクトップ用として GUI 環境をインストールします。メモリがしょぼいので、```ubuntu-desktop```ではなくて```lubuntu-desktop```を選んでみました。

```console
apt install --yes lubuntu-desktop
```

GUI 環境をインストールする場合は NetworkManager を使用してのネットワーク管理が推奨されています。lubuntu も同じでいいよね、多分。

```console
rm /etc/netplan/01-netcfg.yaml
cat >/etc/netplan/01-network-manager-all.yaml <<___
network:
  version: 2
  renderer: NetworkManager
___
```

## 日本語キーボード配列

サーバーのコンソールで記号を打ってみるとわかりますが、英語配列になっています。日本語配列に変更する手順は以下の参考文献を参照。バージョンは古いですが、画面キャプチャがあるのでわかりやすいです。

参考文献：[Ubuntuでキーボードレイアウト変更 - Ragnite Blue](https://thejuraku.com/pc/ubuntu%E3%81%A7%E3%82%AD%E3%83%BC%E3%83%9C%E3%83%BC%E3%83%89%E3%83%AC%E3%82%A4%E3%82%A2%E3%82%A6%E3%83%88%E5%A4%89%E6%9B%B4/)

コマンドは下記。

```console
dpkg-reconfigure keyboard-configuration
```

設定後、次のコマンドを打つ必要があるようです。

```console
setupcon
```

# 再起動して確認

```console
reboot
```

GUI 画面でログインします。
そして色々確認。

- キーボードが日本の配列になっている事。アットマーク @ を打ってみて確認。
- ネットワ－クが有効になっている事。仮想環境など状況によってNICの名称が変わる事があり、その場合は上述の設定```/etc/netplan/01-network.yaml```のNIC名```eth0```を変更する必要があります。
ネットワークに関しては、次のようなコマンドを試してみればわかります。
※ example.com はドメインの例示の際に使うべしとRFC2606で定められています。何か適当なサーバーを選んで下さい。

```console
ping -c2 example.com
```

失敗した場合には、上述のネットワーク設定ファイル```/mnt/etc/netplan/01-netcfg.yaml```を修正します。その為のNIC名取得は下記のコマンドで。

参考文献：[Linux から認識されている、すべてのネットワークインターフェイス名だけを取得する - Qiita](https://qiita.com/p_cub/items/43c5c44886443087de09)

```console
for d in `find /sys/devices -name net | grep -v virtual`; do ls $d; done
```

手打ちのコマンドとしては```ip a```の方が簡単ですが、上記のコマンドならNIC名だけを取り出せますので自動化が可能です。

# root 無効化

引き続き GUI 画面で作業するか、あるいは ssh 接続。
そして root パスワードを無効にします。

```console
sudo usermod -p '*' root
```

root での SSH ログインを無効にします。

```console
sudo sed -i -e"/^PermitRootLogin/d" /etc/ssh/sshd_config
```

一度ログアウトして、root ではログインできない事を確認します。

# Lubuntu の日本語設定

Lubuntu の日本語化を済ませます。

一般的な Lubuntu 設定なので、ネットを検索していただければそこら中に解説記事があります。

メインメニュー > Preferences > LXQt Settings > Locale

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/107218/c10d9ee5-4f05-fbc2-cff7-a0cb34f6cafe.png)

Region で「日本 - 日本語 (ja_JP)」を選択して Close ボタンをクリックします。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/107218/89d26b5c-a8b2-d882-ef3a-c9b05c351377.png)

確認ダイアログが表示されるので Save ボタンをクリックします。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/107218/a409153f-444b-539a-b07c-ca85b1e2de89.png)

日本語入力に関しては、なぜか、上手くいきません。
```sudo apt install --yes fcitx-mozc```してログアウト→ログインしたのですが、どうしても mozc が有効になりません。

とりあえず当面の作業に支障はありませんので、放置する事にしました。

# 家庭内DNS

[以前のサーバー設定で Unbound を立ち上げています](https://qiita.com/katz_engineer/items/4e29b954e0290621c1ab)。家庭内ルーターの DHCP などで上手く設定できていれば問題ありませんが、我が家のルーターでは設定できませんでした。

仕方が無いので、クライアントマシンの[名前解決の設定を弄ります](https://qiita.com/katz_engineer/items/4e29b954e0290621c1ab#systemd-resolved-%E3%81%AE%E8%A8%AD%E5%AE%9A%E3%82%92%E5%A4%89%E6%9B%B4)。

```console
sudo sed -i -e"/^#DNS=/c DNS=172.16.1.3" -e"/^#Domains=/c Domains=home" /etc/systemd/resolved.conf
sudo systemctl restart systemd-resolved
```

# スナップショット

初回インストールのスナップショットを作成しておきます。こういう事をしたいが為にZFSを使うのです。

```console
sudo zfs snapshot -r tank@$(date +%Y%m%d_%H%M%S)_install
```

スナップショットの一覧を表示して確認します。

```console
zfs list -t snapshot
```

ただ、どうも、自動的にsnapshotを撮られているようです。apt-getのタイミングなんでしょうかね。自分で手動snapshotした分を表示するには下記コマンドが良さそうです。

```console
zfs list -t snapshot | grep -v autozsys
```

# 仕舞い

これで最小限の Ubuntu デスクトップをZFSの上にセットアップできました。
この後は下記の記事に従って整備します。

- [自宅サーバー構築譚：Subversionをインストールして /etc をバージョン管理・Ubuntu 22.04](https://qiita.com/katz_engineer/items/92d0b58677b8783e1fe5)
- [自宅サーバー構築譚：NTPクライアント](https://qiita.com/katz_engineer/items/fa46454a85d93e6e671b)

これで Ubuntu デスクトップ環境(Lubuntu)は一通り構築完了になります。やったね:thumbsup_tone1: