如何在Oracle 7下Sign Key for Secure Boot (UEK R6)
最近碰到Oracle 7 uek6要Sign Key進Kernel這件事真的蠻棘手的,有很多眉眉角角,一旦不小心步驟弄錯就有機會要重來,只好存了好幾個Snapshot來保身,因此這邊稍微列出Command,跟官方網站可能會遺漏的小細節。
Signing Kernel Modules for Use With Secure Boot
Oracle 7 Secure Boot 官方文件請參考
那我們開始嘍!
Requirements for Signing Kernel Modules
首先安裝所需要的tools:
- kernel-uek-devel
- openssl
- keyutils
- mokutil
- pesign
在安裝kernel-uek-devel
的時候可能要注意是不是裝自己要的kernel,如果不是的話要記得把kernel版本號打上:
yum install kernel-uek-devel-$(uname -r)
而為了安裝pesign,我們也會需要啟用config-manager的ol7_optional_latest
yum-config-manager --enable ol7_optional_latest
就能夠安裝
yum install openssl keyutils mokutil pesign
Generating a Signing Certificate
接著要產生一組Key Pair for Signing Certificate,先產生 x509.conf ,這裡以放在 /etc/ssl
為例。
[ req ]
default_bits = 4096
distinguished_name = req_distinguished_name
prompt = no
string_mask = utf8only
x509_extensions = extensions[ req_distinguished_name ]
O = Module Signing Example
CN = Module Signing Example Key
emailAddress = first.last@example.com[ extensions ]
basicConstraints=critical,CA:FALSE
keyUsage=digitalSignature
extendedKeyUsage = codeSigning
subjectKeyIdentifier=hash
authorityKeyIdentifier=keyid
openssl req -x509 -new -nodes -utf8 -sha512 -days 3650 -batch -config x509.conf -outform DER -out pubkey.der -keyout priv.key
openssl x509 -inform DER -in pubkey.der -out pubkey.pem
Updating the MOK Database
這時候要記得要用mokutil import這把pubkey.pem,不然簽好後的kernel會以這把key來sign過,結果沒有enroll這把key的話,他根本無法合法地去啟用kernel,就會一直顯示這個kernel has invalid signature。
mokutil --import pubkey.der
reboot
Insert the Module Certificate in the Kernel Image
接著確認sign kernel所需的工具跟kernel是不是對應的版本,如果版本不對得回去上面的kernel-uek-devel
重做。理論上這三個應該要是同版本的:
- $(uname -r)
- /usr/src/kernel/$(uname -r)
- /boot/vmlinuz-$(uname -r)
然後我們先備份 /boot
下的kernel image
cp /boot/vmlinuz-$(uname -r) /boot/vmlinuz-$(uname -r).bak
移到 /etc/ssl
下開始 sign
/usr/src/kernels/$(uname -r)/scripts/insert-sys-cert -s /boot/System.map-$(uname -r) -z /boot/vmlinuz-$(uname -r) -c THE_KEY_WE_LIKE_TO_SIGN.der
Configure an NSS Database
設定NSS Database時,同時自訂一組比較有特殊符號的密碼來當作簽署用的密碼。
certutil -d . -N
openssl pkcs12 -export -inkey priv.key -in pubkey.pem -name cert -out cert.p12
pk12util -d . -i cert.p12
Sign the Kernel Image
pesign -u 0 -i /boot/vmlinuz-$(uname -r) --remove-signature -o vmlinuz.unsigned
pesign -n . -c cert -i vmlinuz.unsigned -o vmlinuz.signed -s
Save the signed kernel image back to /boot
cp -f vmlinuz.signed /boot/vmlinuz-$(uname -r)
rm -f vmlinuz.*
reboot
這樣就全部都 Sign 完了
Validating That a Key Is Trusted
檢查Key的指定也跟原本uek5的不一樣,不再是透過mokutil —-list-enrolled
來查找,而是要透過:
keyctl show %:.builtin_trusted_keys
理論上你所Sign的Key應該就要在這裡面找到了
Trouble Shooting
error: /vmlinuz-{kernel_name} has invalid signature.
如果開機時發生這個訊息,那代表當初sign kernel之前沒有先把pubkey先enroll進去,所以kernel image本身跟sign過的key不match,才會這樣。