それマグで!

知識はカップより、マグでゆっくり頂きます。 takuya_1stのブログ

習慣に早くから配慮した者は、 おそらく人生の実りも大きい。

raspi を lvm on dm-crypt(LUKS) に含める。

raspi を lmv on dm-crypt(LUKS) に含める。

LVM で起動することも出来た。。ext4 on dm-crypt で起動することも出来た

だったら、 ext4 on LVM on LUKSで起動することも出来るんじゃ。とおもったので。試した。

raspberry pi だからといって、特殊なことは何もない。通常通りのUSBメモリへOSインストール手順と、ほとんど同じ。

USBメモリを突っ込んでおく。

USBメモリは、ここまでlvm構成やdm-cryptで使ったもの。

sudo sgdisk -p /dev/sdd
Number  Start (sector)    End (sector)  Size       Code  Name
   1            2048         1050623   512.0 MiB   0700  Microsoft basic data
   2         1050624       250069646   118.7 GiB   8300  Linux 

luks でフォーマットする。

sudo cryptsetup luksFormat /dev/sdb2   --format options
sudo cryptsetup luksOpen /dev/sdb2 crypted
sudo cryptsetup config /dev/sdb2 --label crypted-root

パフォーマンスに差が出るので、暗号化がアルゴリズムを予め決めておく。

次のようにしてみた。

sudo cryptsetup \
  --type luks2 \
  --cipher xchacha20,aes-adiantum-plain64  \
  --hash sha256 \
  --iter-time=5000 \
  --key-size=256 \
   --pbkdf=argon2i \
   --pbkdf-memory 512000 \
  luksFormat \
  /dev/sdb 

今回は、xchacha12にしてみた。

LVMに放り込む

sudo pvcreate /dev/mapper/crypted
sudo vgcreate  vg.main /dev/mapper/crypted
sudo lvcreate  -L 50G -n root vg.main

LVM を初期化する。

sudo mkfs.ext4 /dev/mapper/vg.main-root

MicroSDの内容をUSBへ移動する。

sudo mount /dev/mapper/vg.main-root /mnt
sudo rsync -av --progress --one-file-system / /mnt

boot の内容を移動する。

sudo mount /dev/sdb1 /mnt/boot/firmware
sudo rsync -av --progress --one-file-system /boot/firmware/ /mnt/boot/firmware/

lvm on dm-crypt なので、crypttab fstab を変更する必要がある。

## ディスクのUUIDの確認 3つのコマンドのどれかで調べる。
lsblk -f 
blkid
ls -l /dev/disk/by-uuid/

書き換え後の状態

現在のブロックデバイス状態。

sdd
├─sdd1             vfat        FAT32    system-boot  C950-7AD1     281.1M    45% /mnt/boot/firmware
└─sdd2             crypto_LUKS 2        crypted-root ee398-xxxxxxx
  └─crypted        LVM2_member LVM2 001              LugY-xxxxx-
    └─vg.main-root ext4        1.0      writable     ce15fexxxx    33.4G    27% /mnt

/mnt/etc/fstab

LABEL=writable  /        ext4   discard,errors=remount-ro,commit=240    0 1
LABEL=system-boot       /boot/firmware  vfat    defaults        0       1
/swap.img none    swap    sw              0       0

/mnt/etc/crypttab

# <target name> <source device>         <key file>      <options>
# 2023-02-03
crypted UUID="ee398-xxxxx-xxxx-xxxx-xxxx"  none luks,initramfs

cmdline.txt を変える。

## 実際は1行にかく
root=LABEL=writable 
cryptdevice=UUID=e398977d-1f62-4352-9602-ee8d61d7dc3d:crypt 
initrd=0x01f00000
rootfstype=ext4
ip=192.168.2.240::192.168.1.1:255.255.0.0:raspi-ubuntu:eth0:none

root はラベル(root=LABEL=writable) またはパス(root=/dev/mapper/vg.main-root) で書く。

ip はあとでインストールする dropbearssh経由のアンロックに使う。

UUID長過ぎるし、移動が大変なのでラベルを使うことにした。

## ラベルの付与
sudo tune2fs -L writable /dev/mapper/vg.main-root
sudo fatlabel /dev/sdd1  system-boot

ブートの書き換えのためにchrootに入る。

## デバイスの準備
sudo mount -t proc none /mnt/proc/
sudo mount -t sysfs none /mnt/sys/
sudo mount -o bind /dev /mnt/dev/
sudo mount -o bind /dev/pts /mnt/dev/pts/
## chroot 
sudo -E LANG=C chroot /mnt/

必要なパッケージを入れていく。

root@chroot: # apt update
root@chroot: # apt install lvm2 busybox cryptsetup dropbear-initramfs
root@chroot: # echo "CRYPTSETUP=y" >> /etc/cryptsetup-initramfs/conf-hook

あとは、細かいところを参考資料に従って変えていく。

