FreeBSD13のインストール

FreeBSD 13.0-RELEASEをインストールしてみる。 本記述は13.0-BEATA2時点での内容であるが、13.0がリリースされた後、微調整する。

前提条件

設定目標

インストール設定

以下のパーティション構成を組む。ブート環境に応じて選択する。

BIOSブート環境

パーティション番号

パーティション種別

用途

サイズ

注意

-

GPTヘッダー

Protected MBR ブート

40 ブロック 

UEFIブート環境では Protected MBR は参照されない。

1

freebsd-boot

BIOS用FreeBSDブート領域

984 ブロック 

UFS領域を512KB境界(ブートローダーのサイズ制限)に設置するためのサイズを指定。

2

freebsd-ufs

UFS領域(/boot として使用)

8387584 ブロック 

ZFS領域を4GB境界に設置するためのサイズを指定。

3

freebsd-zfs

ZFS領域(/ として使用)

※都度計算※

スワップ領域を1GB境界に設置するためのサイズを指定。

4

freebsd-swap

スワップ領域(搭載メモリの2倍≦8GB)

16777216 ブロック~

8GB+補正分。

UEFIブート環境

パーティション番号

パーティション種別

用途

サイズ

注意

-

GPTヘッダー

-

40 ブロック 

1

efi

UEFI領域(FAT32フォーマット)

409560 ブロック 

UFS領域を200MB境界に設置するためのサイズを指定。

2

freebsd-ufs

UFS領域(/boot として使用)

7979008 ブロック 

ZFS領域を4GB境界に設置するためのサイズを指定。

3

freebsd-zfs

ZFS領域(/ として使用)

※都度計算※

スワップ領域を1GB境界に設置するためのサイズを指定。

4

freebsd-swap

スワップ領域(搭載メモリの2倍≦8GB)

16777216 ブロック~

8GB+補正分。

BIOSブート環境・UEFIブート環境ともに共存する環境(両用ブート環境と呼称)

パーティション番号

パーティション種別

用途

サイズ

注意

-

GPTヘッダー

Protected MBR ブート

40 ブロック 

UEFIブート環境では Protected MBR は参照されない。

1

freebsd-boot

BIOS用FreeBSDブート領域

984 ブロック 

EFI領域を512KB境界(ブートローダーのサイズ制限)に設置するためのサイズを指定。

2

efi

UEFI領域(FAT32フォーマット)

408576 ブロック 

UFS領域を200MB境界に設置するためのサイズを指定。

3

freebsd-ufs

UFS領域(/boot として使用)

7979008 ブロック 

ZFS領域を4GB境界に設置するためのサイズを指定。

4

freebsd-zfs

ZFS領域(/ として使用)

※都度計算※

スワップ領域を1GB境界に設置するためのサイズを指定。

5

freebsd-swap

スワップ領域(搭載メモリの2倍≦8GB)

16777216 ブロック~

8GB+補正分。

環境確認方法

OS起動後になるが、以下のコマンドで環境を確認できる。実際にインストール時に確認すること。 以下はある環境での実行結果である。

check-list-environment.png

ブート環境

sysctl machdep.bootmethod

この時「BIOS」と表示されればBIOSブート環境、「UEFI」とあればUEFIブート環境である。

ディスク一覧

geom disk status

ディスク一覧が表示される(この時 Status と Components が N/A となるのは無視して良い)。
下記は実行例であるが、下記の実効例の場合、インストール先メディアを選ぶこと(mmcsd0 または ada0)。

root@:~ # geom disk status
       Name  Status  Components
     mmcsd0     N/A  N/A
mmcsd0boot0     N/A  N/A
mmcsd0boot1     N/A  N/A
       ada0     N/A  N/A

TRIM/UNMAP対応の確認

sysctl kern.geom.disk.デバイス名.flags

先に確認したインストール先メディア(デバイス)に対して上記コマンドを実行する。下記の実行例のように CANDELETE の表示があれば、対応している。

root@:~ # sysctl kern.geom.disk.ada0.flags
kern.geom.disk.ada0.flags: be<OPEN,CANDELETE,CANFLUSHCACHE,UNMAPPEDBIO,DIRECTCOMPLETION,CANZONE>

AES-NI/SHA-NI対応の確認

sysctl dev.aesni.0.%desc

この時「AES-XTS」の表示があること(あればAES-NIに対応)。「SHA256」の表示があること(あればSHA-NIに対応)。

時刻およびCMOSクロックのタイムゾーンの確認

