みつきんのメモ

組み込みエンジニアです。Interface誌で「Yocto Projectではじめる 組み込みLinux開発入門」連載中

YoctoProject dm-verity環境を試す

はじめに

最近はセキュリティ的な需要で、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

このクラスでは主に下記のことを行う。

  1. DM_VERITY_IMAGEで指定されたcore-image-minimalなどのイメージに対応するハッシュデータの作成
  2. ハッシュデータをイメージの末尾に結合した.verityファイルの作成
  3. ハッシュデータを検証するためのルートハッシュを含む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がリードオンリーになるため、書き込み領域が必要な場合は別途実装が必要となる。