UEFIのSecure boot + kdump・kexecの動作確認
uefiのSecure bootが有効な環境でkdump・kexecは動作するのか?ってところの確認です。
Secure bootとは?というところはこちらのドキュメントを参照してください。 access.redhat.com
テスト環境
テスト環境にはlibvirtを使います。ホストはFedora 30 x86_64、ゲストもFedora 30 x86_64です。
テスト環境セットアップ
まずはSecure bootを有効にした環境を作ります。まずは普通にlibvirtを使ってOSをインストールします。 このときに、UEFIを使うように設定します。そのため、edk2-ovmfパッケージをインストールしておく必要があります。
インストール段階だとセキュアブート用のファームウェアは指定できないのでとりあえずはセキュアブートなしでインストールします。
kdumpの設定
インストールが終わったら普通に設定しましょう。
この時点で動作確認もしてkdumpが正常動作することを確認しておきます。
Secure bootの設定
virsh editでxmlファイルを編集します。VMは一旦shutdownしておきましょう。
まず、OVMF_VARS.secboot.fdをコピーします。コピー先の名前はなんでも良いです。ここではvm名と合わせてます。
$ sudo cp /usr/share/edk2/ovmf/OVMF_VARS.secboot.fd /var/lib/libvirt/qemu/nvram/secureboot-test_VARS_secboot.fd
そしたらvirsh editで編集します。以下の部分を探します。
<os> <type arch='x86_64' machine='pc-q35-3.1'>hvm</type> <loader readonly='yes' type='pflash'>/usr/share/edk2/ovmf/OVMF_CODE.fd</loader> <nvram>/var/lib/libvirt/qemu/nvram/secureboot-test_VARS.fd</nvram> <boot dev='hd'/> </os>
そして、以下のように編集します。変更したのはloaderのところでOVMF_CODE.secboot.fdを指定したのと、nvramには先ほどコピーしたファイルを指定しました。
<os> <type arch='x86_64' machine='pc-q35-3.1'>hvm</type> <loader readonly='yes' type='pflash'>/usr/share/edk2/ovmf/OVMF_CODE.secboot.fd</loader> <nvram>/var/lib/libvirt/qemu/nvram/secureboot-test_VARS_secboot.fd</nvram> <boot dev='hd'/> </os>
セキュアブート有効で起動
普通にvmを起動すればセキュアブートが有効な状態で立ち上がります。 dmesgで確認するとこんなふうになります。
[masami@secureboot-test ~]$ dmesg | grep secureboot [ 0.000000] secureboot: Secure boot enabled [ 0.928493] systemd[1]: Set hostname to <secureboot-test>. [ 3.770079] systemd[1]: Set hostname to <secureboot-test>. [masami@secureboot-test ~]$
これでvmのセキュアブートが有効になりました。
kdumpのテスト
セキュアブートが有効な状態でkdumpをスタートすると失敗します。エラーメッセージはこのようになってます。
[masami@secureboot-test ~]$ sudo systemctl status kdump ● kdump.service - Crash recovery kernel arming Loaded: loaded (/usr/lib/systemd/system/kdump.service; enabled; vendor preset: disabled) Active: failed (Result: exit-code) since Fri 2019-08-30 22:29:52 JST; 12s ago Process: 1316 ExecStart=/usr/bin/kdumpctl start (code=exited, status=1/FAILURE) Main PID: 1316 (code=exited, status=1/FAILURE) Aug 30 22:29:51 secureboot-test systemd[1]: Starting Crash recovery kernel arming... Aug 30 22:29:52 secureboot-test kdumpctl[1316]: Secure Boot is enabled. Using kexec file based syscall. Aug 30 22:29:52 secureboot-test kdumpctl[1316]: kexec_file_load failed: Operation not permitted Aug 30 22:29:52 secureboot-test kdumpctl[1316]: kexec: failed to load kdump kernel Aug 30 22:29:52 secureboot-test kdumpctl[1316]: Starting kdump: [FAILED] Aug 30 22:29:52 secureboot-test systemd[1]: kdump.service: Main process exited, code=exited, status=1/FAILURE Aug 30 22:29:52 secureboot-test systemd[1]: kdump.service: Failed with result 'exit-code'. Aug 30 22:29:52 secureboot-test systemd[1]: Failed to start Crash recovery kernel arming.
dmesgでカーネルのエラーを確認するとこのようなメッセージを発見できます。
[ 173.215036] Lockdown: kexec: /proc/kcore is restricted; see man kernel_lockdown.7
カーネルのコンフィグを確認するとLockdown機能が有効になってますね。
[masami@secureboot-test ~]$ grep LOCK_DOWN /boot/config-5.2.9-200.fc30.x86_64 CONFIG_LOCK_DOWN_KERNEL=y # CONFIG_LOCK_DOWN_KERNEL_FORCE is not set CONFIG_LOCK_DOWN_IN_EFI_SECURE_BOOT=y
Lockdownの解除
手元にmanがなかったので検索するとこちらが見つかりました。
manによると物理的に接続されたキーボードからのsysrq + xでlockdownが解除できるとあります。というわけで、virsh send-keyでsysrq + xを送ります。
$ sudo virsh send-key secureboot-test KEY_LEFTALT KEY_SYSRQ KEY_X
そうすると以下のようにlockdownを解除したよってメッセージがでます。
[masami@secureboot-test ~]$ dmesg [ 2236.328389] sysrq: Disabling Secure Boot restrictions [ 2236.328934] Lifting lockdown
kdumpのテスト
まずセキュアブートが有効か確認します。
[masami@secureboot-test ~]$ sudo mokutil --sb-state SecureBoot enabled [masami@secureboot-test ~]$
で、kdumpを起動
[masami@secureboot-test ~]$ sudo systemctl start kdump
エラーが出なければOKなので、クラッシュさせてみると /var/crash/に該当時刻のディレクトリが出来ていてコアダンプが取得できてるのが確認できます😃
[masami@secureboot-test ~]$ sudo sh -c "echo c > /proc/sysrq-trigger" client_loop: send disconnect: Broken pipe masami@moon:~$ ssh secureboot-fedora Web console: https://secureboot-test:9090/ or https://192.168.122.191:9090/ Last login: Fri Aug 30 22:58:25 2019 from 192.168.122.1 [masami@secureboot-test ~]$ ls /var/crash/ 127.0.0.1-2019-08-30-01:05:24 127.0.0.1-2019-08-30-23:38:24 [masami@secureboot-test ~]$ date Fri 30 Aug 2019 11:38:53 PM JST [masami@secureboot-test ~]$
まとめ
セキュアブートが有効な環境でもkdump・kexecは使えますが、カーネルのLockdown機能が有効な場合は使えません。もしkdump・kexecを使用したい場合はLockdownを止める必要があるということでした。
追記1 2019/08/31
kexecとセキュアブート
セキュアブートが有効な場合と無効な場合ではkexec実行時のオプションがちょっと違います。では具体的に何が違うのか?というとセキュアブートが有効な場合は-sオプションを使います。 Fedoraの場合はkdumpctlコマンドがこの辺の処理をしていて、以下のようなコードとなってます。
# For secureboot enabled machines, use new kexec file based syscall. # Old syscall will always fail as it does not have capability to # to kernel signature verification. if is_secure_boot_enforced; then echo "Secure Boot is enabled. Using kexec file based syscall." KEXEC_ARGS="$KEXEC_ARGS -s" fi $KEXEC $KEXEC_ARGS $standard_kexec_args \ --command-line="$KDUMP_COMMANDLINE" \ --initrd=$TARGET_INITRD $kdump_kernel if [ $? == 0 ]; then echo "kexec: loaded kdump kernel" return 0 else echo "kexec: failed to load kdump kernel" >&2 return 1 fi
セキュアブートが有効な場合は-sオプション付けて使用するシステムコールを変える必要があります。
超例解Linuxカーネルプログラミング~最先端Linuxカーネルの修正コードから学ぶソフトウェア品質~
- 作者: 平田豊
- 出版社/メーカー: シーアンドアールケンキュウジョ
- 発売日: 2019/07/18
- メディア: 単行本(ソフトカバー)
- この商品を含むブログを見る