ようこそ。

鷹足です。このブログでは、学校でのことやコンピュータ関係のことを書くと思いますが、どうぞよろしくお願いします。

2016年12月13日火曜日

GRUB2のデジタル署名機能を使ってみる

※この記事は、自分の備忘です。あなたの参考になるかもしれませんが、ならないかもしれません。ここに書いた手段を実行する場合、あくまで自己責任で、お願いします。最悪の場合、コンピューターを起動できなくなるおそれがあります。十分気を付けて、備えをしてから臨みましょう。

GRUB2のデジタル署名検証機能


Linuxでは最近ひろくつかわれているブートローダーのGRUB2ですが、どうやら、読み込むファイルのデジタル署名検証機能もついている様子。おそらく、UEFIの機能であるセキュアブートと組み合わせることで、OSに制御が移る前に不正なソフトウェアが実行されることを防ぐことを意図しているようですね。
私のLinuxが入ったノートパソコンは、そもそもBIOSベースのシステムなのでセキュアブートなどは当然できないわけですが、とりあえずこの機能をテストしてみました。

デジタル署名検証機能でできること(たぶん)


ブートローダーに処理が移譲されて以降の、デジタル署名されていないファイルの読み込みを抑止すること。
ご存じのとおり、BIOS/MBRディスクという構成では、BIOSからMBRへ処理が移されるのを始まりとして、各種ブートローダーへ処理が移譲されます。また、UEFI/GPTなシステムでは、NVRAMに登録されたブートレコードに従って、ファームウェアからEFI system partitionに設置されたEFIバイナリへと処理が移譲されていきます。
この機能が有効になっているGRUB2は、自らに処理が移譲されて以降の改竄されたファイルの読み込み等を抑止します。
したがって、BIOSやUEFIファームウェアが、改竄された/悪意のある(GRUBとは別の)ローダーを読み込むことまでは抑止できません(当たり前か…)。そのへんは、UEFIではセキュアブートのお仕事ですね。

やってみた環境


gentoo linux
/bootのみを分割したパーティション構成
GRUB2 バージョン2.02 beta3
GPG バージョン2.1.15


手順


ブートローダーをいじる作業です。設定を間違うと、起動できなくなることがあります。
有効にする場合、作業は慎重に行いましょう。ブログの注意書きにも書いておきましたが、作業は自己責任で! 
(私自身、当初GRUB2を起動できなくなりました。GRUB以外で起動できるツールを用意しておくことも大事です。)
また、試行錯誤した結果ですので、なにか抜けがあるやもしれません。あてにしすぎないでください。
なにはともかく、GRUB2のinfoをまずは読みましょう。

以下のコマンドは、原則としてroot権限で(sudoなど)で実行しました。

とりあえず鍵を作る


GRUBの署名は、GPGで生成できます。まずは、署名に使う鍵を作りました。
gpg --gen-key
…でもいいのかもしれませんが、私は
gpg --full-gen-key
で、詳細設定をしてみました。鍵の種類と鍵長、有効期間の入力を求められます。私は、署名のみの用途のRSA 2048bitを選びました。まあ、テスト用としては十分な暗号強度でしょう。期間も、まあ適当に。

続いて、証明書に使うフィールド(名前、メールアドレスなど)を入力します。たぶん、ここの内容はなんでもよいと思われるので、自分で識別しやすい名前を付けておきます。

乱数生成中は、適当にマウスを動かしたり、キーボードで文字を打ったり、ディスクアクセスを生じさせたりするとよいようですね。

終わったら、
gpg -k
で、鍵一覧の確認。

署名


基本的には、
gpg --detach-sign <ファイル名>
で、<ファイル名.sig>に署名ができるようです。-uオプションでユーザーIDを指定して署名が行えるようですね(試してない)。
鍵が複数ある場合はこれで鍵を指定すればいいんでしょうか。

さて、しかしながら、GRUBの読み込むファイルを全部指定するのは大変です。そこで、署名を一括で行うツール(スクリプト)が開発されています。今回はこれを使わせてもらいました。

https://github.com/Bandie/grub2-signing-extension

 gpg2.1の環境では、異なるブランチが用意されているようです。適切な方を使いましょう。なお、これのREADMEは、GRUB2で書名機能を有効にする手段がわかりやすく解説されていました。これも読むといいですね。

上のツールをcloneするなりダウンロードするなりしたら、make installします。(私は、インストール先を/usr/local/sbinにするべく、Makefileを書き換えました。)

また、署名の検証に使うための鍵(公開鍵)をエクスポートしました。
gpg --export > boot.key
このファイルを、(とりあえずはテスト目的なので)/bootディレクトリにおいておきます。

ここまで出来たら、GRUB2の設定ファイルを書き換えて、署名の検証を有効にします。私の環境(gentoo linux)では、/etc/grub.d/以下に、/boot/grub/grub.cfgを生成するための情報があります。ここの40_custom(独自のメニューエントリを追加するためのファイル)をコピーして書き換えます。このファイルは、中身がそのまま/boot/grub/grub.cfgに転記されるので、ここに
insmod gcry_sha256
insmod gcry_rsa
insmod verify
trust /boot.key
set check_signatures=enforce
 と書き込みます。

最初の3つのinsmodは、署名の検証に必要なモジュールを読み込む命令です。
続いて、trustで、先ほどエクスポートした鍵を指定します。この鍵を使って、GRUBのファイルやカーネルイメージに施した署名を検証するわけです。
最後に、変数を設定して、署名検証の機能を有効化しています。

(ちなみに、私は、必要なモジュールをロードしていなかったせいで当初GRUB2が起動できなくなり、再起動を繰り返すようになりました。私の場合、上記3つのモジュールで足りたようですが、環境あるいは鍵の種類等によって変わるかもしれません。ここの設定を間違えると起動不可能になる恐れがあるのでご注意を。)

いつものように、
grub2-mkconfig -o /boot/grub/grub.cfg
のようにして、 設定ファイルを適用させます。

これでファイルが揃ったので、いよいよ署名。
grub2-sign
を実行します。

(なお、テーマを使っている場合、pngファイル、theme.txtなどが署名されないため、エラーが表示されました。手動で行うか、grub2-signスクリプトを編集してパターンに追加しましょう。私の場合、これらのほか、kernelイメージ、initrdのファイル名についても改良する必要がありました。)

(また、grub2-mkconfigは、署名が含まれる.sigファイルもkernelやinitrdと誤認してしまうようです。/etc/grub.d/10_linuxにif文を追加するなど適宜書き換えるといいかもしれません。参照: https://www.coreboot.org/GRUB2#Security)

念のため、
grub2-verify
で、署名を検証し、また、/bootディレクトリの中身を見て、主なファイルについて、<ファイル名>.sigというファイルがあるかどうか確認。

okなら、リブートしてみる。

 エラーが出ずにブートできれば成功。エラーが出たら、それに合わせて修正。

私の場合、
  • まず、/boot.keyがないと怒られる→/boot/grubではなく/bootに鍵ファイルを置く
  • hash sha256がうんたら→modinst gcry_sha256を設定に追加
  • GRUB2が起動しない→modinst verifyとmodinst gcry_rsaを追加
  • テーマが適用されない→/boot/grub/theme/<テーマ名>以下のpngファイルとtheme.txtに署名
といった試行錯誤をしたところ、なんとか起動できるようになりました。(なお、設定ファイルを変更したら、grub2-mkconfig、ggrub.cfg.sigの削除、gpg --detach-sign /boot/grub/grub.cfgするのを忘れずに。)

トラブルが起きた場合


GRUB自体は起動するようなら、エンターキーを押すなどしてブートエントリを選択する画面までいき、キーボードの「c」を押しましょう。そうすると、コンソールが開くはずです。そうしたら、以下のコマンドを打ち込んで、署名検証機能を無効にします。
set check_signature=no
続いて、エスケープキーを押し、メニュー画面に戻ったら、通常通りブートができるはずです。たぶん。

これもできない場合には、(あれば)他のブートローダー、あるいはブータブルメディアなどを使ってなんとかブートするしかありません。

また、署名については、/bootディレクトリ内の*.sigファイルを削除することで除去できます。くれぐれも、必要なファイルを消さないよう、ご注意あれ。

結果

署名がないファイルについては、読み込みを拒否するようになりました。一応、所期の目的は果たせた、ということで。しかし、背景やUIの要素となるpngファイルやテーマを記述したテキストファイルも対象とは、徹底してますね。

なお、鍵については、GRUB2のcore.imgに埋め込んだほうが安全かもしれません。たぶん、そうしないと、設定ファイルを読み込む際は検証がされてないはずです。grub-installなどに、これを設定するためのオプションがあります。

もっとも、これだけでは、他のブートローダーを仕込むような手法についてはカバーできません。そうしたものへの対策については、 セキュアブートを試してみたいところですね。(対応するコンピューターを持っていないので試せていないのです)

さらに、コンソールが起動されてしまえば、上記のように、check_signature変数を変更することにより署名は無効化されてしまいます。これへの対策としては、GRUBにパスワードを設定する方法がよいかと思います。

 このように、他にも検討すべき点はたくあんありますが、今回は目的の機能を有効化できた、ということでこのあたりで筆をおきたいと思います。

0 件のコメント:

コメントを投稿