sysctl machdep.wall_cmos_clock
date

sysctl machdep.wall_cmos_clock の結果が0であること。date の結果が日本時間から9時間前で「UTC」を含むこと。

インストール

インストールメディアの入手

インストールメディアの起動とコンソールへ

ISOイメージからシステムがブートすると下記の画面が表示される。表示されない場合は起動順序に問題がある(ほぼこれ)、認識してない(挿入ミス、接続されてないなど、希に)ので確認する(確認手順は難しいのでここでは省略)。
10秒カウントダウンの後、OSが起動するので、その前に「3」を押す。あるいはスペースキーを押すとカウントダウンが止まる。

beastie-on-boot.png

3を押すと下記のようにプロンプトが表示されるので、

prompt-on-boot.png

以下のコマンドを入力して起動する(実施しなかったとしてもペナルティは無い)。

set hint.psm.0.disabled="1"
set kern.geom.label.disk_ident.enable="0"
boot

setting-on-boot.png

環境によっては、下記の追加設定を実施しても良い。ただしキー入力を受け付けなくなることがあるので、要動作確認のこと。

set hint.atkbdc.0.disabled="1"
set hint.atkbd.0.disabled="1

今時のハードウェアだと、この手のレガシー(PS/2接続)デバイスのエミュレーションの互換性が低い(遅い等)ことがあるので、可能な限り積極的に設定してみることをお勧めする。

start-bsdinstall.png

上記画面が表示されるので、「<Live CD>」を選択(カーソルキーで→に移動、エンターキーを押す)する。

start-console-login.png

ログインプロンプトが表示されるので「root」を入力してエンターキーを押す(パスワード入力は求められない)。

コマンド操作によるインストール作業

先に情報収集が成されているものとして以下のコマンドを実行する。

パーティションを切る

BIOSブート環境の場合、以下の手順でパーティションを切る(設定状態を都度 gpart show で確認できる)。

gpart destroy -F vtbd0
gpart create -s GPT vtbd0
gpart add -t freebsd-boot -s     984 vtbd0
gpart add -t freebsd-ufs  -s 8387584 vtbd0
gpart add -t freebsd-zfs  -s `gpart show vtbd0 | awk '/- free -/{ st = $1; sz = $2; sw = ( 8 * 1024 * 1024 * 1024 ) / 512; aln = ( 1024 * 1024 * 1024 ) / 512; sz -= sw; sz -= ( st + sz ) % aln; print sz }'` vtbd0
gpart add -t freebsd-swap            vtbd0

UEFIブート環境の場合、以下の手順でパーティションを切る(設定状態を都度 gpart show で確認できる)。

gpart destroy -F vtbd0
gpart create -s GPT vtbd0
gpart add -t efi          -s  409560 vtbd0
gpart add -t freebsd-ufs  -s 7979008 vtbd0
gpart add -t freebsd-zfs  -s `gpart show vtbd0 | awk '/- free -/{ st = $1; sz = $2; sw = ( 8 * 1024 * 1024 * 1024 ) / 512; aln = ( 1024 * 1024 * 1024 ) / 512; sz -= sw; sz -= ( st + sz ) % aln; print sz }'` vtbd0
gpart add -t freebsd-swap            vtbd0

両用ブート環境の場合、以下の手順でパーティションを切る(設定状態を都度 gpart show で確認できる)。

gpart destroy -F vtbd0
gpart create -s GPT vtbd0
gpart add -t freebsd-boot -s     984 vtbd0
gpart add -t efi          -s  408576 vtbd0
gpart add -t freebsd-ufs  -s 7979008 vtbd0
gpart add -t freebsd-zfs  -s `gpart show vtbd0 | awk '/- free -/{ st = $1; sz = $2; sw = ( 8 * 1024 * 1024 * 1024 ) / 512; aln = ( 1024 * 1024 * 1024 ) / 512; sz -= sw; sz -= ( st + sz ) % aln; print sz }'` vtbd0
gpart add -t freebsd-swap            vtbd0

ファイルシステムをフォーマットする

TRIM/UNMAP対応の場合、以下の手順でフォーマットする(両用ブート環境では vtbd0p2 → vtbd0p3 と置き換えること)。

newfs -U -j -E -t /dev/vtbd0p2

TRIM/UNMAPに未対応の場合、以下の手順でフォーマットする(両用ブート環境では vtbd0p2 → vtbd0p3 と置き換えること)。

newfs -U -j /dev/vtbd0p2