vim /usr/share/initramfs-tools/hooks/cryptroot
sed -i 's/^TIMEOUT=.*/TIMEOUT=100/g' /usr/share/cryptsetup/initramfs/bin/cryptroot-unlock

SSHのホスト鍵をOpenSSH-server とDropbear で共通にする。

bash dropbear-hostkey.sh

dropbear-hostkey.sh は以前作ったものを流用

cat <<EOS > dropbear-hostkey.sh

for key_type in {ecdsa,rsa,ed25519} ;  do
    src=/etc/ssh/ssh_host_${key_type}_key
    tmp=/tmp/$( basename $src)
    dst=/etc/dropbear/initramfs/dropbear_${key_type}_host_key
    ##
    cp  "${src}" "${tmp}";
    ssh-keygen -p -m PEM -f  "${tmp}"
    dropbearconvert openssh dropbear "${tmp}" "${dst}"
done;
EOS

Dropbearにログイン可能な公開鍵を登録する(chroot抜けて取ってきた)

sudo cp /home/takuya/.ssh/authorized_keys //mnt/etc/dropbear/initramfs/authorized_keys

initramfs を再構成する

root@chroot: # update-initramfs -u

特に警告もなく終われば、多分大丈夫

修正時 マウントとchroot あたりからやり直す。

sudo cryptsetup luksOpen /dev/sdb2 crypted
sudo mount /dev/mapper/vg.main-root /mnt
sudo mount /dev/sdb1 /mnt/boot/firmware
sudo mount -t proc none /mnt/proc/
sudo mount -t sysfs none /mnt/sys/
sudo mount -o bind /dev /mnt/dev/
sudo mount -o bind /dev/pts /mnt/dev/pts/
sudo -E LANG=C chroot /mnt/

cryptsetup-unlock が動かない?

以前のluks であれば、次のコマンドで動いたが、今回は動かなかった。

# cryptsetup-unlock

いったん、直接 cryptsetup を起動する

# /sbin/cryptsetup luksOpen /dev/sda2 crypted-root

initramfs で使えるようになっている。

# ls /sbin/ | grep crypt
# cryptsetup luksOpen /dev/sda2 crypted

たぶん、cmdline.txt にミスがあると思う。cryptsetupで解除して起動後、update-initramfs を実行したら問題なく動いた。この問題は今後検討する。

また、luksOpenを直接実行しても解除できた。

無事に起動できた。

MAC ADDRESSが被る

クローンしたらMacアドレスが被る。そのためIPを変えても通信できなくなることがある。

複製したらmachine-idを変えておく。MACアドレスが重複する。(macvlan) - それマグで!

systemd - Is it OK to change /etc/machine-id? - Unix & Linux Stack Exchange

マシンIDを変えておくといい。

cmdline.txt のデバッグ

cmdline.txt はカーネル起動時に渡すパラメータなので、起動後に次のコマンドで確認できる。

cat /proc/cmdline

また、dmesg でも確認できる。

たとえば、次の例は、cmdline.txt の記述をミスった場合の例。

追記

cryptroot-unlock コマンドが動かないので、以下のように設定を変更した。

/etc/cryptsetup-initramfs/conf-hook

echo CONFIG_BLK_DEV_INITRD=y >>  /etc/cryptsetup-initramfs/conf-hook

cmdline.txt

root=/dev/mapper/vg.main-root cryptdevice=/dev/mapper/crypted 

追記

tar で大量にファイルを書き込んだとき。さすがにちょっとCPU負荷がきつい。

追記 fstrim

fstrimを有効にする方法を使ってfstrim を有効化した方がいい。

discardをしないとSSDの寿命を縮めるらしいので、discardが動くようにしてほうがのが良い。luksでcryptroot を使った場合は、dm-crypt のcrypttab から discardをしてtrimを有効にしないとちゃんと動かない。

sudo vim /etc/crypttab # discard追記
sudo update-initramfs -k all -c 
sudo reboot 
## 有効になったかチェック
# Flags:          allow-discards が出ればOK
sudo cryptsetup luksDump /dev/sda2 | grep Flags 

fstrim が動くことを確認すれば、systemd を確認

 sudo systemctl status fstrim.service    
 sudo systemctl status fstrim.timer

追記

ip=xxxxの記述は、ちゃんとやらないとおかしくなる。

systemd-network-generator がエラーになる。

## エラー
ip=192.168.12.12::192.168.12.1:255.255.255.0:ubuntu:eth0:none:192.168.12.2::
## 通る
ip=192.168.12.12::192.168.12.1:255.255.255.0::eth0:none:192.168.12.2::

通るかテスト

/lib/systemd/systemd-network-generator -- `cat /proc/cmdline`
/lib/systemd/systemd-network-generator -- 'ip='
/lib/systemd/systemd-network-generator -- 'ip=123::::ubuntu::'

まったく、systemdはほんま https://github.com/systemd/systemd/issues/14319

cmdline.txt にホスト名を入れるとsystemdが誤作動するらしい。

2023-04-05

fstrim に付いて追記。