自宅サーバー構築譚：Ubuntu 22.04 LTS on ZFS in デスクトップパソコン(BIOS,MBR)・その2

# 能書き

[自宅サーバー構築譚：基本構想](https://qiita.com/katz_engineer/items/cb592be44daa28a51d9b)に基づく自宅サーバー構築の続き。

[以前の手順](https://qiita.com/katz_engineer/items/1ffea0a145da7025e10d)では、OpenSSH をインストールせず、ログインユーザーについても root での直接ログインを許可する形になっていました。色々考えまして、ここを Ubuntu の流儀に合わせます。ほとんどの手順は[以前](https://qiita.com/katz_engineer/items/1ffea0a145da7025e10d)と同じですが、それを修正するのではなく、新しい記事を起こす事にしました。

## 参考文献

- [自宅サーバー構築譚：Ubuntu on ZFS in デスクトップパソコン(BIOS,MBR)](https://qiita.com/katz_engineer/items/43bfd7ca82c941b33dc3)
- [自宅サーバー構築譚：Ubuntu 22.04 LTS on ZFS in デスクトップパソコン(BIOS,MBR)](https://qiita.com/katz_engineer/items/1ffea0a145da7025e10d)
- [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)

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

ハードウェアの仕様は[昔書いた記事](https://qiita.com/katz_engineer/items/f032a24cb273c4eb6669)の通りです。将来的にはこれをセカンダリサーバにする予定ですが、今回はプライマリサーバとして構築します。

ちなみにストレージの暗号化はしない方針です。家庭用なので。

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

サーバーをインストールする場合でもデスクトップ版のisoを使用します。Ubuntuのサイトからダウンロードして、USBメモリに焼きます。
私は普段使いのWin10マシンで[Rufus](https://forest.watch.impress.co.jp/library/software/rufus/)というツールを使ってみましたが、ここはお好みでどうぞ。

このUSBメモリをインストール対象マシンに挿入して、ここから起動。

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 zfsutils-linux
```

```console
systemctl stop zed
```

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

起動用のUSBメモリを挿します。ここにブートローダを仕込んで常時付けっ放しにしておく予定。

そのUSBメモリを含めたフォーマット対象ディスクを確認します。

```console
lsblk
```

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

```console
root@ubuntu:~# lsblk
NAME   MAJ:MIN RM    SIZE RO TYPE MOUNTPOINT
loop0    7:0    0    2.1G  1 loop /rofs
loop1    7:1    0     62M  1 loop /snap/core20/1587
loop2    7:2    0   91.7M  1 loop /snap/gtk-common-themes/1535
loop3    7:3    0   45.9M  1 loop /snap/snap-store/582
loop4    7:4    0  163.3M  1 loop /snap/firefox/1635
loop5    7:5    0  400.8M  1 loop /snap/gnome-3-38-2004/112
loop6    7:6    0     47M  1 loop /snap/snapd/16292
loop7    7:7    0    284K  1 loop /snap/snapd-desktop-integration/14
loop8    7:8    0      4K  1 loop /snap/bare/5
sda      8:0    0  465.8G  0 disk
├─sda1   8:1    0  465.8G  0 part
└─sda9   8:9    0      8M  0 part
sdb      8:16   0  465.8G  0 disk
├─sdb1   8:17   0  465.8G  0 part
└─sdb9   8:25   0      8M  0 part
sdc      8:32   1   58.2G  0 disk
└─sdc1   8:33   1   58.2G  0 part /cdrom
sdd      8:48   1   14.7G  0 disk
├─sdd1   8:49   1      1G  0 part
└─sdd2   8:50   1   13.7G  0 part
sr0     11:0    1   1024M  0 rom
```

```loop0```～```loop8```はインストーラによる設定でしょうか。
```sda```と```sdb```が内蔵HDDで、以前入れたUbuntuが残っています。
```sdc```が今回のUbuntuインストーラでしょう。
```sdd```はブートローダを仕込む為のUSBメモリです。
```sr0```はCR-ROMドライブと思われますが、今回は無関係です。

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

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

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

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

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

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

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

```console
swapoff --all
```

ブート用USBメモリのパーティションを全削除します。

```console
wipefs -a $BOOTDISK
```

ブート用USBメモリにパーティションを作成。GPTではなくてMBRにします。

※最初のパーティションを1GBに設定したら、後日、[LXDインストール](https://qiita.com/katz_engineer/items/74d7b357750e51e9c61c)の際に領域不足になりました。多目に確保した方が良さそうです。

```console
sfdisk $BOOTDISK <<___
,4G,bf
,
___
```

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

```console
sfdisk -l $BOOTDISK
```

```$DISK1```と```$DISK2```はパーティションに分けません。

```console
wipefs -a $DISK1 $DISK2
```

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

いよいよ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 ${BOOTDISK}-part1
```

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

そして内蔵HDDもzfsフォーマットします。2つ1組のHDDをミラーリングに設定します。

こちらの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 mirror ${DISK1} ${DISK2}
```

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

```console
root@ubuntu:~# zpool list
NAME    SIZE  ALLOC   FREE  CKPOINT  EXPANDSZ   FRAG    CAP  DEDUP    HEALTH  ALTROOT
bpool   960M   576K   959M        -         -     0%     0%  1.00x    ONLINE  /mnt
tank    464G   480K   464G        -         -     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/compativility.d.
config:
        NAME                                                      STATE     READ WRITE CKSUM
        bpool                                                     ONLINE       0     0     0
          usb-SanDisk__Cruzer_Fit_4C530000180129117161-0:0-part1  ONLINE       0     0     0

errors: No known data errors

  pool: tank
 state: ONLINE
  scan: none requested
config:

        NAME                                            STATE     READ WRITE CKSUM
        tank                                            ONLINE       0     0     0
          mirror-0                                      ONLINE       0     0     0
            ata-WDC_WD5003ABYX-50WERA1_WD-WMAYP7972470  ONLINE       0     0     0
            ata-WDC_WD5003ABYX-50WERA1_WD-WMAYP7949276  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/usr/local
```

LXDをインストールする為のsnapというパッケージ管理システムは、下記ディレクトリを使用します。

参考文献：[snapパッケージの関連ディレクトリ - 第714回 Firefoxを含むsnapパッケージとの付き合い方 - gihyo.jp](https://gihyo.jp/admin/serial/01/ubuntu-recipe/0714#sec4)

```console
zfs create tank/ROOT/ubuntu/snap
zfs create tank/ROOT/ubuntu/var/snap
zfs create tank/ROOT/ubuntu/var/lib/snapd
```

Dockerの為には下記ディレクトリを用意します。

```console
zfs create tank/ROOT/ubuntu/var/lib/docker
zfs create tank/ROOT/ubuntu/var/lib/containerd
```

このマシンはHDDがミラー構成なので、次のデータセットを作成します。

```console
zfs create -o com.ubuntu.zsys:bootfs=no bpool/grub
```

```/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```を作成します。今回はIPv6は使わないようにするので下記のようにしてみました。

このマシンはNICを2枚持っています。片方はオンボードで、もう片方はギガビットイーサのPCIネットワークカードです。オンボードの方は遅いのでケーブルを外してあります。

```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: enp2s1: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc fq_codel state UP group default qlen 1000
    link/ether 00:16:01:5c:19:df brd ff:ff:ff:ff:ff:ff
    inet 172.16.2.22/16 brd 172.16.255.255 scope global dynamic noprefixroute enp2s1
       valid_lft 79109sec preferred_lft 79109sec
    inet6 fe80::d711:2541:6143:727e/64 scope link noprefixroute
       valid_lft forever preferred_lft forever
3: enp0s25: <NO-CARRIER,BROADCAST,MULTICAST,UP> mtu 1500 qdisc fq_codel state DOWN group default qlen 1000
    link/ether 00:21:9b:1a:5f:94 brd ff:ff:ff:ff:ff:ff
```

[以前の記事](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アドレスを割り振ります。

参考文献：[固定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
  renderer: networkd
  ethernets:
    enp2s1:
      dhcp4: no
      addresses: [172.16.1.3/16]
      gateway4: 172.16.2.1
      nameservers:
        addresses: [172.16.2.1]
    enp0s25:
      dhcp4: no
      addresses: [172.16.1.4/16]
      gateway4: 172.16.2.1
      nameservers:
        addresses: [172.16.2.1]
___
```

## パッケージソース

```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 BOOTDISK=$BOOTDISK 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は設定しません。

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

```console
apt install --yes grub-pc linux-image-generic 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
```

## スワップ無し

スワップは諦めたので、該当手順は実施しません。

## 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
```

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

レガシー BIOS 用に GRUB をインストールします。

```console
grub-install $BOOTDISK
```

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ログイン

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

```console
ssh root@172.16.1.3
```

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

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

参考文献：[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
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
```

サーバ用としてコマンドライン環境のみをインストールします。

```console
apt install --yes ubuntu-standard
```

# 再起動して確認

```console
reboot
```

サーバーコンソールでログインします。
そして色々確認。

- キーボードが日本の配列になっている事。アットマーク @ を打ってみて確認。
- ネットワ－クが有効になっている事。仮想環境など状況によって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 無効化

引き続きサーバーコンソールで作業するか、あるいは ssh 接続。
そして root パスワードを無効にします。

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

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

```console
sed -i -e"/^PermitRootLogin /s/yes/no/" /etc/ssh/sshd_config
```

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

# スナップショット

初回インストールのスナップショットを作成しておきます。こういう事をしたいが為に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)
- [自宅サーバー構築譚：LAN内DNSサーバー Unbound・Ubuntu 22.04](https://qiita.com/katz_engineer/items/4e29b954e0290621c1ab)
- [自宅サーバー構築譚：dhcpサーバ冗長化・Ubuntu 22.04](https://qiita.com/katz_engineer/items/dfc77db6d48f0e2d3cd8)

そして更なる Ubuntu サーバー構築に進んでいきます。やったね:thumbsup_tone1: