それマグで!

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

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

ext4 の予約ブロックのサイズを調整して空き容量を確保する。

WEBでアレコレ調べてるときに目にしたので試してみた。

容量の5%を予約ブロックとして占有している

ext4 では容量の5%を、先立って確保している

予約領域は root だけが書き込める領域で、仮にディスクの空きがなくなっても root は予約領域を使って作業ができる。

この仕組のお陰で、ディスクの空き容量が心許なくなってもしっかり動作する。

15TB の 5% って・・・

8GBのディスクを2本でRAIDを組んでいるとする。つまり15TBほどある、この5%を確保しているとすればば、800GB弱を予約ブロックとして確保しているのである。流石に多すぎないか?

ファイルを移動したりコピーするための予約ブロックとはいえ、扱うファイルは1ファイルで最大1GB程度だ、バックアップを扱ったとしても50GBくらいだ。700-800GBは使い切れない。

アーカイブ目的であれば大丈夫

デフォルトでは、ファイルシステムの 5% はフラグメントが起こらないように root ユーザー用に予約されます。非特権のプロセスがファイルシステムに書き込めなくなってからも root が使用しているデーモンは正しく動作し続けることができます (詳しくは mke2fs(8) を参照)。

最近の大容量ディスクでは、パーティションを長期アーカイブとして使用したり、システム運用に重要でない場合(/homeなど)必要以上に大きな値を設定します。予約ブロックに関する ext4 開発者の Ted Ts'o の意見は このメール を、このトピックに関する一般的な背景は このスーパーユーザの回答 を参照してください。

パーティションが以下の条件を満たしているならば、ディスク容量を増やすために予約ブロックの割合を減らしても大抵は問題ありません:

Archさんによれば、50GB以上のディスクで、データ保存が主たるディスク(頻繁に大量のファイルを作成したり消したりしない)の条件であれば、予約ブロックは消していいとのこと。つまり、徐々にファイルが溜まっていくようなバックアップ専用ディスクであれば、消して問題ないってことですね。/home でも予約ブロックが必要以上だというのであれば、もはやいらない子なんじゃ・・・

現在のブロックの確認

sudo tune2fs -l /dev/mapper/data  | grep -i Block
Reserved block count:     158135746
Block size:               4096

ブロックサイズは4096 で 予約ブロック数は、、、すごいサイズだなこれ。どう考えてもいらないわこれ。

予約ブロックの容量を減らすことにした。

100GBもあれば十分だと思うんだけど、まずは1%くらいにしておきます。

20GB にする場合

sudo tune2fs  -r $(( 20 * 1024* 1024 * 1024  / 4096 )) /dev/mapper/data-video

2%にする場合

sudo tune2fs  -m 2 /dev/mapper/data-video

参考資料

USBメモリが壊れたので記録

USB メモリ壊れました。

読み込みも書き込みもできなくなりました。

USBメモリは、保護機能があって壊れそうになると、リードオンリーになるのですが、今回はいきなり壊れました。

Raspi に挿したSDカードやUSBメモリは本当によく壊れますね。raspi はUSB-SSDや USB-HDDで運用するのが鉄板なのかもしれません。もしくは超安いSDカードを壊れる前提で使うとかですかね。

今回壊れたのは、次のUSBフラッシュ メモリです。

高耐久のSD・フラッシュメモリSSDどちらが良いのだろうか

SSDの安すぎるやつは、不安だし。産業用の高耐久なSDカードは高すぎるし。

ほどほどの高耐久のSDカードがいいんでしょうか。

通常のSSDをUSBアダプタで使うのが良いんでしょうか。

ext4 / btrfs / xfs のパフォーマンス比較だけでいいの?機能も比較しようよ。

速いか遅いかより、扱いやすいか。

なんかね、ファイル・システムのパフォーマンス比較でイキってるエントリがまた増えてたので書こうと思ったの。

以前ね、パフォーマンスを見てXFSが良さそうと思って勇んで活用したが、XFSは拡大縮小が出来なかった。

xfs Shrinking does not support (2019)

私もつかってみたがXFSは縮小が出来なかった。 なので、パーティションを作り直すとなると、どこかにRsync/xfsdumpして取り出すしかない。ちょっと不便なんですよ。

そのうち作られるだろうけど、まだまともに動く縮小機能はない。

なにより、XFSのファイルシステムは電源断で何度もぶっ壊れた経験がある。個人的な経験ですけどね。高い信頼は望むファイルシステムではないと感じる。

brfs は fsck や df が使えない。swap も難あり

使えないというわけではないが、btrfs check や btrfs df で扱う。通常のコマンドでは使えない。つまり、起動時にfsck とか出来ないってことよ。

最近では、改善されたけど以前のbtrfs はSwapファイルが作れないんですよね。改善されたけど、swapファイル作成は不便なままなんですよ。

LVMはいらないの?

xfs+ lvmやext4 + lvmのときの速度は?

btrfsならlvm同等機能あるからlvm付きで比較したほうがよくない?

ext4 は5%を税金として持っていく。

ext4 は容量の5%を予約ブロック(システム安定のため)に確保します。安定化のための税金みたいなものです。

8TBのディスクの5%ってかなりのサイズですよ。

比較するならちゃんと予約ブロックにも言及してほしいですよね。

本当にパフォーマンスが選択理由でいいの?

比較するって本当の、書き込み・読み込み速度でいいの?

っていうか、その書き込み・読み込み速度ってHDDパフォーマンスのどれくらいまで出てるの?

っていか、そのR/W速度は、SSDに変えたら上限までいくの?どうなるの?もしRAM-FSなら?

っていうか、そのR/Wってシーケンシャルなの?ブロックサイズは?

っていうか、そのR/Wはバッファどうなってるの?メモリキャッシュがあるときはどうなるの?

っていうか、極小ファイルを大量に書く場合と、巨大ファイルを更新するときは?

っていうか、透過圧縮した場合は?pci/sataの速度より速くなる?

などと考えたら、キリがないです。

ファイルシステム選択で必要な比較は、速度だけでいいんでしょうか。

速度ならまずメモリサイズを気にした方がいいし、Write backやcommit のマウントオプションだったり、圧縮性能・暗号化の有無・重複排除・安定性・可搬性だったりしませんか?

linuxファイルシステムを比較してみたって記事に速度測定のパフォーマンスしか出てこないのってなんだかなって気分になる。

