openSUSE:UEFI
UEFI について
UEFI 標準とは
UEFI (Unified Extensible Firmware Interface; 統合型拡張ファームウェアインターフェイス) とは、システムの起動前に必要な様々なインターフェイスを提供するための新しい工業規格です。 UEFI はシステムの電源が投入され、オペレーティングシステムが完全に読み込まれた後もシステムを制御します。また、 UEFI はシステムやオペレーティングシステムが提供する様々な資源間に対して、インターフェイスを提供する責任も負っています。
言い換えれば、 UEFI は古い BIOS ファームウェアを置き換え、拡張するための仕組みです。
UEFI はそれほど新しい仕組みではありません。 Intel 社は 1990 年中盤より EFI/UEFI の作業を開始し、 HP 社や Apple 社など、ずっと以前より EFI マシンを提供している製造元があります。ですが、 Microsoft がマシンに対して Windows 8 の認証を付与するにあたり、 UEFI を必須としたことにより、知られるようになりました。
UEFI 仕様 (http://www.uefi.org/specs/) は長い文書で、ファームウェアの製造元が提供しなければならず、オペレーティングシステムからアクセスできるべきすべてのインターフェイスや変数、構造体などを含んでいます。 Linux では GRUB や elilo を使用することで、 2000 年以降のリリースのものは EFI に対応しています。事実、 openSUSE 12.2 には UEFI のサポートが含まれていて、 openSUSE 12.3 では Secure Boot 拡張に実験的ながらサポートを提供しています。
Secure Boot は UEFI の拡張です。 UEFI はその仕組み上、拡張を行うことができます。 UEFI にはアーキテクチャに依存しない内蔵の仮想マシンが用意され、それを使用して拡張する仕組みです。 UEFI 標準では、その仮想マシン向けにコンパイルされた特別なバイナリファイル (EFI バイナリ) を、その環境下で実行できるようになっています。これらのバイナリは UEFI に対するデバイスドライバのほか、アプリケーションや拡張という形で動作させることができます。また UEFI は、ある意味マシン内で動作する小さなオペレーティングシステムのようなもので、マシンが起動するとすぐに動作し、他のオペレーティングシステムを見つけてそれを実行するまでを主な作業としているといえます。
UEFI マシンかどうかを判別したい場合は、通常ファームウェア設定ユーティリティを使用します。マシンの起動時に F1 (または ESC など、お使いのマシンによって異なります) を押してユーティリティを起動してください。メニュー内に "レガシーモード" ("Legacy mode"; 古い BIOS のモード) や EFI モード、もしくはハイブリッドモードなどの表示があれば、 UEFI に対応しているものと判断できます。なお、どのモードを設定する必要があるのかは、読み込むオペレーティングシステムによって異なります。
お使いのマシンが UEFI に対応していない状況で openSUSE の新技術を試してみたい場合は、 QEMU と Intel の UEFI 参照実装を利用する方法があります: QEMU を利用した UEFI Secure Boot
GPT
UEFI はファームウエアやシステムコール、インターフェイスの変更だけを行ったわけではありません。ハードディスクに対する新しいパーティション仕様を提案しています。 GUID Partitioning Table (GPT) は、古い Master Boot Record (MBR) 形式を置き換える目的で作成されたものです。
MBR にはいくつかの重要な上限があります。たとえばプライマリパーティションや論理パーティションの数に制限があるほか、これらのパーティションのサイズにも上限があります。 GPT ではそのような問題を解決し、任意の数 (128 個まで) のパーティションを作成することができるほか、 2^64 バイト (エクサバイト単位) までディスク領域を拡大することができます。このような事情から、巨大なディスクをお持ちの場合には非常に有用な仕組みです。また、大きな違いとして、 GPT は各パーティションをユニークな UUID 番号で識別します。これにより、パーティションの識別を誤ってしまうことがないようになっています。
YaST はお使いのマシンが EFI モードで動作していることを検出すると、新規のインストールでは GPT パーティションを作成しようとします。 GPT パーティションがいったん作成できるし、古い fdisk ではパーティションの作成や削除、編集などを行うことができなくなります。 gdisk, gptfdisk パッケージなどで提供される新しいツールをお使いください。これらのインターフェイスは fdisk のツールとほぼ同じです。
場合によっては、テストや実験などの目的で異なるモード (GPT 形式から MBR 形式に) に切り替えたい場合があります。この作業も YaST2 で行うことができます。これを行うには、熟練者向けパーティション設定で対象のハードディスクを選択して、 "熟練者向け機能..." -> "新しいパーティションテーブルの作成" を選んでください。
警告!
|
新しくパーティションテーブルを作成すると、そこに今まで存在していたパーティションとデータを壊してしまいます! 下記に示す手順を実行する際は、必ず事前に対象のデータをバックアップしておいてください! |
これによりパーティションテーブルが再作成されます。
EFI システムパーティション
EFI システムパーティション (ESP) は UEFI がプログラムを検索する際に使用するパーティションで、マシンにインストールされたすべてのオペレーティングシステムを起動する際に使用するためのものです。また、 EFI はこのパーティション内に、起動時に必要なデバイスドライバを保存したり、オペレーティングシステムを起動する前に実行する必要のあるツールを保存したりすることがあります。
このパーティションは FAT ファイルシステムを利用しているため、 YaST2 の新規インストールの際にも作成することができます。また、デュアルブートのマシンであれば、すでにあるパーティションをそのまま利用することもできます。このような仕組みにより、 Windows が既にインストールされている環境であれば、 YaST2 は EFI パーティションを自動的に検出し、 openSUSE を読み込むための EFI ブートローダを配置して、そのパーティションを /boot/efi 以下にマウントするようになっています。
既定では、オペレーティングシステムを起動する際、ファームウエアは /EFI/BOOT/bootx64.efi を拡張として読み込みます。 Windows マシンの場合、正しい拡張は /EFI/Microsoft/Boot/BCD.efi で、 openSUSE の場合は /EFI/opensuse/grubx64.efi (Secure Boot が有効化されている環境では shim.efi) になっています。
ブートマネージャ
オペレーティングシステムを読み込むための正しい拡張を読み込む目的で、 EFI には内蔵のブートマネージャが用意されています。また、オペレーティングシステムは、自分自身を読み込むための新しい項目を作成する際、自分で処理を行う必要があります。ブートマネージャを起動して起動項目のすべてを表示させたい場合は、システムの電源を投入した後に F9 または F12 (マシンによって異なります。それ以外の場合もあります) を押してください。 efibootmgr ツールを利用して、項目を問い合わせたり編集したりすることもできます。たとえば現在の項目を一覧表示したい場合は。 efibootmgr -v のように実行します。
上記のスクリーンショットでは、 openSUSE が 2 種類の項目を作成しています。 1 つは Secure Boot に対応したモードで、もう 1 つはそれ以外で使用するモードです。
何らかの理由で項目を削除してしまった場合は、 efibootmgr を利用して再作成することができます。たとえば 'opensuse' という項目を再作成するには、下記のようにして行います:
EFI 変数
UEFI 標準では、ファームウエアの不揮発性メモリ内に変数を保存する機能を定義しています。これらの変数は、情報の保存に使用することができるほか、 UEFI システムの動作を制御したりする目的でも使用することができます。ブートマネージャで新しい項目を作成したり、 Secure Boot のオプションを有効または無効に設定したりすることで、これらの変数の値を変更したことになります。
これらの UEFI 変数は、 openSUSE の sysfs を介してアクセスすることができます。 sysfs はカーネルが提供する仮想的なファイルシステムで、いくつかの内部的な情報をユーザスペース側に提供することができる仕組みです。 UEFI 変数は sysfs の '/sys/firmware/efi/vars/' ディレクトリに公開されています。たとえば、ブートローダで最後に起動した項目を表示するには、下記のように実行します:
Secure Boot
背景
UEFI Secure Boot は、システムの起動にあたって、実行できるバイナリを制限するための仕組みです。ファームウエアは、既知の署名者が電子的に署名したブートローダだけを実行します。 Secure Boot では、 X.509 証明書を利用して、バイナリの識別を実施しています。
今日の消費者向け PC ハードウエアでは Secure Boot が有効化され、 Windows 8 が同梱されています。そのため、ファームウエアには Microsoft がブートローダに署名する際の情報のみが記録されています。署名の発行者の一覧を再設定することなく、かつ Secure Boot を無効にすることなく openSUSE を起動できるようにするには、 openSUSE のブートローダを Microsoft に署名してもらわなければなりません。
openSUSE 12.3 における実装
openSUSE 12.3 で既定で使用されるブートローダは、 grub2 です。 Secure Boot モードの場合、追加のブートローダである 'shim' も使用します。 grub2 を直接実行する代わりに、ファームウエアは 'shim' と呼ばれるローダを読み込みます。 'shim' にはファームウエアで識別してもらうための Microsoft の署名があります。 'shim' は openSUSE の署名を知っているため、 'shim' から grub2 を実行することができるようになっています。これにより grub2 は、同様に openSUSE の署名が設定されている Linux カーネルを読み込んで実行することができるようになっています。 Linux カーネルが起動することで、 Secure Boot としての処理は終わりになります。 openSUSE で利用している Linux カーネルには、特段の制限はありません。
独自のブートローダやカーネルを起動したい場合に備えて、 shim には独自の署名取り込み機能が用意されています。これを行うには、 'MokManager' を利用してください。 'shim' に対して既知でない者が署名したバイナリを読み込むよう指示した場合は、 MokManager を呼び出してデータベース内に証明書を取り込み、既知の署名者とするようになっています。
Secure Boot サポートを有効/無効にする方法
openSUSE 12.3 における Secure Boot のサポートは実験的なものとして位置づけられています。インストールプログラムである YaST は、 Secure Boot が有効化されているかどうかを自動的に判断することができません。インストールの際に Secure Boot サポートを有効にするかどうかを選択することができますので、必要に応じて有効化してください。この機能を有効化した場合は、 shim オプションもインストールする必要があります。 Secure Boot のサポートの有効化/無効化は、 YaST モジュールを利用してインストール後に実施することもできます。
Secure Boot が有効化されているかどうかを判断する方法
お使いのマシンで Secure Boot が有効化されているかどうかを確認するには、 Linux から下記のコマンドを root で実行してください:
'1
' が表示されれば Secure Boot が有効化されています。ただし、古いファームウエアでは、 Secure Boot が有効化されていても '0
' を表示してしまう場合もあることに注意してください。
独自のカーネルの起動
Secure Boot は、独自にコンパイルしたカーネルを起動できないようにする仕組みではありません。自分の証明書で署名したあと、その証明書の発行者をファームウエアか MOK にインストールすることで、解決することができます。
- 署名に使用する独自の X.509 鍵と証明書を作成する: openssl req -new -x509 -newkey rsa:2048 -sha256 -keyout key.asc -out cert.pem -nodes -days 666 -subj "/CN=$USER/"
- 鍵と証明書を PKCS#12 形式にパッケージ化する: openssl pkcs12 -export -inkey key.asc -in cert.pem -name kernel_cert -out cert.p12
- pesign で使用する NSS データベースを生成する: certutil -d . -N
- NSS データベース内に PKCS#12 に含まれる鍵と証明書を取り込む: pk12util -d . -i cert.p12
- カーネルを新しい証明書で署名する: pesign -n . -c kernel_cert -i arch/x86/boot/bzImage -o vmlinuz.signed -s
- カーネルイメージに含まれる署名を一覧表示する: pesign -n . -S -i vmlinuz.signed
あとは通常通り、 /boot ディレクトリ内にカーネルをインストールすることができます。カーネルには独自の証明書による署名が設定されているため、これをファームウエアか MOK に取り込む必要があります。
- UEFI ファームウエアまたは MOK に取り込むため、証明書を DER 形式に変換する: openssl x509 -in cert.pem -outform der -out cert.der
- 簡単にアクセスできるよう、 ESP に証明書をコピーする: sudo cp cert.der /boot/efi/
残念ながら、 openSUSE 12.3 における mokutil
はうまく動作しないため、 MOK を自動的に起動するような簡単な方法はありません。 MOK を起動するには、下記の手順を実施してください。
- システムを再起動します。
- grub のメニューが表示されたら、 'c' キーを押します。
- 下記のように入力します (ESP が 'hd0' の 'gpt1' にある場合の例です): chainloader (hd0,gpt1)/EFI/opensuse/MokManager.efi
boot
- "Enroll key from disk" を選択します。
- cert.der ファイルを選んで enter を押します。
- あとは鍵を取り込むための手順に従います。通常は '0' を押してから 'y' を押すことで、取り込みを行うことができます。
上記以外にも、ファームウエア側で新しい鍵を 'db' に取り込む機能を用意している場合もあります。
Tumbleweed カーネルの起動
Tumbleweed リポジトリが提供するカーネルは標準の openSUSE の証明書で署名されておらず、 Tumbleweed プロジェクトの証明書で署名されています。
このカーネルを起動したい場合は、まず pesign -n . -r -u 0 -i vmlinuz -o vmlinuz.unsigned
コマンドで既存のバイナリから署名を削除したあと、上述の手順で署名を再設定してください。
なお、新しいカーネルがインストールされるたびに、上記の手順を繰り返さなければなりません。
それ以外にも、 Tumbleweed プロジェクトの鍵を MOK に取り込み、提供されるカーネルをそのまま使用する方法もあります。ただし、署名済みの証明書を取得するには openSUSE Build Service のアカウント (またはその他の SUSE アカウント) が必要です。 SSL の証明書は PEM 形式で、 https://api.opensuse.org/source/openSUSE:Tumbleweed/_project/_sslcert?meta=1 にアクセスすることで取得することができます。ユーザ名とパスワードを尋ねられたら、それぞれ SUSE のアカウント情報を入力してください。あとは上述の手順で証明書を DER 形式に変換し、 MOK に取り込めば作業は完了です。
現時点での (2014 年 6 月 23 日現在) の Tumbleweed の証明書は、下記の通りです:
-----BEGIN CERTIFICATE----- MIIDujCCAqKgAwIBAgIJAMk7ZhLBbXDnMA0GCSqGSIb3DQEBCwUAMGExKDAmBgNV BAMMH29wZW5TVVNFOlR1bWJsZXdlZWQgT0JTIFByb2plY3QxNTAzBgkqhkiG9w0B CQEWJm9wZW5TVVNFOlR1bWJsZXdlZWRAYnVpbGQub3BlbnN1c2Uub3JnMB4XDTEz MDIxODE3MTAzN1oXDTE1MDQzMDE3MTAzN1owYTEoMCYGA1UEAwwfb3BlblNVU0U6 VHVtYmxld2VlZCBPQlMgUHJvamVjdDE1MDMGCSqGSIb3DQEJARYmb3BlblNVU0U6 VHVtYmxld2VlZEBidWlsZC5vcGVuc3VzZS5vcmcwggEiMA0GCSqGSIb3DQEBAQUA A4IBDwAwggEKAoIBAQDdyvze0Q5FQ6tARNmm5LJOT8q6OvpuXAj/b2xZjpy/7yzp Kb09b43xPs+c3c9ItKfWF62RyLZnT3freN3nq2G8tj1SzybBc4fcIQ4ngN5/vAC2 2u1czjo8vUb5mzde8HnuRLog4JeXmOrZvOlRWmt7jd4NYCkpZOlsDbrSDd2cUmS2 ROixthA588432UjaCP5v77yKDCijvJUg+1dwz84qvhkgd84CMzGHQgMZGVMA6Eo7 MOuFrBjv26lD4CSIacARamqDyoZRkBDaV48bj8/xONBIjLRhPziVNPJJi+YSOUsL oRzX53myjguTDTwsVS2bZdwLnP1wr1vdf5qAi6ZjAgMBAAGjdTBzMAwGA1UdEwEB /wQCMAAwHQYDVR0OBBYEFGszE3ufhxeDqUdv1sfxNQhB91AUMB8GA1UdIwQYMBaA FGszE3ufhxeDqUdv1sfxNQhB91AUMA4GA1UdDwEB/wQEAwIHgDATBgNVHSUEDDAK BggrBgEFBQcDAzANBgkqhkiG9w0BAQsFAAOCAQEAhSn8TDl8Rm2P6PomDFCQ6gP+ BvXz4HtrRqlFNWlcm+4hw1jHE1/K6uUN6pSf0sRKCVAjNj3G0IzGeovDCG2KaUfK RYAkqfT6kG6suIKsIbgDjwXeaRDOtP1Vgs/CMVoUQo3LoDASMXba8gSQ4/7j6CNe /Wf8jEfjYi7BQARJiKdnokAG36F352HnozigrEXqHvv05BcaUI0WiaoCGVvGGzy/ q9lezSXNZMt0EF4UoYiwVSFdyss8SPeUW3IjZAOA74Akbygh0aGKxf1X33aNtqZp MIdgoMhEkJmOJj4IZ47U8S0HjMwthFc6JY2RilNNfXjMxcHAtVPm9LwrWIwx5A== -----END CERTIFICATE-----
製造元が提供する鍵を利用せずにマシンを起動する方法
ファームウエアのメニューに Secure Boot で使用する鍵をリセットする機能が用意されている場合、 Microsoft の鍵をインストールせずに新しい PK や KE, データベースをインストールすることができるかもしれません。この場合、 openSUSE のカーネルを起動できるようにするには、 /usr/lib64/efi/shim-opensuse.der をデータベースに取り込みます。既定の shim は Microsoft と openSUSE の両方の署名が設定されています。ファームウエアによっては 2 種類の証明書を受け入れない場合がありますが、このような場合は /boot/efi/EFI/opensuse/shim.efi として openSUSE の署名のみが設定されている /usr/lib64/efi/shim-opensuse.efi をインストールしてください。
製造元が提供する鍵で署名されたもののみに対応しているマシンの場合
ファームウエアによっては、 EFI イメージ内に複数個の署名がされている場合、処理ができなくなってしまうものがあります。この場合、既定の shim ではうまく動作しません。ファームウエアメニューに新しい鍵の取り込みオプションも用意されていない場合、 openSUSE の署名のほうを手作業で削除しなければなりません。
- mozilla-nss-tools と pesign の各パッケージをインストールする: zypper install mozilla-nss-tools pesign
- 一時的な NSS データベースを作成する: mkdir certdb
certutil -N -d certdb
(press "Enter" to ignore the password request)
- openSUSE の署名を削除する: pesign -n certdb/ -r -i /usr/lib64/efi/shim.efi -o shim.efi -u 1
- 既定の shim.efi を新しく作成した shim.efi に置き換える: mv shim.efi /boot/efi/EFI/opensuse/shim.efi
- 一時的な NSS データベースを削除する: rm -rf certdb
上記の手順は、 shim が更新されるたびに実施しなければなりません。
このような種類のファームウエアは、 edk2 アップストリーム側で複数署名に対応して何年も経過していることから、年々少なくはなってきていますが、古いマシンでは発生する可能性があります。
用語
- PK
- "Platform Key" (プラットフォーム鍵) - 一般的には、ハードウエアの製造元がマシンにインストールした証明書のこと。 KEK を変更するには、正しい PK の署名が必要となる。
- KEK
- "Key Exchange Key" (鍵交換鍵) - 署名データベースを更新する際、 "鍵交換鍵" の正しい署名が必要となる。
- db
- 署名データベース (db) には、既知の証明書や署名、バイナリのハッシュが含まれる。ファームウエアは、このデータベースで検証できたバイナリのみを実行する。署名データベースを更新するには、 KEK の正しい署名が必要となる。
- dbx
- 'db' の反対の意味で、禁止署名データベースと呼ばれる。証明書や署名、ハッシュのブラックリストが含まれる。バイナリがこれらの項目に合致した場合、実行することができなくなる。禁止署名データベースを更新するには、 KEK の正しい署名が必要となる。
- MOK
- "Machine Owner Keys" (マシン所有者鍵) - MokManager で使用される、追加の証明書/ハッシュデータベース。 MokManager は MOK を更新する際、対話的に利用することができる。