はじめに
最近はセキュリティ的な需要で、YoctoProjectを使用した環境でもルートFSをdm-veirtyで検証したいという要望を聞くようになった。
meta-securityを使用することで、dm-verityを使用したルートFSの検証を実装することができる。 恐らく、もっとも簡単に実行可能な環境を作成するにはmeta-securityのkasディレクトリに格納されている「kas-security-dm.yml」を使用することである。
kasについて
kasについてはYocto meta-raspberrypi環境の作成にkasを使ってみるで解説している。
ビルド環境の構築
今回はkasを使用するので、明示的に取得する環境はmeta-securityのみとなる。
作業ディレクトリ
作業ディレクトリは~/yocto/kas-security
とする。
$ mkdir -p ~/yocto/kas-security $ cd ~/yocto/kas-security
meta-securityの取得
$ git clone git://git.yoctoproject.org/meta-security
ビルド用のベース環境を構築
kasを使用してビルド用のベースとなる環境を構築する。
$ kas checkout ./meta-security/kas/kas-security-dm.yml
kasの実行
kasを使用してビルドを実行する。コマンドはビルドディレクトリではなく~/yocto/kas-security
で実行する。
$ kas build ./meta-security/kas/kas-security-dm.yml
動作確認
普通にqemuを実行
普通に実行してみる。
$ source ./poky/oe-init-build-env $ runqemu nographic
下記のように「Device /dev/vda is not a valid VERITY device.」となり、ルートFSのデバイスとなる/dev/vda
が正しいVERITYデバイスではないというエラーになる。
...(snip)... realpath: /dev/disk/by-partuuid//dev/vda: No such file or directory Device /dev/vda is not a valid VERITY device. [ 4.375051] /dev/mapper/rootfs: Can't open blockdev mount: /rootfs: special device /dev/mapper/rootfs does not exist. ...(snip)...
正しいverityデバイスを指定
$ source ./poky/oe-init-build-env #設定済みであれば不要 $ runqemu nographic ./tmp/deploy/images/qemux86-64/core-image-minimal-qemux86-64.ext4.verity
実行結果
...(snip)... Poky (Yocto Project Reference Distro) 4.1+snapshot-fb1853c66ce901d03a45f6dbef549b66bb94279d qemux86-64 /dev/ttyS0 qemux86-64 login: root root@qemux86-64:~# mount | grep 'on / ' /dev/mapper/rootfs on / type ext4 (ro,relatime)
ログイン可能となっており、/dev/mapper/rootfs
が/
としてマウントされている。
meta-securityが提供するdm-verityの機能
必要パッケージのレシピなどを除いて、meta-securityでは次のdm-veirtyの機能を提供している。
- dm-verity-img.bbclass
- dm-verity-image-initramfs.bb
dm-verity-img.bbclass
このクラスでは主に下記のことを行う。
DM_VERITY_IMAGE
で指定されたcore-image-minimal
などのイメージに対応するハッシュデータの作成- ハッシュデータをイメージの末尾に結合した
.verity
ファイルの作成 - ハッシュデータを検証するためのルートハッシュを含むenvファイルの作成
このクラスはconfファイルなどで、IMAGE_CLASSES += "dm-verity-img"
された場合に自動的にinheritされるため、直接inheritしない。
普通にrunqemuした際に、ルートFSが「Device /dev/vda is not a valid VERITY device.」とエラーになったのは、 1と2の作用によるものとなっている。
このクラスの機能は、dm-verityによる検証に必要なデータを作成するためのもので、検証する機能は含まれていない。
3で作成されるenvファイルにはルートハッシュなどが含まれている。このファイルが自由に参照されてしまうと dm-verityでの検証は意味をなさなくなってしまうため、このファイル自体に署名などを行いセキュリティチェックを行うか、 安全なストレージに格納される必要がある。
dm-verity-image-initramfs.bb
このレシピでは、dm-verity-img.bbclassで作成されたenvファイルをinitramfsイメージに取り込み、 ルートFSのマウント時にinitramfs上で検証するという機能を提供する。
実際に検証を行うのは、initramfs-module-dmverityで提供される80-dmverity
となっている。
検証用スクリプトを入れるだけであれば、core-image-minimal-initramfsにinitramfs-module-dmverityすれば行けそうであるが、
envファイルをinitramfsに取り込む処理は別途実装する必要が出てくるので、dm-verity-image-initramfsを使用するほうが無難そう。
また、80-dmverityはルートファイルシステムをリードオンリーでマウントするため、書き込み領域が必要であれば、 overlayfsなどを使用して別途実装する必要がある。
このinitramfsではenvファイルに対して署名検証などは行っていないため、実践的な環境で使うためにはenvファイルへの署名検証のプロセスを追加するか、このinitramfs自体を何らかの形で署名検証しセキュアにする必要がある。
まとめ
YoctoProjectでルートFSをdm-verityする方法としてmeta-securityを紹介した。 qemu環境とはなるが、簡単に実行可能な環境を作成する方法としてkas-security-dm.ymlを使用するというものがある。 実践的な環境でこれらの機能を使用するためには、dm-verity-img.bbclassは問題なく使用可能であると思うが、 envファイルの管理上の問題からdm-verity-image-initramfs.bbはそのまま使用する場合は、initramfsを他の何らかの仕組みでセキュアに保つ必要がありそうだ。 また、ルートFSがリードオンリーになるため、書き込み領域が必要な場合は別途実装が必要となる。