crypttab に書いた内容を反映してチェックする。

cryttab 書いたけど・・・

この書式であってんのかな。と、自身が無い

/etc/crypttab の内容をチェックしたり、テストしたり、また再起動せずに反映したいときにどうするのか。

cryptdisks_start crypt-ssd を使う

crypttab の内容を使ってリマッピングする

sudo cryptdisks_start crypt-my-ssd
sudo cryptdisks_stop crypt-my-ssd

再起動前にチェックする

systemd の仕組みを通して、再起動のプロセスを擬似的に再現する。

sudo /usr/lib/systemd/system-generators/systemd-cryptsetup-generator /run/systemd/generator
sudo systemctl daemon-reload
sudo systemctl restart cryptsetup.target

参考資料

ラズパイのsdカードの情報を調べる。

このRaspiにどのSDカードを挿していたかなと。SDカードの型番やメーカーを調べたいときに、いちいち抜き差しするのもRaspiを見にくのも面倒です。

ssh 経由やコマンドでSDカードの情報を得られたら良い。

mmc コマンドでSDカードの情報を調べる。

$ mmc cid read /sys/block/mmcblk0/device
type: 'SD'
manufacturer: 'SanDisk' 'SD'
product: 'SH32G' 8.0
serial: 0x52ec4aaf
manfacturing date: 2020 nov

インストール

sudo apt install mmc-utils -y

使用方法

mmc コマンドでSDカードの情報が出来る。

mmc csd read /sys/block/mmcblk0/device
mmc scr read /sys/block/mmcblk0/device
mmc cid read /sys/block/mmcblk0/device

実行例

対応規格を調べる。

# mmc csd read /sys/block/mmcblk0/device
type: 'SD'
card classes: 11 extension, 10 switch, 8 application specific, 7 lock card, 5 erase, 4 block write, 2 block read, 1 reserved, 0 basic,
capacity: 29.72Gbyte (31914983424 bytes, 62333952 sectors, 512 bytes each)

タイプを調べる

# mmc scr read /sys/block/mmcblk0/device
type: 'SD'
version: SD 3.0x
bus widths: 4bit, 1bit,

メーカーと型番、シリアルを調べる。

# mmc cid read /sys/block/mmcblk0/device
type: 'SD'
manufacturer: 'SanDisk' 'SD'
product: 'SH32G' 8.0
serial: 0x52ec4aaf
manfacturing date: 2020 nov

その他のMMCコマンドもあるが、eMMC用なので、SDカードで使えるのは上記くらい。

参考資料

https://raspberrypi.stackexchange.com/questions/121560/how-do-i-figure-out-the-brand-and-type-of-an-sd-card-on-the-commandline

raspi でホスト名(マシン名)が変更できない

hostname を変更しても無駄なときがある。

よくある記事の「hostnamectl を使えば良い。」という記事を信じてやってみたが。

sudo hostnamectl  set-hostname my-server --static
sudo reboot 

変わらない。

hostnamectl
 Static hostname: raspberrypi
       Icon name: computer
      Machine ID: 4331286d1cd4be5f9603f87863e361bd
         Boot ID: 44a08433aff242e0bb39cd2a1bf45ce1
Operating System: Ubuntu 22.04.1 LTS
          Kernel: Linux 5.15.0-1023-raspi
    Architecture: arm64

なぜだ。

以下のファイルを変えても無駄。

ホスト名を変えられる手段を試したがだめだった。

hostname myhost
hostnamectl set-hostname myhost
vim /etc/hostname
vim /etc/hosts

これらのファイルは、systemdの制御下に置かれている。

ホスト名は、systemdが管理している。

かといっても、systemdで設定を書き換えても、再起動で元に戻る。詰んだ。

原因は cloud-init

systemd はinit時に cloud-initを尊重するように設計されている。これ原因らしい。

raspberry pi の場合は、cloud-initを使うように構成されている。

mount /dev/sdb1 /mnt
cat /mnt/user-data

user-data を書き換えるか削除すると改善する。

sudo rm /var/lib/cloud/data/set-hostname

cloud-initにはキャッシュがある。

設定済みのコンフィグは最後に起動した設定を再現するようにキャッシュされている。

そのため user-data だけを消してもまたもとに戻ることがある。

だったら、cloud-initを無効化するとか

sudo touch /etc/cloud/cloud-init.disabled

キャッシュ消してもいいけど。。。

sudo rm -rf /etc/cloud/*
sudo rm -rf /var/lib/cloud/*

中途半端に消したり無効化すると、ネットワークに繋がらなくなったりするのであまりおすすめできないんですよね。

netplanを使ってる場合は netplanをきちんと書くか、/etc/systemd/network に記述しないとネットワークが繋がらなくなります。

Raspberry Pi Imager が原因

Raspberry Pi Imager では cloud-init を用いて設定を流し込んでいる。

Imagerの各種設定で初期設定した場合

D:\user-data のファイルが作られる。このuser-dataファイルに初期設定が書かれる。cloud-initとしては正しい運用だ。 ただ、cloud-initで再起動時に常に上書きされるのは、気づかないとハマります。

Pi Imager は入門者がサクッと触るにはいいけど、Linux初心者向けとは言い難い気がする。

cloud-init で 残り続けるパスワード

先述の通り、Raspberry pi Imager で作成するとUser Data が作られる。このデータは初期化終了後もVFAT ディスクに残り続ける。

そのため、SDカードを抜き取れば誰でも読めてしまう。たとえば、私のRaspberry Ubuntu には、以下のデータが残っていた。

root@raspi-ubuntu:/# cat /boot/firmware/user-data
#cloud-config
hostname: raspi-ubuntu
manage_etc_hosts: true
packages:
- avahi-daemon
apt:
  conf: |
    Acquire {
      Check-Date "false";
    };

users:
- name: takuya
  groups: users,adm,dialout,audio,netdev,video,plugdev,cdrom,games,input,gpio,spi,i2c,render,sudo
  shell: /bin/bash
  lock_passwd: false
  passwd: $5$ZQ3aRCLP8q/

ssh_pwauth: true

timezone: Asia/Tokyo
runcmd:
- sed -i 's/^s*REGDOMAIN=S*/REGDOMAIN=JP/' /etc/default/crda || true
- localectl set-x11-keymap "us" pc105
- setupcon -k --force || true