更にUEFIブート環境の場合、以下の手順でフォーマットする(両用ブート環境では vtbd0p1 → vtbd0p2 と置き換えること)。

newfs_msdos -F 32 -c 1 -L EFISYS /dev/vtbd0p1

フォーマットしたファイルシステムをマウントしてディレクトリを準備する

以下の手順を実施する(両用ブート環境では vtbd0p2 → vtbd0p3 と置き換えること)。

mount -t ufs -o rw,noatime /dev/vtbd0p2 /mnt
mkdir -p /mnt/boot/efi

更にUEFIブート環境の場合、以下の手順を実施する(両用ブート環境では vtbd0p1 → vtbd0p2 と置き換えること)。

mount -t msdosfs /dev/vtbd0p1 /mnt/boot/efi
mkdir -p /mnt/boot/efi/EFI/BOOT

ブートローダーをインストールする

BIOSブート環境の場合、以下の手順でブートローダーをインストールする。

gpart bootcode -b /boot/pmbr -p /boot/gptboot -i 1 vtbd0

UEFIブート環境の場合、以下の手順でブートローダーをインストールする。

cp -a /boot/loader.efi /mnt/boot/efi/EFI/BOOT/BOOTX64.efi

パーティションを暗号化(GELI)する

SHA-NIに対応している場合、以下の手順でZFSパーティションを暗号化(GELI)を施す(両用ブート環境では vtbd0p3 → vtbd0p4 と置き換えること)。

kldload geom_eli

dd if=/dev/random of=/mnt/vtbd0p3.key bs=64 count=1
chmod 0400 /mnt/vtbd0p3.key

geli init -b -B none -e AES-XTS -l 256 -a HMAC/SHA256 -s 4096 -K /mnt/vtbd0p3.key /dev/vtbd0p3
geli attach -k /mnt/vtbd0p3.key /dev/vtbd0p3

SHA-NIに未対応の場合、以下の手順でZFSパーティションを暗号化(GELI)を施す(両用ブート環境では vtbd0p3 → vtbd0p4 と置き換えること)。

kldload geom_eli

dd if=/dev/random of=/mnt/vtbd0p3.key bs=64 count=1
chmod 0400 /mnt/vtbd0p3.key

geli init -b -B none -e AES-XTS -l 256 -s 4096 -K /mnt/vtbd0p3.key /dev/vtbd0p3
geli attach -k /mnt/vtbd0p3.key /dev/vtbd0p3

ZFSファイルシステムの構築

両用ブート環境では vtbd0p3 → vtbd0p4 と置き換えること。

mkdir -p /tmp/zroot
zpool create -R /tmp/zroot -O atime=off -m legacy zroot vtbd0p3.eli
mount -t zfs -o rw,noatime zroot /tmp/zroot

zfs create -o mountpoint=/home zroot/home
zfs create -o mountpoint=/tmp  zroot/tmp
zfs create -o mountpoint=/usr  zroot/usr
zfs create -o mountpoint=/var  zroot/var
zfs create -o compression=lz4  zroot/usr/src
zfs create -o compression=lz4  zroot/usr/obj
zfs create -o compression=lz4  zroot/usr/ports
zfs create -o compression=off  zroot/usr/ports/distfiles
zfs create zroot/usr/local
zfs create zroot/var/empty
zfs create zroot/var/log
zfs create zroot/var/spool
zfs create zroot/var/spool/mqueue
zfs create zroot/var/tmp

mkdir -p /tmp/zroot/boot /tmp/zroot/bootdir
mount -t nullfs /mnt/boot /tmp/zroot/boot

配布物のインストール

tar -xpf /usr/freebsd-dist/base.txz   -C /tmp/zroot
tar -xpf /usr/freebsd-dist/kernel.txz -C /tmp/zroot
tar -xpf /usr/freebsd-dist/lib32.txz  -C /tmp/zroot

zfs set readonly=on zroot/var/empty

起動に必要な最低限の設定の実施

/tmp/zroot/etc/fstab

BIOSブート環境の場合、以下の内容でファイルを作成する(TRIM/UNMAP対応環境では sw → sw,trimonce に置き換えること)。

# Device                Mountpoint      FStype  Options                 Dump    Pass #
zroot                   /               zfs     rw,noatime              0       0
/dev/vtbd0p2            /bootdir        ufs     rw,noatime              1       1
/bootdir/boot           /boot           nullfs  rw                      0       0
/dev/vtbd0p4.eli        none            swap    sw                      0       0

