目的
防止未授权的或恶意的驱动模块加载
测试模块准备
参考https://paper.seebug.org/779/
先准备个测试module
功能很简单: 内核加载时打印Hello World
, 卸载时打印Goodbye World
driver_example.c
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
| #include <linux/init.h> #include <linux/module.h>
MODULE_LICENSE("Dual BSD/GPL"); MODULE_AUTHOR("Hcamal");
int hello_init(void) { printk(KERN_INFO "Hello World\n"); return 0; }
void hello_exit(void) { printk(KERN_INFO "Goodbye World\n"); }
module_init(hello_init); module_exit(hello_exit);
|
Makefile
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
| ifneq ($(KERNELRELEASE),)
obj-m := driver_example.o
else
KERN_DIR ?= /usr/src/linux-$(shell uname -r)/ PWD := $(shell pwd)
default: $(MAKE) -C $(KERN_DIR) M=$(PWD) modules
endif
clean: rm -rf *.o *~ core .depend .*.cmd *.ko *.mod.c .tmp_versions
|
最后通过make
生成driver_example.ko
通过insmod driver_example.ko
和rmmod driver_example.ko
来进行内核模块的加载、删除
dmesg -T
可以看到打印的信息
1 2
| [Tue Sep 14 17:25:16 2021] Hello World [Tue Sep 14 17:25:20 2021] Goodbye World
|
签名配置
内核模块签名 https://www.kernel.org/doc/html/latest/admin-guide/module-signing.html?highlight=signing
1 2 3 4 5 6 7 8 9
| Enable loalable module support --->
[*] Module signature verification
[*] Require modules to be validly signed
[*] Automatically sign all modules
Which hash algorithm should modules be signed with?(Sign modules with SHA-512)
|
最终生成的关键配置项
1 2 3 4 5 6 7
| CONFIG_MODULE_SIG=y CONFIG_MODULE_SIG_FORCE=y CONFIG_MODULE_SIG_ALL=y CONFIG_MODULE_SIG_SHA512=y CONFIG_MODULE_SIG_HASH="sha512"
CONFIG_MODULE_SIG_KEY="certs/signing_key.pem"
|
重新编译内核和安装、重启系统
1 2 3
| make -j`nproc` make modules_install make install
|
确认已启用内核签名
dmesg -T | grep -i 'x.*509'
1 2 3 4 5
| [Tue Sep 14 18:54:43 2021] Asymmetric key parser 'x509' registered [Tue Sep 14 18:54:43 2021] Loading compiled-in X.509 certificates [Tue Sep 14 18:54:43 2021] Loaded X.509 cert 'Build time autogenerated kernel key: 61e75ddf5386c7378280fbed3f5d3b5f39dc5b9a' [Tue Sep 14 18:54:43 2021] cfg80211: Loading compiled-in X.509 certificates for regulatory database [Tue Sep 14 18:54:43 2021] cfg80211: Loaded X.509 cert 'sforshee: 00b28ddf47aef9cea7'
|
或
cat /proc/keys
1 2 3 4 5 6 7 8 9
| 075b6d49 I------ 1 perm 1f0b0000 0 0 keyring .builtin_trusted_keys: 1 07b9d7e9 I------ 1 perm 1f030000 0 0 asymmetri sforshee: 00b28ddf47aef9cea7: X509.rsa [] 0b22aa86 I--Q--- 2 perm 1f3f0000 0 65534 keyring _uid.0: empty 2515517c I------ 1 perm 1f0b0000 0 0 keyring .builtin_regdb_keys: 1 2a5884f8 I--Q--- 1 perm 1f3f0000 0 65534 keyring _uid_ses.0: 1 2cad08c9 I------ 1 perm 1f030000 0 0 keyring .id_resolver: empty 301e3a1b I------ 1 perm 1f030000 0 0 asymmetri `Build time autogenerated kernel key`: 61e75ddf5386c7378280fbed3f5d3b5f39dc5b9a: X509.rsa 39dc5b9a [] 31476e28 I------ 1 perm 1f030000 0 0 keyring .dns_resolver: empty 357f2eb8 I--Q--- 1 perm 0c030000 0 65534 keyring .user_reg: 2
|
验证 - 只允许加载签名后的模块
加载测试模块insmod driver_example.ko
- 失败
1
| insmod: ERROR: could not insert module driver_example.ko: Key was rejected by service
|
用系统生成的key、证书对模块进行签名
1
| scripts/sign-file sha512 certs/signing_key.pem certs/signing_key.pem /home/test/driver_example.ko
|
加载签名后的测试模块insmod driver_example.ko
- 成功
dmesg -T | tail
看到Hello World
的输出
1
| [Wed Sep 15 10:15:18 2021] Hello World
|
签名信息会被追加到模块尾部 hexdump -C driver_example.ko | tail
1 2 3 4 5 6 7 8 9 10
| 00001250 d3 5b d7 6e 42 b8 3d 6b ad 1d 17 7c dc cf 5f 9d |.[.nB.=k...|.._.| 00001260 07 02 93 45 d5 ea e4 cd 2c 3d ae 92 bd 33 81 4f |...E....,=...3.O| 00001270 67 39 a7 c2 a9 96 42 d0 87 1c 19 d9 e4 79 a3 c5 |g9....B......y..| 00001280 5e 83 a6 3c 1e 13 70 93 c3 4a ad 51 32 d8 ab e5 |^..<..p..J.Q2...| 00001290 26 b4 ed 27 ca 98 37 78 70 d7 79 69 cf 9f 5b 67 |&..'..7xp.yi..[g| 000012a0 98 f6 17 84 8d 4c 32 0a b0 00 00 02 00 00 00 00 |.....L2.........| 000012b0 00 00 00 02 a9 7e 4d 6f 64 75 6c 65 20 73 69 67 |.....~Module sig| 000012c0 6e 61 74 75 72 65 20 61 70 70 65 6e 64 65 64 7e |nature appended~| 000012d0 0a |.| 000012d1
|
删除签名信息
1
| strip --strip-debug driver_example.ko
|
证书文件生成方式
参照certs/Makefile
, 更多自签名证书相关自行搜索
1 2 3 4
| $(Q)openssl req -new -nodes -utf8 -$(CONFIG_MODULE_SIG_HASH) -days 36500 \ -batch -x509 -config $(obj)/x509.genkey \ -outform PEM -out $(obj)/signing_key.pem \ -keyout $(obj)/signing_key.pem \
|
注意事项
- 公司如果有统一的签名管理体系的话, 生产环境不建议自动生成签名证书
- 私钥保护好, 避免被恶意人员利用