User Dataのファイルは残ってるので再利用可能なのだが、暗号化ディスクの場合、流石に消さないと不味いんじゃないかと思った。

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

Raspberry Pi のSDカードを複製して、2台起動したらMACアドレスが衝突した。eth0は衝突しないんだけど、macvlan が衝突した

machine-id の変更

rm -f /etc/machine-id
dbus-uuidgen --ensure=/etc/machine-id
reboot

machine-id を変更したら衝突がなくなった。

dd によるclone後にやっておくべきだったかもしれない。

systemd-firstboot --root=/mnt --setup-machine-id

確認方法

次のように行って、マシンのIDを確認しておく。

hostnamectl
 Static hostname: pi4-ubuntu
       Icon name: computer
      Machine ID: 50078343ec98aa8a7392aac963e35ec6
         Boot ID: dfe88d213c74429fb56afcf16383a54a
Operating System: Ubuntu 22.04.1 LTS
          Kernel: Linux 5.15.0-1023-raspi
    Architecture: arm64

reboot なしで行うには、次のように行えるが、machine-idから生成されるっぽいmacvlan のMAC ADDRを考慮すると再起動したほうが良いかもしれない。

rm /etc/machine-id
rm /var/lib/dbus/machine-id
dbus-uuidgen --ensure
systemd-machine-id-setup
cat /etc/machine-id
hostnamectl

ちゃんとおぼえてないけど、cloud-init が走る ubuntu の場合、ssh のホストキーも変更されたような。

参考資料

https://unix.stackexchange.com/questions/402999/is-it-ok-to-change-etc-machine-id

You must choose a longer password にとりあえず対処する

パスワードが短くて怒られる。

とりあえずサクッと作業するために一時的にパスワードを変えようとしたら怒られた。

takuya@pi4-ubuntu:~$ passwd
Changing password for takuya.
Current password:
New password:
Retype new password:
You must choose a longer password.

PAM で制限されてるんだろうけど、ちょっと変えたいだけ。ということもある。

その時は、root 権限で強制的に上書きする。

sudo passwd

弱いパスワードは、一時的な対応です。正しい長さのパスワードに戻すのを忘れないようにしてください。

ubuntuの仮想マシンを作って、ecryptfs を実験した。

仮想マシンを作って、encfs・ecryptfs を実験する

ecryptfs

https://abillyz.com/moco/studies/276

ecryptfs制限

  • ファイルの名前の長さに制限(割と辛い)
  • スパース・ファイルが作れない(割と辛い)

代替案との比較

  • dm-crypt ブロック全体を暗号化する。TPMチップがないと解除が大変
  • Encfs ほとんど同じ。 ecryptfsのUbuntu実装の機能を使わないならこれでもいい。

目的をはっきりさせる。

LUKSでシステム全体を暗号化してしまうのがベター

特定のパスワードやパスフレーズを暗号化するのであれば、ecrypts を持ち出さなくてもいい。SSHパスフレーズをつけたり、特定ファイルをOpenSSLで暗号化してしまえばいい。またこの目的でBitwarden / 1passwordにデータを入れてしまうのもいい。

ホームディレクトリ全体の暗号化は、SSH公開鍵認証と相性が悪い。

以上のことより、ecryptfs を使うのであれば、特定ディレクトリを対象にするとメリットが得られる。たとえばChromeFirefoxのキャッシュストレージを暗号化するなど特定のフォルダを暗号化してしまうのが良い。と判断している。

ホームディレクトリを暗号化してしまう場合。とルートファイルシステムを暗号化することを考えると、ecryptfsでは、どうしても中途半端になるイメージが拭えない

仮想マシンの作成

NAME=u04
### 
qemu-img create -f qcow2 /var/lib/libvirt/images/$NAME.qcow2 10G
##
virt-install\
 --connect=qemu:///system  \
 --name $NAME \
 --ram 8192  \
 --disk path=/var/lib/libvirt/images/$NAME.qcow2  \
 --location /var/lib/libvirt/images/ubuntu-20.04.5-live-server-amd64.iso,kernel=casper/hwe-vmlinuz,initrd=casper/hwe-initrd \
 --vcpus 8  \
 --virt-type kvm  \
 --os-type linux  \
 --os-variant ubuntu20.04  \
 --graphics none \
 --extra-args "console=tty0 console=ttyS0,115200n8" \

インストール

ssh \
 -o UserKnownHostsFile=/dev/null \
 -o StrictHostKeyChecking=no \
installer@192.168.2.195

ユーザーの作成

sudo adduser takuya01
sudo usermod -aG sudo takuya01

別のユーザーでログインし直す

Ubuntu 20.04.5 LTS u04 ttyS0
    
u04 login: takuya01

暗号化ツールをインストール

sudo apt-get install ecryptfs-utils
sudo ecryptfs-migrate-home -u takuya

実際にやったものがこちら

takuya01@u04:~$ sudo ecryptfs-migrate-home -u takuya
INFO:  Checking disk space, this may take a few moments.  Please be patient.
INFO:  Checking for open files in /home/takuya
Enter your login passphrase [takuya]:

************************************************************************
YOU SHOULD RECORD YOUR MOUNT PASSPHRASE AND STORE IT IN A SAFE LOCATION.
  ecryptfs-unwrap-passphrase ~/.ecryptfs/wrapped-passphrase
THIS WILL BE REQUIRED IF YOU NEED TO RECOVER YOUR DATA AT A LATER TIME.
************************************************************************

Done configuring.

