Fedora 35 で LUKS2 を自動マウントする

# お詫び
肝心の1行が抜けていたので足しました。
```
cryptsetup reencrypt --resume-only --active-name <name_c> --header <header> --key-file <key-file>
```
です。

# 動機
HDD を大容量に換装した後古いものは中古買取業者に売るのですが、その際格納データの消去に悩む。
で、いつもは scrub コマンドで消し込むのだけれど、HDD容量が 10TB を超えた辺りからどうもいけない。下手すると数日かかりますんで。
で、漏れたら困るものだけ暗号化パーティションに最初から入れておけば、特に scrub 不要だろう、と。
で、色々視察するに、ポータビリティ等の観点も含め LUKS が良さそうと思いました。

# 参考
色々見渡して役立ったのはこの辺り。
- [Encrypting block devices using LUKS](https://access.redhat.com/documentation/en-us/red_hat_enterprise_linux/8/html/security_hardening/encrypting-block-devices-using-luks_security-hardening "RedHat Customer Portal")
- [LUKSパーティション自動アンロック（ubuntuインストール時の暗号化）。自動起動。](https://qiita.com/t13m082h/items/296fc1f166a2feb62dc8 "Qiita")

後は地道にマニュアル・ページ。

# 前提
- 起動時、マウント時にいちいちパスフレーズを手打ちするのはごめんなので、ファイルから読み込んで自動マウント可能とする
- ヘッダー情報はデバイスに埋め込まないで、分離ファイルに入れることにする
- LVM で下位デバイスを用意して、上は btrfs にしておく
- fstab では LABEL でマウントする

こうしておけば、物理ディスクの換装も容易だし、ファイルシステムの動的容量拡張も簡単なので。
後、ディスク破棄の際は、ヘッダーとパスフレーズ格納したパーティションだけ scrub すれば多分(簡単には)復号できないだろうから。
そのパーティションだけの scrub なら精々5GBとかだから、すぐ終わるよね。

あ、多分このトピックで影響受けることは無いと思いますが私が実際に使っているのは、Fedora 35 Silverblue です。

# 凡例
|用途|記法|実例|
|----|----|----|
|元にする名前|\<name\>|test|
|暗号化で使う名前|\<name_c\>|test_c|
|元のデバイス|\<DEV\>|/dev/VG0/LVtest|
|暗号化されたデバイス|\<DEV_c\>|/dev/mapper/LVtest_c|
|パスフレーズ入れたファイル|\<key-file\>|/boot/PPFs/test.ppf|
|ヘッダー入れたファイル|\<header\>|/boot/PPFs/test.hdr|

# 手順
## 新規にパーティション作成から始める場合
0. パスフレーズを格納したキー・ファイルの生成
    - ```dd if=/dev/urandom of=<key-file> bs=1024 count=4```
0. LVの作成(fsフォーマットはしない)
    - ```lvcreate -Ay -L <size> -n LV<name> <VG>```
0. LUKS2 でフォーマット
    - ```cryptsetup luksFormat <DEV> <key-file> --type luks2 --header <header> --label <name>```
0. LVから暗号化デバイスの作成
    - ```cryptsetup open <DEV> <name_c> --header <header> --key-file <key-file>```
0. 暗号化デバイスを btrfs でフォーマット
    - ```mkfs.btrfs -L <name_c> <DEV_c>```
0. fstab に当該エントリを追加
    - ```LABEL=<name_c>					<mount-point>		btrfs	defaults	1 4```
0. マウント
    - ```mount -L <name_c>```
0. crypttab に当該エントリを追加
    - ```<name_c>	<DEV>	<key-file>	header=<header>```

## 既存パーティションを変換する場合
0. 既存デバイスのアンマウント
0. パスフレーズを格納したキー・ファイルの生成
    - ```dd if=/dev/urandom of=<key-file> bs=1024 count=4```
0. 既存デバイスを暗号化デバイスに変換
    - ```cryptsetup reencrypt --encrypt --init-only <DEV> --key-file <key-file> --type luks2 --header <header> <name_c>```
0. 暗号化デバイスにファイルシステム・ラベルを付与
    - ```btrfs filesystem label <DEV_c> <name_c>```
0. fstab に当該エントリを追加
    - ```LABEL=<name_c>					<mount-point>		btrfs	defaults	1 4```
0. マウント
    - ```mount -L <name_c>```
0. 暗号化実行
    - ```cryptsetup reencrypt --resume-only --active-name <name_c> --header <header> --key-file <key-file>```
0. crypttab に当該エントリを追加
    - ```<name_c>	<DEV>	<key-file>	header=<header>```

## ファイルシステムの容量を拡大したい場合
0. 元のデバイスを拡大
    - ```lvextend -L <new-size> <DEV>```
0. LUKS2 デバイスの拡大
    - ```cryptsetup resize <DEV_c> --header <header> --key-file <key-file>```
0. btrfs の拡大
    - ```btrfs filesystem resize max <mount-point>```

## その他
### 当該デバイスのヘッダーを見る
- ```cryptsetup luksDump <header>```

### パスフレーズの入ったキー・ファイルの追加
- ```cryptsetup -v luksAddKey <header> <new-key-file>```

### 暗号化済みパーティションが見つからず、マウントに失敗した場合
0. 暗号化デバイスが見つかるか確認する
    - ```cryptsetup status <name_c>```
0. 見つからないなら、オープンする
    - ```cryptsetup open <DEV> <name_c> --header <header> --key-file <key-file>```
0. 復活したらマウント
    - ```mount -L <name_c>```


# 実行例
## 新規にパーティション作成から始める場合
```

bash-5.1# mkdir -p /boot/PPFs
bash-5.1# ls -ald /boot/PPFs/
drwxr-xr-x. 2 root root 4096 Feb 22 11:00 /boot/PPFs/
bash-5.1# cd /boot/PPFs
bash-5.1# dd if=/dev/urandom of=test.ppf bs=1024 count=4
4+0 records in
4+0 records out
4096 bytes (4.1 kB, 4.0 KiB) copied, 0.00052914 s, 7.7 MB/s
bash-5.1# ls -l test.ppf 
-rw-r--r--. 1 root root 4096 Feb 22 11:03 test.ppf
bash-5.1# chmod o-r test.ppf 
bash-5.1# ls -l test.ppf 
-rw-r-----. 1 root root 4096 Feb 22 11:03 test.ppf
bash-5.1# /sbin/vgdisplay -s
  "VG0" <7.42 TiB [801.00 GiB used / <6.64 TiB free]
bash-5.1# /sbin/lvcreate -Ay -L 1G -n LVtest VG0
  Logical volume "LVtest" created.
bash-5.1# cryptsetup luksFormat /dev/VG0/LVtest /boot/PPFs/test.ppf --type luks2 --header /boot/PPFs/test.hdr --label test_c

WARNING!
========
Header file does not exist, do you want to create it?

Are you sure? (Type 'yes' in capital letters): YES
bash-5.1# cryptsetup open /dev/VG0/LVtest test_c
Device /dev/VG0/LVtest is not a valid LUKS device.
bash-5.1# cryptsetup open /dev/VG0/LVtest test_c --header /boot/PPFs/test.hdr --key-file /boot/PPFs/test.ppf 
bash-5.1# ls -l test.hdr 
-rw-------. 1 root root 16777216 Feb 22 11:07 test.hdr
bash-5.1# mkfs.btrfs -L test_c /dev/mapper/test_c 
btrfs-progs v5.16.1 
See http://btrfs.wiki.kernel.org for more information.

NOTE: several default settings have changed in version 5.15, please make sure
      this does not affect your deployments:
      - DUP for metadata (-m dup)
      - enabled no-holes (-O no-holes)
      - enabled free-space-tree (-R free-space-tree)

Label:              test_c
UUID:               ad31855f-6701-4166-a5e7-b4e2ca8ccf14
Node size:          16384
Sector size:        4096
Filesystem size:    1.00GiB
Block group profiles:
  Data:             single            8.00MiB
  Metadata:         DUP              51.19MiB
  System:           DUP               8.00MiB
SSD detected:       no
Zoned device:       no
Incompat features:  extref, skinny-metadata, no-holes
Runtime features:   free-space-tree
Checksum:           crc32c
Number of devices:  1
Devices:
   ID        SIZE  PATH
    1     1.00GiB  /dev/mapper/test_c

bash-5.1# cat /etc/fstab

#
# /etc/fstab
# Created by anaconda on Sat Jul  3 09:02:24 2021
#
# Accessible filesystems, by reference, are maintained under '/dev/disk/'.
# See man pages fstab(5), findfs(8), mount(8) and/or blkid(8) for more info.
#
# After editing this file, run 'systemctl daemon-reload' to update systemd
# units generated from this file.
#
LABEL=SB-sysroot	/		btrfs	defaults	1 1
LABEL=/boot		/boot		ext4    defaults        1 2
LABEL=SB-var		/var		btrfs	defaults        1 2
#
LABEL=test_c		/mnt/test	btrfs	defaults        1 2
bash-5.1# mkdir /mnt/test
bash-5.1# mount -L test_c
bash-5.1# df -h /mnt/test/
Filesystem          Size  Used Avail Use% Mounted on
/dev/mapper/test_c  1.0G  3.6M  905M   1% /var/mnt/test
bash-5.1# cat /etc/crypttab
test_c	/dev/VG0/LVtest	/boot/PPFs/test.ppf	header=/boot/PPFs/test.hdr
bash-5.1# 
```

## 既存パーティションを変換する場合
```
bash-5.1# df -h /mnt/retest/
Filesystem                Size  Used Avail Use% Mounted on
/dev/mapper/VG0-LVretest  1.0G  3.6M  905M   1% /var/mnt/retest
bash-5.1# umount /mnt/retest 
bash-5.1# pwd
/boot/PPFs
bash-5.1# dd if=/dev/urandom of=retest.ppf bs=1024 count=4
4+0 records in
4+0 records out
4096 bytes (4.1 kB, 4.0 KiB) copied, 0.000432192 s, 9.5 MB/s
bash-5.1# ls -l retest.ppf 
-rw-r--r--. 1 root root 4096 Feb 22 11:30 retest.ppf
bash-5.1# chmod o-r retest.ppf 
bash-5.1# ls -l retest.ppf 
-rw-r-----. 1 root root 4096 Feb 22 11:30 retest.ppf
bash-5.1# cryptsetup reencrypt --encrypt --init-only /dev/VG0/LVretest --key-file /boot/PPFs/retest.ppf --type luks2 --header /boot/PPFs/retest.hdr retest_c

WARNING!
========
Header file does not exist, do you want to create it?

Are you sure? (Type 'yes' in capital letters): YES
/dev/mapper/retest_c is now active and ready for online encryption.
bash-5.1# ls -l retest.hdr 
-rw-------. 1 root root 16777216 Feb 22 11:31 retest.hdr
bash-5.1# btrfs filesystem label /dev/mapper/retest_c retest_c
bash-5.1# cat /etc/fstab

#
# /etc/fstab
# Created by anaconda on Sat Jul  3 09:02:24 2021
#
# Accessible filesystems, by reference, are maintained under '/dev/disk/'.
# See man pages fstab(5), findfs(8), mount(8) and/or blkid(8) for more info.
#
# After editing this file, run 'systemctl daemon-reload' to update systemd
# units generated from this file.
#
LABEL=SB-sysroot	/		btrfs	defaults	1 1
LABEL=/boot		/boot		ext4    defaults        1 2
LABEL=SB-var		/var		btrfs	defaults        1 2
#
LABEL=test_c		/mnt/test	btrfs	defaults        1 2
LABEL=retest_c		/mnt/retest	btrfs	defaults        1 2
bash-5.1# mount -L retest_c
bash-5.1# cryptsetup reencrypt --resume-only --active-name retest_c --header /boot/PPFs/retest.hdr --key-file /boot/PPFs/retest.ppf &
bash-5.1# df -h /mnt/retest/
Filesystem            Size  Used Avail Use% Mounted on
/dev/mapper/retest_c  1.0G  3.6M  905M   1% /var/mnt/retest
bash-5.1# cat /etc/crypttab
test_c		/dev/VG0/LVtest	/boot/PPFs/test.ppf	header=/boot/PPFs/test.hdr
retest_c	/dev/VG0/LVretest	/boot/PPFs/retest.ppf	header=/boot/PPFs/retest.hdr
bash-5.1# cryptsetup status retest_c
/dev/mapper/retest_c is active and is in use.
  type:    n/a
  cipher:  aes-xts-plain64
  keysize: 512 bits
  key location: keyring
  device:  /dev/mapper/VG0-LVretest
  sector size:  512
  offset:  0 sectors
  size:    XXXXX sectors
  mode:    read/write
```

## ファイルシステムの容量を拡大したい場合
```
bash-5.1# /sbin/lvscan|fgrep LVtest
  ACTIVE            '/dev/VG0/LVtest' [1.00 GiB] inherit
bash-5.1# /sbin/lvextend -L 2G /dev/VG0/LVtest 
  Size of logical volume VG0/LVtest changed from 1.00 GiB (256 extents) to 2.00 GiB (512 extents).
  Logical volume VG0/LVtest successfully resized.
bash-5.1# cryptsetup resize /dev/mapper/test_c --header /boot/PPFs/test.hdr --key-file /boot/PPFs/test.ppf 
bash-5.1# btrfs filesystem resize max /mnt/test
Resize device id 1 (/dev/mapper/test_c) from 1.00GiB to max
bash-5.1# df -h /mnt/test/
Filesystem          Size  Used Avail Use% Mounted on
/dev/mapper/test_c  2.0G  3.6M  1.9G   1% /var/mnt/test
bash-5.1# 
```

## その他
```
bash-5.1# cryptsetup luksDump /boot/PPFs/test.hdr 
LUKS header information
Version:       	2
Epoch:         	3
Metadata area: 	16384 [bytes]
Keyslots area: 	16744448 [bytes]
UUID:          	6e6b7681-dc18-4072-ba40-401b6b061b1c
Label:         	test_c
Subsystem:     	(no subsystem)
Flags:       	(no flags)

Data segments:
  0: crypt
	offset: 0 [bytes]
	length: (whole device)
	cipher: aes-xts-plain64
	sector: 4096 [bytes]

Keyslots:
  0: luks2
	Key:        512 bits
	Priority:   normal
	Cipher:     aes-xts-plain64
	Cipher key: 512 bits
	PBKDF:      argon2id
	Time cost:  4
	Memory:     1048576
	Threads:    4
	Salt:       59 5e 34 a0 58 44 c2 14 d3 50 ca 81 ab 8d e0 e8 
	            a4 4e 30 a3 d1 a1 f4 17 a9 19 98 39 20 f4 d4 ab 
	AF stripes: 4000
	AF hash:    sha256
	Area offset:32768 [bytes]
	Area length:258048 [bytes]
	Digest ID:  0
Tokens:
Digests:
  0: pbkdf2
	Hash:       sha256
	Iterations: 229548
	Salt:       fe 46 5e aa e5 9b 6b d1 71 5d 65 4a b7 71 bc 22 
	            66 e5 b3 81 19 bb e2 89 6c b1 33 00 7e 06 6f b3 
	Digest:     3f 92 0d a7 c5 37 84 40 fc d8 93 2c 66 07 2a 09 
	            01 58 83 06 3b 91 44 3a fd 02 eb 67 7d c6 67 9c 
bash-5.1# 
```