UEFIブート環境の場合、以下の内容でファイルを作成する(TRIM/UNMAP対応環境では sw → sw,trimonce に置き換えること)。

# Device                Mountpoint      FStype  Options                 Dump    Pass #
zroot                   /               zfs     rw,noatime              0       0
/dev/vtbd0p2            /bootdir        ufs     rw,noatime              1       1
/bootdir/boot           /boot           nullfs  rw                      0       0
/dev/vtbd0p1            /boot/efi       msdosfs rw                      0       0
/dev/vtbd0p4.eli        none            swap    sw                      0       0

両用ブート環境の場合、以下の内容でファイルを作成する(TRIM/UNMAP対応環境では sw → sw,trimonce に置き換えること)。

# Device                Mountpoint      FStype  Options                 Dump    Pass #
zroot                   /               zfs     rw,noatime              0       0
/dev/vtbd0p3            /bootdir        ufs     rw,noatime              1       1
/bootdir/boot           /boot           nullfs  rw                      0       0
/dev/vtbd0p2            /boot/efi       msdosfs rw                      0       0
/dev/vtbd0p5.eli        none            swap    sw                      0       0

/tmp/zroot/boot/loader.conf

両用ブート環境では vtbd0p3 → vtbd0p4 と置き換えること。

autoboot_delay="5"
beastie_disable="YES"

#hint.atkbdc.0.disabled="1"
#hint.atkbd.0.disabled="1
hint.psm.0.disabled="1"

zfs_load="YES"
nullfs_load="YES"
geom_eli_load="YES"

vfs.root.mountfrom="zfs:zroot"
vfs.root.mountfrom.options="rw,noatime"

geli_vtbd0p3_keyfile0_load="YES"
geli_vtbd0p3_keyfile0_type="vtbd0p3:geli_keyfile0"
geli_vtbd0p3_keyfile0_name="/vtbd0p3.key"

/tmp/zroot/etc/rc.conf

keyrate="fast"
keymap="jp"
zfs_enable="YES"
clear_tmp_enable="YES"
moused_nondefault_enable="NO"

hostname="ホスト名"
ipv6_activate_all_interfaces="YES"
defaultrouter="IPv4デフォルトゲートウェイ"
ipv6_defaultrouter="IPv6デフォルトゲートウェイ"
ifconfig_vtnet0="inet IPv4アドレス/ネットマスク値 up"
ifconfig_vtnet0_ipv6="inet6 IPv6アドレス prefixlen 64"

sshd_enable="YES"
ntpd_enable="YES"
ntpd_sync_on_start="YES"

/tmp/zroot/etc/resolv.conf

nameserver      DNSキャッシュサーバー1
nameserver      DNSキャッシュサーバー2
nameserver      DNSキャッシュサーバー3
options         edns0 timeout:2 attempts:5

※/etc/resolv.conf の変更後、デフォルトで2秒以内に反映される(options reload-period:2)。 これはDHCP等によるネームサーバーの変更を、反映させるための設定である。

/tmp/zroot/etc/localtime

tzsetup -s -C /tmp/zroot Asia/Tokyo

/tmp/zroot/etc/ntp.conf

--- /etc/ntp.conf.orig  2021-02-12 15:31:56.000000000 +0900
+++ /etc/ntp.conf       2021-02-14 17:49:37.089165000 +0900
@@ -29,7 +29,7 @@
 #
 # The option `iburst' is used for faster initial synchronization.
 #
-pool 0.freebsd.pool.ntp.org iburst
+pool NTPサーバー iburst

 #
 # If you want to pick yourself which country's public NTP server
@@ -95,6 +95,8 @@
 #
 #server 127.127.1.0
 #fudge 127.127.1.0 stratum 10
+server 127.127.1.0
+fudge 127.127.1.0 stratum 10

 # See http://support.ntp.org/bin/view/Support/ConfiguringNTP#Section_6.14.
 # for documentation regarding leapfile. Updates to the file can be obtained

/tmp/zroot/etc/ssh/sshd_config

--- /etc/ssh/sshd_config.orig   2021-02-12 06:26:33.000000000 +0000
+++ /etc/ssh/sshd_config        2021-02-14 10:26:06.896045000 +0000
@@ -28,21 +28,21 @@

 # Logging
 #SyslogFacility AUTH
-#LogLevel INFO
+LogLevel VERBOSE

 # Authentication:

 #LoginGraceTime 2m
-#PermitRootLogin no
+PermitRootLogin prohibit-password
 #StrictModes yes
 #MaxAuthTries 6
 #MaxSessions 10

