DeskMini A300 に Arch Linux をインストール

# はじめに

DeskMini A300 に Arch Linux をインストールしました。

Arch Wiki の[インストールガイド](https://wiki.archlinux.jp/index.php/インストールガイド)に非常に丁寧な解説があるため、基本的にはその手順通りに進めるだけで大丈夫です。ただし、一部は環境や用途に応じて自分で設定を考える必要があったため、念のため記録を残しておきます。

# USB インストールメディアの作成

以下の手順を進める前に Arch Linux のインストールイメージ (.iso) をダウンロードします。
https://www.archlinux.jp/download/

ミラーからインストールイメージを取得した場合、改竄への対策としてファイルの署名検証が推奨されます。以下では OpenSSL を使用して SHA-1 ハッシュを計算しています。このハッシュ値が[本家](https://www.archlinux.jp/download/)で公開されているハッシュと一致することを確認します。

```console
% openssl sha1 /path/to/arch.iso
SHA1(/path/to/arch.iso)= c71fdff7f793888d7f53aa5e0685602e3167825c
```

以下の手順はインストールメディア作成に使用する OS によって異なります。

## Windows

[Rufus](https://rufus.akeo.ie/) を使用します。Rufus.exe を起動したら Device に対象のインストールメディアを、Boot selection に Arch Linux の ISO を選択して START をクリックします。書き込みモードを問われたら DD モードを選択してください。

## MAC OS X

まず、USB デバイスの名前を確認します。

```console
% diskutil list
```

Mac OS X では USB デバイスが自動的にマウントされます。この状態ではインストールイメージを書き込めないため、手動でアンマウントします。

```console
% diskutil unmountDisk /dev/diskN
```

インストールイメージを書き込みます。`/dev/diskN` の代わりに `/dev/rdiskN` を使用することで高速に転送できます。接頭辞の `r` は raw モードを意味しています。 

```console
% sudo dd if=/path/to/arch.iso of=/dev/rdiskN bs=1M
```

# ライブ環境

Arch Linux のインストールメディアを書き込んだ USB デバイスをインストール対象のコンピュータに挿入し、この USB デバイスを起動ディスクとしてシステムを起動します。DeskMini A300 の場合は何も設定しなくても勝手に起動しました。

## ロケール

最初にフォントとキーボードレイアウトの設定を行います。ここでの設定は永続化されるものではなく、必須ではありませんが、コンソールからの操作が続くため作業しやすい環境を整えておきましょう。

筆者の場合、4K テレビに HDMI 出力したこともあって、文字が小さすぎて何も読めなかったので適当に大きめのフォントに変更しました。以下の設定で、なんとか顔を近づければ文字が読める程度には改善しました。さらに大きなフォントはデフォルトでは用意されていないためライブ環境では諦めました。

```console
# setfont sun12x22
```

また、日本語キーボードを使いたかったのでキーマップも変更しました。英字キーボードを使用される場合はこの設定は必要ありません。

```console
# loadkeys jp106
```

## パーティション分割

ライブ環境から認識されているディスクの一覧を確認します。

```console
# fdisk -l
```

ディスクの名前を確認したら、対象のディスクを指定してパーティションを作成します。UEFI ブート用の `/boot` パーティションについては一定のルールがあるため以下の指示に従って作成してください。

```console
# parted /dev/nvme0n1
(parted) mklabel gpt
(parted) mkpart ESP fat32 1MiB 513MiB
(parted) set 1 boot on
(parted) set 1 esp on
```

他のパーティションについてはファイルシステムもサイズも自由です。ここではファイルシステムとして ext4 を選択し、`/` パーティションだけを作成しました。

```console
(parted) mkpart primary ext4 513MiB 100%
(parted) quit
```

パーディションの名前を `fdisk -l` で確認し、ファイルシステムに応じた適切なユーティリティでフォーマットします。

```console
# fdisk -l
Disk /dev/nvme0n1: 465.78 GiB, 500107862016 bytes, 976773168 sectors
Device           Start       End   Sectors   Size Type
/dev/nvme0n1p1    2048   1050623   1048576   512M EFI System
/dev/nvme0n1p2 1050624 976773119 975722496 465.3G Linux filesystem

# mkfs.fat -F32 /dev/nvme0n1p1
# mkfs.ext4 /dev/nvme0n1p2
```

Arch Linux をインストールするため、パーティションを `/mnt` 以下にマウントしておきます。

```console
# mount /dev/nvme0n1p2 /mnt
# mkdir /mnt/boot
# mount /dev/nvme0n1p1 /mnt/boot
```

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

署名鍵の検証には日時が必要なので、NTP を使って時刻を同期しておきます。

```console
# timedatectl set-ntp true
```

次にパッケージを取得するミラーサーバーを指定します。`vim` などを使用して `/etc/pacman.d/mirrorlist` を編集してください。距離的に近い日中韓のサーバーを上位に移動するのが良いでしょう。[Mirror Status](https://www.archlinux.jp/mirrors/status/) も参考になります。以下に一例を示します。

```config:/etc/pacman.d/mirrorlist
Server = https://ftp.jaist.ac.jp/pub/Linux/ArchLinux/$repo/os/$arch
Server = https://jpn.mirror.pkgbuild.com/$repo/os/$arch
Server = https://mirrors.cat.net/archlinux/$repo/os/$arch
```

準備ができたら `pacstrap` スクリプトを使用して base パッケージと Linux カーネル、ファームウェアをインストールします。

```console
# pacstrap /mnt base linux linux-firmware
```

## fstab の作成

先程作成したパーティションが自動的にマウントされるように `genfstab` コマンドを使用して `/etc/fstab` を作成しておきます。

```console
# genfstab -U /mnt >> /mnt/etc/fstab
```

# システムの設定

今までは USB インストールメディアのライブ環境を `/` としていました。以下のコマンドを実行すると、`pacstrap` で Arch Linux をインストールした `/mnt` 以下が `/` とて扱われるようになります。

```console
# arch-chroot /mnt
```

## パッケージインストール

最初に `/etc/pacman.conf` を編集して並列ダウンロードを有効にしておきましょう。

```config
ParallelDownloads = 5
```

`pacman -Syu` を使用して必要なグループやパッケージをインストールします。以下に例を示します。

| Package        | Repository | Description                                              |
| -------------- | ---------- | -------------------------------------------------------- |
| amd-ucode      | core       | AMD プロセッサ用のマイクロコード (ファームウェア更新)    |
| base-devel     | core       | 開発や AUR に必要なパッケージのグループ |
| fd             | community  | find の代替となる検索ツール |
| fzf            | community  | インクリメンタルな検索ツール |
| git            | extra      | 高速な分散型バージョン管理システム                       |
| intel-ucode    | extra      | Intel プロセッサ用のマイクロコード (ファームウェア更新)  |
| linux-stable   | core       | Linux カーネルの安定版                                   |
| openssh        | core       | SSH サーバーとクライアント                               |
| pacman-contrib | community  | pacman 関連のユーティリティ                              |
| ripgrep        | community  | grep の代替となる検索ツール |
| tmux           | community  | ターミナルマルチプレクサ                                 |
| vim            | extra      | テキストエディタ                                         |
| zsh            | extra      | 高機能なコマンドシェル                                   |

DeskMini A300 では AMD の Ryzen や Athlon を搭載しているはずなので `amd-ucode` をインストールします。`intel-ucode` は不要です。Intel の CPU を搭載している場合は逆です。

## タイムゾーン

システムのタイムゾーンはシンボリックリンクで指定します。

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

ハードウェアクロックを NTP で同期したシステムクロックに合わせます。ハードウェアクロックとはマザーボードに記録されている時刻のことで、システムがシャットダウンされている間も時計が動き続けます。次にシステムを起動したときにハードウェアクロックを読み込むことで自動的にシステムクロックが設定されます。

ここではハードウェアクロックにシステムクロックと同じ UTC 時間を記録します。自動的に生成される `/etc/adjtime` にハードウェアクロックが UTC 時間である旨が記載されています。

```console
# hwclock --systohc --utc
```

## ロケール

`/etc/locale.gen` を編集し、使用するロケールをアンコメントしてください。例えば、`en_US.UTF-8 UTF-8` と `ja_JP.UTF-8 UTF-8` をアンコメントします。その後で `locale-gen` スクリプトを実行することで実際にそのロケールが有効になります。

```console
# locale-gen
```

システムロケールを設定します。

```sh:/etc/locale.conf
LANG=en_US.UTF-8
```

必要に応じてフォントとキーボードレイアウトを設定しておきます。

```sh:/etc/vconsole.conf
FONT=sun12x22
KEYMAP=jp106
```

## ホスト名

このコンピュータの名前を `/etc/hostname` に書き込んでください。

```console
# echo your-hostname > /etc/hostname
```

同じ名前を `/etc/hosts` にも書き込みます。

```sh:/etc/hosts
127.0.0.1 localhost
127.0.1.1 your-hostname
::1 localhost
```

## パスワード

root ユーザーのパスワードを設定します。

```console
# passwd
```

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

EFI システムパーティションに systemd-boot をインストールします。

```console
# bootctl --path=/boot install
```

`/` パーティションの UUID を確認します。

```console
# ls -l /dev/disk/by-uuid
total 0
lrwxrwxrwx 1 root root 15 Feb 14 22:01 5a534876-bb2f-4fd3-880e-9244235d42c3 -> ../../nvme0n1p2
lrwxrwxrwx 1 root root 15 Feb 14 22:01 1234-5678 -> ../../nvme0n1p1
```

Arch Linux を起動するローダーの設定を `/boot/loader/entries` 以下に追加します。Intel プロセッサを使用している場合は `/amd-ucode.img` を `/intel-ucode.img` に置き替えてください。また、UUID には先程確認した `/` パーティションの UUID を指定してください。

```sh:/boot/loader/entries/arch.conf
# 最新の Linux カーネルを使用する場合
title Arch Linux
linux /vmlinuz-linux
initrd /amd-ucode.img
initrd /initramfs-linux.img
options root=UUID=5a534876-bb2f-4fd3-880e-9244235d42c3 rw
```

```sh:/boot/loader/entries/arch.conf
# 安定版 (Longterm Support) の Linux カーネルを使用する場合
title Arch Linux
linux /vmlinuz-linux-lts
initrd /amd-ucode.img
initrd /initramfs-linux-lts.img
options root=UUID=5a534876-bb2f-4fd3-880e-9244235d42c3 rw
```

ブートローダーの設定ファイル `/boot/loader/loader.conf` を編集します。

```sh:/boot/loader/loader.conf
default arch
timeout 5
editor no
```

## 再起動

chroot 環境から抜けてコンピュータを再起動してください。USB デバイスを取り除いても先程のブートローダーからシステムを起動できるようになっているはずです。

```console
# exit
# umount -R /mnt
# reboot
```

# ネットワーク設定

## ネットワーク・インタフェースの確認

以下のコマンドでネットワーク・インタフェースの名前を確認してください。

```console
# /ls -l /sys/class/net
total 0
lrwxrwxrwx 1 root root 0 Feb 14 22:01 enp2s0 -> ../../devices/pci0000:00/0000:00:01.7/0000:02:00.0/net/enp2s0
lrwxrwxrwx 1 root root 0 Feb 14 22:01 lo -> ../../devices/virtual/net/lo
```

## IP アドレス

ネットワークの設定は systemd-networkd を使用して管理します。以下は DHCP を使用する場合の設定ファイルです。

```ini:/etc/systemd/network/wired-dhcp.network
[Match]
Name=enp2s0

[Network]
DHCP=ipv4
```

固定 IP アドレスを使用する場合は以下のようになります。

```ini:/etc/systemd/network/wired-static.network
[Match]
Name=enp2s0

[Network]
Address=192.168.0.16/24
Gateway=192.168.0.1
DNS=8.8.8.8
```

システムの起動時に systemd-networkd が自動的に実行されるようにしておきます。また、設定を反映するために一度サービスを再起動します。

```console
# systemctl enable systemd-networkd
# systemctl restart systemd-networkd
```

## DNS

全ての名前解決を systemd 経由にするために以下のシンボリックリンクを作成します。

```console
# ln -sf /run/systemd/resolve/stub-resolv.conf /etc/resolv.conf
```

名前解決機能を提供する systemd-resolved サービスを有効にします。

```console
# systemctl enable systemd-resolved
# systemctl restart systemd-resolved
```

## SSH

SSH ログインを有効にしておきましょう。SSH サーバーの設定ファイルは `/etc/ssh/sshd_config` に存在しますが、そのままでも root 以外のユーザでパスワードログインすることは可能なので設定は後回しにしても良いでしょう。

```console
# systemctl enable sshd
# systemctl restart sshd
```

[Arch Linux における OpenSSH の設定](https://qiita.com/pttkny/items/02fcff8ae35c318776a0) も参照してください。

# ユーザー

全ての操作を root 権限で実行するのは非常に危険です。管理用のユーザーを作成し、root 権限が必要なときにだけ `sudo` を実行する運用を推奨します。

## ユーザーの追加

ユーザーの追加には `useradd` コマンドを使用します。伝統的に root 権限を取得できるユーザーグループの名称は wheel です。

```console
# useradd -m -G wheel -s /bin/zsh tacbooon
```

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

```consle
# passwd tacbooon
```

## sudo の設定

sudo の設定には `/etc/sudoers` を編集する必要がありますが、安全のため、このファイルは直接編集せず `visudo` コマンドを使用することになっています。このコマンドでファイルを編集すれば内容が誤りがないか確認してくれます。

まず、使用したいエディタを環境変数 EDITOR に設定します。ここではシェルから設定しても構いませんが、bash_profile や zshrc に以下の設定を書くなどして永続化することを推奨します。

```console
# export EDITOR=vim
```

続いて `visudo` コマンドを実行し、以下の行をアンコメントすることで wheel グループのユーザーが `sudo` を使用できるようにしてください。

```sh:/etc/sudoers
%wheel ALL=(ALL) ALL
```