chown: cannot access '/dev/shm/.ecryptfs-takuya': No such file or directory
INFO:  Encrypted home has been set up, encrypting files now...this may take a while.
sending incremental file list
./
.bash_history
            109 100%    0.00kB/s    0:00:00 (xfr#1, to-chk=8/10)
.bash_logout
            220 100%  107.42kB/s    0:00:00 (xfr#2, to-chk=7/10)
.bashrc
          3,771 100%  920.65kB/s    0:00:00 (xfr#3, to-chk=6/10)
.profile
            807 100%  131.35kB/s    0:00:00 (xfr#4, to-chk=5/10)
.sudo_as_admin_successful
              0 100%    0.00kB/s    0:00:00 (xfr#5, to-chk=4/10)
.cache/
.cache/motd.legal-displayed
              0 100%    0.00kB/s    0:00:00 (xfr#6, to-chk=1/10)
.ssh/
.ssh/authorized_keys
          1,460 100%  109.68kB/s    0:00:00 (xfr#7, to-chk=0/10)
Could not unlink the key(s) from your keying. Please use `keyctl unlink` if you wish to remove the key(s). Proceeding with umount.

========================================================================
Some Important Notes!

 1. The file encryption appears to have completed successfully, however,
    takuya MUST LOGIN IMMEDIATELY, _BEFORE_THE_NEXT_REBOOT_,
    TO COMPLETE THE MIGRATION!!!

 2. If takuya can log in and read and write their files, then the migration is complete,
    and you should remove /home/takuya.sAHJQilw.
    Otherwise, restore /home/takuya.sAHJQilw back to /home/takuya.

 3. takuya should also run 'ecryptfs-unwrap-passphrase' and record
    their randomly generated mount passphrase as soon as possible.

 4. To ensure the integrity of all encrypted data on this system, you
    should also encrypt swap space with 'ecryptfs-setup-swap'.
========================================================================

暗号化前のファイルはコピーされて保持されている。

暗号化前のファイルは必要に応じて消す。

takuya01@u04:~$ sudo ls  /home/
takuya  takuya.sAHJQilw  takuya01

暗号化の設定について。

sudo cat /home/takuya/Access-Your-Private-Data.desktop
[Desktop Entry]
_Name=Access Your Private Data
_GenericName=Access Your Private Data
Exec=/usr/bin/ecryptfs-mount-private
Terminal=true
Type=Application
Categories=System;Security;
X-Ubuntu-Gettext-Domain=ecryptfs-utils

READMEが作られている。

sudo cat /home/takuya/README.txt
THIS DIRECTORY HAS BEEN UNMOUNTED TO PROTECT YOUR DATA.

From the graphical desktop, click on:
 "Access Your Private Data"

or

From the command line, run:
 ecryptfs-mount-private

一度ログインすると。マウントされる。

Ubuntu 20.04.5 LTS u04 ttyS0

u04 login: takuya
Password:
takuya@u04:~$ ls -at
.bash_history  ..                         .cache        .bashrc
.Private       .                          .ssh          .profile
.ecryptfs      .sudo_as_admin_successful  .bash_logout

ログアウトしても、マウントは維持される。*1

takuya@u04:~$ logout

別のユーザーでログイン

Ubuntu 20.04.5 LTS u04 ttyS0

u04 login: takuya01
Password:

マウントされたまま

takuya01@u04:~$ mount  | grep takuya
/home/.ecryptfs/takuya/.Private on /home/takuya type ecryptfs (rw,nosuid,nodev,relatime,ecryptfs_fnek_sig=5f73458653f1ac97,ecryptfs_sig=a910660e088e68f2,ecryptfs_cipher=aes,ecryptfs_key_bytes=16,ecryptfs_unlink_sigs)

再起動後

リカバリ用のパスワードを取り出す

/usr/bin/ecryptfs-unwrap-passphrase
Passphrase:
060ec7342ef1715c66b0dcd0a5f27fa0

ログアウトしてもマウントされたまま残る

これがセキュリティ的に問題を発生させると問われると、どうなんでしょう。私は別に問題ないと思う。

https://askubuntu.com/questions/910484/encrypted-home-folder-still-accessible-after-logout

SSH公開鍵認証でログインできない /etc/ssh/sshd_config

Match user takuya
  AuthorizedKeysFile    /etc/ssh/takuya/authorized_keys .ssh/authorized_keys
sudo midir /etc/ssh/takuya
sudo cp  /home/takuya/.ssh/authorized_keys  /etc/ssh/takuya/authorized_keys
sudo chown takuya. -R /etc/ssh/takuya

これでログインできるようにはなるが、公開鍵認証で秘密鍵でログインしても、ecryptfs は解除されない。

ssh  takuya@192.168.2.195 ls  -alt ~
total 8
dr-x------ 2 takuya takuya 4096  2月  2 09:26 .
lrwxrwxrwx 1 takuya takuya   56  2月  2 09:26 Access-Your-Private-Data.desktop -> /usr/share/ecryptfs-utils/ecryptfs-mount-private.desktop
lrwxrwxrwx 1 takuya takuya   52  2月  2 09:26 README.txt -> /usr/share/ecryptfs-utils/ecryptfs-mount-private.txt
lrwxrwxrwx 1 takuya takuya   31  2月  2 09:26 .Private -> /home/.ecryptfs/takuya/.Private
lrwxrwxrwx 1 takuya takuya   32  2月  2 09:26 .ecryptfs -> /home/.ecryptfs/takuya/.ecryptfs
drwxr-xr-x 6 root   root   4096  2月  2 09:26 ..

SSH経由でログイン・ログアウトしたら・・・?

ログイン手法 ecrypt自動解除 ログアウト時
パスワードログイン 解除される マウントされたまま
ssh pubkey 手動解除 ロックされる

マウント中は、root権限で閲覧できます。マウントはしてるので当然です。

SSH公開鍵認証後に、ecryptfs-mount-private するか、いったんパスワードログインしておくのが良いでしょう。 公開鍵の設置場所を変えると、返ってややこしいと思います。

解決策

  • systemd で ログアウト時にユーザー所有プロセスを全部KILLする参考
  • .profile に ecryptfs-mount-private を追加する。参考
  • .logout に ecryptfs-umount-private を追加する。

参考資料

https://qastack.jp/unix/251902/ecryptfs-auto-umount-does-not-work

*1:後で調べたら pam_systemd.so が動くので自動アンマウントが動かないらしい。

Chromeが動画再生で真っ黒対策になる対策

WindowsGoogle Chromeで真っ黒になる。

画面全体がブラックアウトして、Chromeの画面が真っ黒になることがある。

原因はハードウェア・アクセラレーション

GPU周りの、ハードウェアアクセラレーションが原因であることが多い。

とされるが、ハードウェアのアクセラレーションをきちんと処理できずChromeが自分自身のキャッシュをぶっ壊してしまうのである。

結局はChromeの問題である。

シェーダーキャッシュの削除

とにかくGoogle Chromeのキャッシュ(シェーダーキャッシュ)を削除する。

%USERPROFILE%\AppData\Local\Google\Chrome\User Data\ShaderCache

以下のファイルを削除する。

エクスプローラーでキャッシュフォルダを開いてゴミ箱にブチこむ。

Google ChromeのUser Dataは、Chromeを起動中に更新されるため、Chromeを終了後に行う。

その他の方法(多分見当違い)

検索すると、いろいろな解決方法が出てくる。

履歴を消したりキャッシュを消したら治ると言われているが、理由がある。

それは、開いていたウェブサイトがキャッシュヒットしなくなるためであり、同じサイトの同じページを開いたら再発するのである。

Google Chromeからログアウト。すれば治ると言われているが、理由がある。

Chromeからログアウトしてプロファイルを削除すれば、User Dataが削除されるので合わせてShareCacheも削除されるので治るのである。

Windows再起動すれば治ると言われているが。GPUドライバの更新があるとそのときにアップデートが走って偶然治ることがあるかもしれない。

もう一つの解決方法がハードウェアアクセラレーション

ハードウェア・アクセラレーションを停止する。この方法は機能する。

たしかに、Windowsのハードウェア・アクセラレーションとGoogle Chromeのキャッシュ結果がおかしいのは間違いないので。それをオフにすれば治る。

CPU負荷が上がりそうなのでできればハードウェアアクセラレーションをオンにしておきたいところである。

エラーが良く起きるとき

画面が真っ黒になり、応答なしになり、真っ白なウインドウだけが表示される。

こういうのは、Google Meet を使ったあとに頻発するので、たぶんだけど、Google Meetでの画面共有のストリーミング処理に問題があるのではと思っている。

linuxでディスクのラベルの確認と変更方法まとめ。

linux のディスクのラベルの確認方法

/dev のマッピングから見える

ls -l /dev/disk/by-label/

または、lsblk で

lsblk -f 

ほかにも、df -Tblkid を使って見ることが出来る。

ディスクのラベルの設定 ext4

tune2fs -L YOURNAME /dev/sdb2

他にも、e2label コマンドで指定可能、また、mkfs.ext4 -L でフォーマット作成時に、同時で指定が可能。

ディスクのラベルの設定 vfat

fatlabel /dev/sdb1 system-boot   

ほかにも、mlabel コマンドで可能です。また、mkfs.vfat -n NAME コマンドで作成時に指定可能。

暗号化ブロックデバッグ luks

sudo cryptsetup config /dev/sda2 --label root-crypted

cryptsetup を使うと、LUKS2のVolumeにLabel指定が可能になる。

また、`sudo cryptsetup luksDump /dev/sdx でラベル確認が可能。

exfat のラベルの設定

exfatlabel  DEVICE LABEL

exfatlabel コマンドでサクッとラベルを付けられる。

btrfs のラベルを変更

sudo btrfs filesystem label <mountpoint> <newlabel>
sudo btrfs filesystem label <device> <newlabel>

btrfs はブロックデバイスとマウントポイント引数に取るのがちょっと不思議。

swap ファイルシステム

swaplabel コマンドがある。

swaplabel -L NAME /dev/mapper/block

参考資料

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 に付いて追記。

Raspberry pi を dm-crypt(LUKS) にして暗号化する。(その2構成実践)

LVM で起動することも出来た。

ext4 on dm-crypt で起動するようにする。 raspberry pi だからといって、特殊なことは何もない。通常通りのUSBメモリへOSインストール手順と、ほとんど同じ。

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

USBメモリは以前にGPT実験でつかったのでパーティションがそのままあるので流用。

sudo sgdisk -p /dev/sdb
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 crypt
sudo cryptsetup config /dev/sdb2 --label root-crypt

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

sudo cryptsetup  luksFormat \
 --type luks2 \
 --cipher xchacha20,aes-adiantum-plain64 \
 --hash sha256 --iter-time 5000 \
  -s 256 --pbkdf argon2i \
  /dev/sdb2

xchacha12,aes-adiantum-plain64 もあるけど、xchacha20,aes-adiantum-plain64でいいと思います。

ブート用のパーティションを用意する。

sudo mkfs.vfat /dev/sdb1 

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

sudo mount /dev/mapper/crypted /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/

わたしは、raspi-ubuntu(arm64) を使っているので、boot/firmware/ raspi3 / raspbian だと異なるかもしれない。

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

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

crypttab / fstab を書き換える。

UUIDを確認する。

sudo lsblk -f

現在の状態。

sdb
├─sdb1             vfat        FAT32  system-boot  FE3C-0011
└─sdb2             crypto_LUKS 2  root-crypted xxx-b2ed-xxxx
  └─crypt          ext4        1.0      writable   406d-8c6c-xxxx

crypttab を確認

cat /mnt/etc/crypttab
# <target name> <source device>         <key file>      <options>
# 2023-02-03
crypt UUID="xxx-xxxx-xxxx-xxxx-xxxx"  none luks,initramfs

fstab を確認

cat /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

fstab はLABELなので、そのままでも問題なさそう。

cmdline.txt を編集

root=LABEL=writable root=/dev/mapper/crypt cryptdevice=UUID=xxxxx-xxxx-xxxx-xxxx-xxxxxxx:crypt

入れたのは、次の項目。

## 実際は1行にかく
root=LABEL=writable 
cryptdevice=UUID=XXXX-XXXX-XXXX-XXXX-XXXXXXXXXX:crypt 
rootfstype=ext4
ip=192.168.12.240::192.168.12.1:255.255.0.0:raspi-ubuntu:eth0:none

ブートの書き換えのために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のホスト鍵をOpenSSHd とDropbear で共通にする。

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
bash dropbear-hostkey.sh

ログイン可能なユーザのauthorized_keys を登録する

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

initramfs を再構成する

root@chroot: # update-initramfs -u

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

再起動後

USB メモリを差し替えて、起動を確認する。

再起動して確認したら、起動出来た。

sda                  8:16   1  14.3G  0 disk
├─sda1               8:17   1   256M  0 part  /boot/firmware
└─sda2               8:18   1  14.1G  0 part
  └─crypt          253:3    0  14.1G  0 crypt /

initramfsからブートするする

initramfsで止まったときも、自分で何とかすることができる。

(initramfs) cryptsetup luksOpen /dev/sda3 dm_crypt-0
(initramfs) mount /dev/mapper/vg-lv /root
(initramfs) exec swich_root /root /sbin/init

ssh のブートアンロック

ssh のdropbear 経由でのアンロックを試す。

ssh  \
  -o UserKnownHostsFile=/dev/null \
  -o StrictHostKeyChecking=no \
root@192.168.12.122

鍵が同じなってることを確認

ssh root@192.168.12.122

参考資料

Raspberry pi を dm-crypt(LUKS) にして暗号化する。(その1考察ポエム)

raspberry pi をLUKSにする。

バイスを暗号化すると、盗難対策だとかコピープロテクションとかを考慮しつつ、センシティブ情報を格納出来る。

暗号化は現代には不可欠な技術だが、RaspberryPiにはTPMチップが無いので、X86のPCのような手軽に扱える用にならない。

が、パスワードやログなど見られたくない情報を保護するのであれば、やはりLUKSが一番だろうと思う。

Raspi を暗号化する前に考えること。

2つの事を考える。一つはCPUの負荷、もう一つは格納方法だ。

パフォーマンスとCPU負荷

暗号化によりCPU不可が大きくなりすぎると、ほかの処理に影響がでる。

格納手段による違い。

機密情報を保持するのに、システム全体か、特定ファイルだけを暗号化すればいいのか。ディレクトリだけでいいのか、ネットワーク上だけでいいのか。などを考えておかないといけない。

パフォーマンス

intel にはAES-NIという強烈なAESサポートがある。armの一部製品にも含まれるらしいが、RaspiのCPUには含まれない。

CPUベンチマーク

LUKSを使ったとき、どれくらいの速度差があるか、ちょっと見てみる。

cryptsetup benchmark -c xchacha20,aes-adiantum-plain64
cryptsetup benchmark -c aes-xts-plain64 -s 256

自宅に転がっているPCで軽く測定してみた。

cpu アルゴリズム Encrypt Decrypt
RPi4(Cortex-A72) xchacha20,aes-adiantum 256b 133.2 MiB/s 132.6 MiB/s
RPi4(Cortex-A72) aes-xts 256b 76.8 MiB/s 85.5 MiB/s
Intel i6700 xchacha20,aes-adiantum 256b 498.8 MiB/s 473.6 MiB/s
Intel i6700 aes-xts 256b 2762 MiB/s 2853 MiB/s
Intel n4200 xchacha20,aes-adiantum 256b 303.3 MiB/s 304.4 MiB/s
Intel n4200 aes-xts 256b 742.5 MiB/s 743.6 MiB/s
intel n3350 xchacha20,aes-adiantum 256b 258.6 MiB/s 293.6 MiB/s
intel n3350 aes-xts 256b 697.3 MiB/s 716.8 MiB/s
AMD 4750GE xchacha20,aes-adiantum 256b 469.7 MiB/s 498.3 MiB/s
AMD 4750GE aes-xts 256b 1119.7 MiB/s 1095.9 MiB/s

正確に測定するのであれば、openssl でやるべきだろうが、今回は cryptsetup のベンチマークを利用した。

intel 6700 という古いCPUでも格段のスコアを叩き出している。AMD Ryzenは期待ほど伸びない。インテル強い。

この測定から、Raspberry Pi でLUKSのような暗号化デバイスを扱うと、暗号化がボトルネックになると予想される。

ちなみに、Rpi4 結果を抜粋するとつぎのようになる。

cpu アルゴリズム Encrypt Decrypt
RPi4(Cortex-A72) xchacha20,aes-adiantum 256b 133.2 MiB/s 132.6 MiB/s
RPi4(Cortex-A72) xchacha12,aes-adiantum 256b 161.0 MiB/s 162.2 MiB/s
RPi4(Cortex-A72) aes-xts 256b 76.8 MiB/s 85.5 MiB/s
RPi4(Cortex-A72) aes-cbc 128b 79.6 MiB/s 82.7 MiB/s

他にもみたいときは cryptsetup benchmarkをオプション無しで起動すると良い。chachaがずば抜けている。xchacha12はなんちゃって暗号化のためには行けそうだけど、ちゃんと安全を確保するには厳しそう

cpu 負荷について。

仮にAES-XTSで妥協したとする。そこそこの速度がでるから良いかも。と判断して採用したとする。そうしても、CPUがハイ・ロードでとどまり続けてしまうと。使いものにならないかもしれない。

https://github.com/keks24/raspberry-pi-luks/issues/2のスレッドをみてみると、以下の画像がでてきた。

LUKSで起動に成功したとしても、暗号化処理にCPUを取られる可能性がある。 CPUのワークロードが高くなりすぎて電源浪費するし、CPUリソースを食い尽くすと他の処理が遅延するため、暗号化に意味がないということがわかる。10年前には「秘文」のようなソフトウェア暗号化による体感速度の低下があった。先輩方にわせると、みんな秘文が嫌いだったらしい。あの当時の苦痛に、いまさら頭を悩ますことになる可能性がある。

adiantumという暗号化

ここで、注目されるのが、xchacha20,aes-adiantum である。これはCPU負荷はそんなに高くはなく速度もAES-NIには及ばない。しかしCPUでAES-XTSを処理するよりは早く、ワークロードも低めに抑えられる。

試しに、適当なUSBメモリをxchacha20,aes-adiantumで暗号化して使ってみたところ、CPU負荷は気にならないレベルまで落ちてくれた。

このあたりの詳しい検証は参考資料に書いてあった。

暗号化する対象と、ツール

dm-cryptのようにルートファイルシステム全体を暗号化せずに、機密情報をRaspberry Pi に格納するにはどうすればいいだろうか。

RaspiのストレージはSDカードです。簡単に奪取されます。パスワードや秘密鍵を設置しておくと面倒が起きそうです。

Raspiに安全にパスワード(秘密鍵)を設置する

安全に機密情報保持するなら、考えられる手段は、次のとおりです。

  • LUKSでSDカード全体を暗号化する
  • ecryptfs/encfs で$HOMEを暗号化する
  • 秘密鍵パスフレーズ保護する。単なる暗号化ファイル作成
  • bitwarden / 1passwordなどを使う。
  • NFS などネットワークマウント
手法 対象 デメリット
LUKS システム全体 起動時にパスワード入力が必要
initramfsが必要
ecryptfs ディレクト 再起動の初回ログインで必ずパスワードが必要
単なる暗号化 ファイル ファイルが増えてくると厄介。ディレクトリは面倒
bitwarden bitwarden 専用サーバーが必要。cli も必要。1passwordなら課金も必要
NFS/Cifs ネットワーク NASサーバーが必要。常時接続が必要。

LUKS の場合

LUKSを解除するために、initramfs が再構成が必要です。initramfs がCryptSetupを使うように構成を変更しなくてはいけません。再起動のたびにパスフレーズの入力が必要です。システム全体を暗号化してしまうので、ロック解除後は通常のLinux操作と同じです。何も意識せずに暗号化のメリットを享受できます。考えることが少なくてすみます。TPMチップがあればロック解除も安心できるのですが。残念ながらRaspiにはプリインストールされていません。モジュールで購入も可能ですが、UKで£32 (≒送料込5000円弱)くらいです。

encrypt-fs の場合

めちゃくちゃ簡単です。驚くくらい簡単に$HOMEを暗号化出来ます。時短には最適。何個かコマンドをコピペするだけで最低限十分な暗号化が手に入ります。

encfs / ecrypt-fsを用いる場合、指定ディレクトリを暗号化出来ます。ecryptfs は/home/usernameを暗号化できます。ただしロック解除時にパスフレーズが必要です。パスフレーズは、通常はログインパスワードと共通にします。ecrypt-fs で $HOMEを暗号化すると、/home/usernameがロックされるので、~/.ssh/authorized_keys が使えません。

 察しの良い読者さんは、保存場所を変えればいいじゃんと思うかもしれません。ところが、そう簡単でもないのです。authorizied_keysの保存場所を変えてログインできたとしても、$HOMEロックされたままですsshログインできても、結局は、homeロック解除にパスフレーズを提供します。じゃあ秘密鍵でロック解除すればいいじゃん!と思うかもしれません。libpam-ssh-agent-authでできはくはないが、そのためには、ssh-agentで秘密鍵転送が必要になります。秘密鍵を提供できたとしても、.bashrcすらロック状態です。ロック状態でそれらのpam設定を行うのは地獄のような気がします。

ecryptfsなら $HOME ロックををLUKSで代替できる。

同じ目的であれば、LUKS+PAMで同等の機能が実現できるらしい。これらのことを考えると、ノートPCにインストールしたUbuntuであればecryptfsにメリットはあるが、パーティションをイジくれるなら、LUKS+ログイン時にロック解除で良いと考えられます。

ecryptfsにはいくつかの制限事項がある。ファイル名が143文字に限定される。スパースファイルが作れないスパースファイルが作れないのは、諦めるとしてもファイル名が長くなるとエラーになるのはちょっと怖い。

なにより、Ubuntuであれば簡単ですが、その他のディストリで苦労が伴います。

公開鍵認証によるSSHログインを諦めなら、encryptfs はいい選択肢だと思います。ただそれでもLUKS+PAMで同じことだと思います。わざわざ暗号化のオーバーヘットを掛ける理由がありません。LUKSをxchachaで行い、encryptfsの代わりにPAMを構成すればい同じことです。手軽さに頼るかどうか。ここが判断基準になると思います。

単なるファイル暗号化 openssl enc -d -pbkdf2 -aes256 -base64

Raspiに設置したファイルを、暗号化しておけば良いかもしれません。openssl enc -d -pbkdf2 -aes256 -base64 のようなOpenSSLのコマンドや、ssh内蔵のssh-keygen -p -f ~/my.ssh.id_rsa コマンドが使えそうです。ファイルが少ないときは良いのですが。ディレクトリまるごと暗号化のような需要に答えるのは苦労が伴います。もし実現するとすれば、たとえばtar ファイルに圧縮しておいて、tar マウント(archivemount my.tgz ~/mnt)方法も考えられますが、更新が頻繁になると、これも面倒です。ファイルが増えてくるとSparseファイルを作ってloopback ブロックデバイスを結局は使うことになるでしょう。なので、これはファイル数の多寡が判断基準になりそうです。多いときはdm-crypt LUKSに行き着きます。

bitwarden / 1password など使う。

cli から利用できるパスワード管理ソフトを使ってその中に機密情報を保存する方法が考えられます。bitwarden には bwというクライアントコマンドがあります。これを使って安全にファイルを暗号化すれば良いのですが。ディレクトリまるごと暗号化では手間が苦痛です。また bitwardenのbwコマンドの公式レポジトリはディスコンされて行き場を失っています。この点からも外部依存するのも考えものです。1passwordなら完成度は高いのですが、値段も高いです。

NFS/cifs マウントを使う

ネットワークをマウントしまえばいいかもしれません。SSHFSやrclone マウントなどの便利な方法もあります。しかいNFSのようなネットワーク接続先への接続情報と認証情報をどうやって管理すれば良いのでしょうか。「振り出しに戻る」です。データを保護するのであればNFS/Cifsで十分でしょう。ただ、/homeを暗号化するような目的を考えるとNFSNISでガチな移動プロファイル環境が必要で手に余ると思います。いまのRaspiberry piはNFSでブート出来るので、ディスクレスにしてしまってNFSで運用も悪くないとは思います。・・・SDカードはすぐ壊れるし。USBメモリもそこまで寿命はないですし。AD/Cifs の移動プロファイルを使うのは悪くないと思いますが、通信経路の保護や認証情報の保持を考えて、サーバを用意するとなるとハードルが高くなりすぎて。

 Google DriveやOneDriveをマウントするのもいいと思います。ログイン時に自動的にリモートのファイルサーバをマウントするのも同じです。systemd-user をつかってログイン時に、ログインパスワードで機密情報を解除してマウントしてしまうのです。この場合は、パスワードをどうやって提供するかが問題になり、ecryptfsと同じく公開鍵認証を用いた場合に設定が煩雑になりそうです。ただスクリプトを組めば手軽になりそう。

pam_mount を使う。

pam_moutを使って、ログイン時に何かをマウントすることも出来ますし、それでも良いと思いますが、ログアウト時にロック解除が動かないそうです

Pam_mount はセッションの終了時にパーティションをアンマウントすることもできますが、pam で使われている pam_systemd.so が原因で今のところ機能しません。

安定性は非常に高いですが,DM 起動前にパスワードが求められるのでタブレットBluetooth キーボードでは解錠ができませんし,ログイン操作との統合もできず,あえてこうする実益があるケースは思いつきません。

PAMをクラウド認証やLDAPと組み合わせる。

GoogleChromebookは2010 の段階でこのような設計になっていたそうです。

昔の大学や高校の情報処理教室ではpamとLDAPとCIFSを組み合わせて、移動プロファイルの代わりに、CIFSマウントを起動時に行っていたらしいです。ここまでの設定を振り切ってやりきってた学校があったのか。非常に驚きです。

個人的な結論

adiantum で暗号化、dm-crypt で LUSKを起動時に dropbear でSSH経由でロック解除で十分じゃん。

自動マウントとか夢だけど、夢にしておこう。

参考資料

Raspberry Pi のルートファイルシステム LVMにしてを ext4 on LVM にする

Raspberry Pi4 はLVMに入れられるのか。

LVMにしておけば、マイクロSDカードが巨大サイズでも困りません。OpenMediaVaultのようなNASサーバーを構築する際もLVMが扱えると便利です。LXC/LXDのような仮想マシンを扱うときもLVMが扱えると管理が楽です。ルートファイルシステムをバックアップとるにしてもスナップショットが扱えるのでLVMが便利です。

準備したもの

  • Raspberry Pi4 8GB(コロナ前に買って放置してたやつ)
  • MicroSDカード128GB ( USB アダプタ経由)
  • MicroSDカード 32GB ( 本体emmcblock )
  • raspi ubuntu

Pi4 8GB は5台買って殆ど使わずに放置してました。ええ勿体ないです。転売すれば儲かってたレベル。

今回は、ubuntu on raspberry pi を用いています。3年前の事情でUbntuです。aarch64環境化では、ubuntu 64bit が便利だった*1ので、随分前にインストールしたまま放置してたものです。

手順

だいたいの手順は次のとおりです。

  • ディスクレイアウトの確認。
  • ラベルの確認。
  • バックアップ
  • クローンの作成
  • パーティションの初期化
  • パーティションレイアウトの作成
  • LVMを作る
  • ブートを作り直す

ディスクの確認

ディスクのレイアウトを確認します。

root@raspi-ubuntu:~# lsblk -f
sda
├─sda1    vfat        FAT32 system-boot FE3E 23.5M    91% /boot/firmware
└─sda2    ext4        1.0   writable    ce2ab978 3.3G    71% /
sdb
├─sdb1    vfat        FAT32 system-boot FE3E
└─sdb2    ext4        1.0   writable    87f67789 

バックアップ

最初にバックアップを取っておきます。

sudo tar cpvf -  --one-file-system /  | ssh takuya@192.168.12.15 'pigz | cat -> raspi-ubuntu.lan.tgz'
sudo tar cpvf -  --one-file-system /boot/firmware  | ssh takuya@192.168.12.15 'pigz | cat -> raspi-ubuntu.boot.firmware.tgz'

--one-file-system については過去記事に書きました

gdisk を用いてパーティション開放と作成

sudo gdisk  /dev/sdb

出来上がったディスクレイアウト

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

LVMを構成する。

sudo pvcreate /dev/sdb2
sudo vgcreate vg.main /dev/sdb2
sudo lvcreate -n root  -L 10G vg.main
sudo mkfs.ext4 /dev/mapper/vg.main-root

ファイルシステムを作る。

ext4 を選択。btrfs でも良かったけどまた今度。

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

ファイルをコピーする

既存のディスクから同期する(raspi-ubuntuの場合)

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

raspi-ubuntuの場合/boot/firmware,raspbian は /boot

同期する(rootファイルシステム同期)

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

--one-file-system が超便利。マウントポイント(dev/mnt)は無視してくれた。

swap が大きいときは邪魔なので退けておいてもいい。

sudo swapoff /swap.img

マウント解除する。

sudo umount /mnt2 
sudo umount /mnt 

initamfs を再構成

chroot で中に入ってinitramfs をリビルドが必要。その準備をしていく。

ここでは、次のことを行う。

  • lvm2 をインストール initramfsをインストール
  • fstab を変更
  • cmdline.txtを変更

dev と proc と sys をマウントしていく。

sudo mkdir -p /mnt/chroot/
sudo mount /dev/mapper/vg.main-root /mnt/chroot/
sudo mount /dev/sdb1 /mnt/chroot/boot/firmware/
sudo mount -t proc none /mnt/chroot/proc/
sudo mount -t sysfs none /mnt/chroot/sys/
sudo mount -o bind /dev /mnt/chroot/dev/
sudo mount -o bind /dev/pts /mnt/chroot/dev/pts/

chroot する

sudo -E LANG=C chroot /mnt/chroot/

ツールをインストールする。

root@chroot :# apt install initramfs-tools lvm2

/etc/fstab を編集する。

root@chroot :#  vim /etc/fstab

cmdline.txt カーネルオプションを書き換える。

cmdline.txt にinitrdを記入するのがコツらしい。

initrd=0x01f00000 

fstabでの指定にはラベルを付けておくと便利。

root@chroot :# tune2fs -L writable /dev/mapper/vg.main-root

ラベルを使ってcmdline.txtはこんな感じに

(略)console=(略) initrd=0x01f00000 root=LABEL=writable  (略)

0x00f00000って何?

config.txt でもいいらしい。でもたぶんいまのRaspberryPi4にはいらないやつかもしれない。

参考資料1と、参考資料2によると、initramfsをメモリにロードした状態を示すんだとか。

This answer helped me to use a UUID for my root file system on a USB drive. I was wondering however what exactly the number (address) in initramfs initrd 0x00f00000 means.

The address 0x00f00000 is the address where the initramfs image is loaded into memory.

USBメモリを入れ替えて実験

全部終わったら、シャットダウンして、USBメモリとSDカード入れ替えて実験。

確認

レインボー画面が表示されて、ブートが始まったらほぼ成功。

再起動の例

sudo lsblk  /dev/sda
NAME               MAJ:MIN RM   SIZE RO TYPE  MOUNTPOINTS
sda                  8:0    0 119.2G  0 disk
├─sda1               8:1    0   512M  0 part  /boot/firmware
└─sda2               8:2    0 118.7G  0 part
    ├─vg.main-root 253:1    0    50G  0 lvm   /
    └─vg.main-swap 253:2    0     2G  0 lvm   [SWAP]

rpi on lvm の参考資料

*1:kvm など仮想マシン環境のサポート面