-#PubkeyAuthentication yes
+PubkeyAuthentication yes

 # The default is to check both .ssh/authorized_keys and .ssh/authorized_keys2
 # but this is overridden so installations will only check .ssh/authorized_keys
-AuthorizedKeysFile     .ssh/authorized_keys
+#AuthorizedKeysFile    .ssh/authorized_keys

 #AuthorizedPrincipalsFile none

@@ -50,7 +50,7 @@
 #AuthorizedKeysCommandUser nobody

 # For this to work you will also need host keys in /etc/ssh/ssh_known_hosts
-#HostbasedAuthentication no
+HostbasedAuthentication no
 # Change to yes if you don't trust ~/.ssh/known_hosts for
 # HostbasedAuthentication
 #IgnoreUserKnownHosts no
@@ -58,20 +58,20 @@
 #IgnoreRhosts yes

 # Change to yes to enable built-in password authentication.
-#PasswordAuthentication no
+PasswordAuthentication no
 #PermitEmptyPasswords no

 # Change to no to disable PAM authentication
-#ChallengeResponseAuthentication yes
+ChallengeResponseAuthentication no

 # Kerberos options
-#KerberosAuthentication no
+KerberosAuthentication no
 #KerberosOrLocalPasswd yes
 #KerberosTicketCleanup yes
 #KerberosGetAFSToken no

 # GSSAPI options
-#GSSAPIAuthentication no
+GSSAPIAuthentication yes
 #GSSAPICleanupCredentials yes

 # Set this to 'no' to disable PAM authentication, account processing,
@@ -97,9 +97,9 @@
 #TCPKeepAlive yes
 #PermitUserEnvironment no
 #Compression delayed
-#ClientAliveInterval 0
-#ClientAliveCountMax 3
-#UseDNS yes
+ClientAliveInterval 120
+ClientAliveCountMax 30
+UseDNS no
 #PidFile /var/run/sshd.pid
 #MaxStartups 10:30:100
 #PermitTunnel no

/tmp/zroot/root/.ssh/authorized_keys

mkdir -p /tmp/zroot/root/.ssh
# /tmp/zroot/root/.ssh/authorized_keys ファイルを編集 #

authorized_keys ファイルを設置すること。またこの時ネットワークからダウンロードできるようにしておくと便利。
ネットワークに接続して authrized_keys ファイルを取得、設置する場合は下記のような手順となる。

chroot /tmp/zroot service netif start
chroot /tmp/zroot service routing start

mount -t devfs devfs /tmp/zroot/dev
chroot /tmp/zroot fetch -o /root/.ssh/authorized_keys https://....
umount /tmp/zroot/dev

/mnt/boot/zfs/zpool.cache

umount /tmp/zroot/boot

zpool export zroot
zpool import -o cachefile=/mnt/boot/zfs/zpool.cache -o altroot=/tmp/zroot zroot
zpool export zroot
zpool import zroot

再起動する

reboot

よくある質問とその答え

Q.SHA-NIに対応したCPUなんてあるんですか?

A.2021年2月現在のIntel製CPU(Cooper Lake、Comet Lake、Tiger Lake、Tremont)において、サーバー(Ice Lake-SP 以降)・デスクトップ(Rocket Lake 以降)向けでは存在しない。
モバイル(Ice Lake 以降)向けおよび組み込み(Goldmont 以降)向けのCPUでのみ対応している状況である。
またAMD製CPUにおいてZENアーキテクチャから対応してるので、RYZENシリーズ(EPICシリーズ)では当たり前に対応してると言える。

Q.これ全部手で入力するんですか?

A.ここまでコマンドで手順化できてるなら、自動化は難しくない!と思われ。
最初から用意してくれ、という向きがあるかもしれないけど、コードだけ読まされても理解できないなら意味ないし。

クラウド環境だとシングルディスク構成がほとんどだろうから、ここに書いた手順で十分だとは思うけど、 物理環境だとマルチディスク構成を組むとして、どう設計するかは自分で考えないといけないから、
ここでの手順は参考になると思う。どこに何をどう挟み込めばいいのか、という議論はあるけど。

Q.ZFSパーティションを確保するときの計算式が意味不明です。説明求む!

A.LBAは0から始まるので、次の開始位置は領域のサイズ(の累計)となる。まずこれが前提。
512KB境界は1024ブロック、1MB境界は2048ブロック、1GBは2097152ブロックとなるので、 パーティションの開始位置が各境界のブロックで割った余りが0であることを確認する。

TODO

参考文献