这是关于Linux安全启动和签名模块两篇系列文章的第2篇:
- Linux系统安全启动
- 构建并安装已签名Kvaser驱动程序模块
第一篇文章概述了安全启动的概念,以及它如何影响第三方模块。在本文中,我们将介绍如何构建和签名Kvaser驱动程序模块,以便能够在启用了安全启动的Linux计算机上使用它们。
这是关于Linux安全启动和签名模块两篇系列文章的第2篇:
第一篇文章概述了安全启动的概念,以及它如何影响第三方模块。在本文中,我们将介绍如何构建和签名Kvaser驱动程序模块,以便能够在启用了安全启动的Linux计算机上使用它们。
我们准备好最新安装的Ubuntu16.04。
$ uname -a
Linux mypc 4.8.0-51-generic #54~16.04.1-Ubuntu SMP Wed Apr 26 16:00:28 UTC 2017
x86_64 x86_64 x86_64 GNU/Linux
$ lsb_release -a
No LSB modules are available.
Distributor ID: Ubuntu
Description: Ubuntu 16.04.2 LTS
Release: 16.04
Codename: xenial
$ mkdir ~/sign_cert
$ cd ~/sign_cert
# Change YOUR_NAME below for identification purposes, we’ll use kvaser.com
$ openssl req -new -x509 -newkey rsa:2048 -keyout modulesign.priv -outform DER
-out modulesign.der -nodes -days 36500 -subj "/CN=YOUR_NAME/"
现在出现两个文件。
$ ls
modulesign.der modulesign.priv
下一步使用mokutil4命令导入公钥,让其可以被系统信任。这个过程需要两步,其中首先导入密钥,然后在下次启动机器时必须进行注册。简单的密码即可,因为只是临时使用。
$ sudo mokutil --import modulesign.der
input password:
input password again:
我们现在可以验证是否已导入正确的证书。 在这里我们也注意到上面使用的公用名称(CN)是kvaser.com。
$ sudo mokutil --list-new
[key 1]
SHA1 Fingerprint: 2c:d4:5b:a3:c6:34:3f:a6:1a:8f:e3:d3:23:8d:88:69:7d:33:ae:12
Certificate:
Data:
Version: 3 (0x2)
Serial Number: 18315900181576503446 (0xfe2f262c60615096)
Signature Algorithm: sha256WithRSAEncryption
Issuer: CN=kvaser.com
Validity
Not Before: May 9 07:52:56 2017 GMT
Not After : Apr 15 07:52:56 2117 GMT
Subject: CN=kvaser.com
Subject Public Key Info:
Public Key Algorithm: rsaEncryption
Public-Key: (2048 bit)
Modulus:
:
:
现在重新启动机器。引导加载程序启动时,MOK管理器EFI实用程序应自动启动。在我的机器屏幕上出现浅蓝色背景的白色文字,提示要“点击任意键执行MOK管理”和“10秒后启动”5,YMMV。选择“注册MOK”,选择密钥,并注册密钥。在上述导入步骤中我们会被要求输入设置密码。完成注册步骤,然后继续启动。Linux内核将记录加载的密钥,我们可以使用dmesg
命令查看我们自己的密钥。
$ dmesg|grep ’EFI: Loaded cert’
[ 0.671897] EFI: Loaded cert ’Microsoft Windows Production PCA 2011:
a92902398e16c49778cd90f99e4f9ae17c55af53’ linked to ’.builtin_trusted_keys’
[ 0.671908] EFI: Loaded cert ’Microsoft Corporation UEFI CA 2011:
13adbf4309bd82709c8cd54f316ed522988a1bd4’ linked to ’.builtin_trusted_keys’
[ 0.673771] EFI: Loaded cert ’kvaser.com: 74fd8929d9e2fb64a9bd0abe3bdf
42d519b7382f’ linked to ’.builtin_trusted_keys’
[ 0.673902] EFI: Loaded cert ’Canonical Ltd. Master Certificate Authority:
ad91990bc22ab1f517048c23b6655a268e345a63’ linked to ’.builtin_trusted_keys’
我们现在还可以使用mokutil
命令测试我们的证书是否已注册。
$ cd ~/sign_cert
$ mokutil --test-key modulesign.der
modulesign.der is already enrolled
在构建之前,我们需要从Kvaser下载页面下载最新版本的linuxcan,截至到这篇文章撰稿最新版本是v5.20.。6
$ wget http://www.kvaser.com/software/7330130980754/V5_20_0/linuxcan.tar.gz
$ tar xvzf linuxcan.tar.gz
$ cd linuxcan
为了方便我们在正常构建过程中将文件签名,我们修改文件config.mak中的kv_module目标如下。7
# Target found in config.mak located in the top level directory of linuxcan
kv_module:
@echo --------------------------------------------------------------------
@echo "building $(KV_MODULE_NAME) $(IS_DEBUG)"
@echo "Kernel src:" $(KV_KERNEL_SRC_DIR)
$(MAKE) -C $(KV_KERNEL_SRC_DIR) SUBDIRS=$(PWD) modules
@if [ "$(KV_SIGN_CERT_PATH)" != "" ] && [ "$(KV_SIGN_CERT_NAME)" != "" ]; then \
echo "Signing module $(KV_MODULE_NAME).ko with $(KV_SIGN_CERT_PATH)/$(KV_SIGN_CERT_NAME)"; \
$(KV_KERNEL_SRC_DIR)/scripts/sign-file sha256 $(KV_SIGN_CERT_PATH)/$(KV_SIGN_CERT_NAME).priv \
$(KV_SIGN_CERT_PATH)/$(KV_SIGN_CERT_NAME).der $(KV_MODULE_NAME).ko; \
fi
@echo --------------------------------------------------------------------
现在可以通过添加两个环境变量KV_SIGN_CERT_PATH
和KV_SIGN_CERT_NAME
,使用常见的make
命令来构建和签名驱动程序模块。在构建后安装模块。
# KV_SIGN_CERT_PATH is the path to your private key and certificate.
# KV_SIGN_CERT_NAME is the base file name of your private key and
certificate, without suffix.
$ make KV_SIGN_CERT_PATH=~/sign_cert KV_SIGN_CERT_NAME=modulesign
$ sudo make install
为了验证已安装的模块是否正常工作,我们使用modprobe
命令来手动加载模块并验证它是否已加载。8 我们要确保删除模块以免在Kvaser USB设备连接时自动加载。
$ sudo modprobe mhydra
$ lsmod | grep ’kvcommon\|mhydra’
mhydra 45056 0
kvcommon 45056 1 mhydra
$ sudo modprobe -r mhydra kvcommon
1 有关保护私钥的注意事项可以在Linux内核文档中找到,网址为https://static.lwn.net/kerneldoc/admin-guide/module-signing.html#administering-protecting-the-private-key
2 您可以在SSL安装知识库中阅读有关不同X509文件扩展名(如DER)的更多信息,网址为https://support.ssl.com/Knowledgebase/Article/View/19/0/der-vs-crt-vs-cer-vs-pem-certificates-and-how-to-convert-them/.
3 有关公用名称重要性的说明,请参阅stackexchange文章中的详细内容https://security.stackexchange.com/questions/40026/openssl-x509-whats-the-significance-of-cn-common-name/.
4 使用mokutil
命令来管理shim层使用的机主密钥(MOK),以验证grub2和内核映像。
5 如果您错过此超时,则需要重新运行mokutil --import
命令并重新启动。
6 Kvaser下载页面https://www.kvaser.cn/downloads
7 调整后的makefile目标将被并入linuxcan的下一个版本
8 目前无法使用modinfo
查看模块是否已经签名,详细信息请参阅github中所列的coreos问题,网址为https://github.com/coreos/bugs/issues/1054/