CONFIG_MODULE_SIG 的作用
CONFIG_MODULE_SIG 的工作原理是什么?
简单来说,当这个选项被启用时,内核在加载任何一个模块(.ko 文件)之前,都会先检查它是否附带了一个有效的数字签名。如果签名不存在或验证失败,内核就会拒绝加载这个模块。
为什么需要这个功能? 这个功能是 Linux 内核安全体系中的一个关键环节,主要为了解决以下两个问题: 防止加载恶意或未经授权的模块(安全性)
启用了 CONFIG_MODULE_SIG 后,使攻击者获得了 root 权限,他也无法加载一个没有被可信密钥签名的模块,因为内核会进行最终的校验。这为系统提供了一道强大的、纵深防御的安全屏障。
确保模块的完整性和来源可靠性(完整性)
签名不仅验证了模块的来源(它是由持有私钥的人签名的),还验证了它的完整性。
modprobe 或 insmod 在加载模块时,会计算模块文件的哈希值,并与签名中包含的哈希值进行对比。如果文件在传输或存储过程中被意外(或恶意)修改了哪怕一个比特位,哈希值就会不匹配,签名验证就会失败。
这可以防止因文件损坏而加载一个有问题的模块,从而避免潜在的系统不稳定或崩溃。
它是如何工作的? 整个流程大致如下:
生成密钥对: 在编译内核时,系统会生成一对公钥/私钥。 私钥 (signing_key.pem):被严格保存在编译环境中,用于对内核模块进行签名。 公钥 (signing_key.x509):被编译进内核本身(vmlinuz 文件)。
这两个文件是内核产生的:
cp certs/signing_key.pem .
cp certs/signing_key.x509 .
模块签名: 在内核编译过程的最后阶段(通常是在 make modules_install 之后),一个名为 sign-file 的脚本会自动被调用。它会遍历所有编译好的 .ko 文件,使用私钥为每一个模块计算并附加一个数字签名。这个签名被存储在每个 .ko 文件末尾的一个特殊 ELF 段中。
加载时验证: 当系统管理员尝试使用 insmod 或 modprobe 加载一个模块时:
内核会提取模块文件末尾的签名。 使用内置在内核中的公钥来解密这个签名,并验证其有效性。 如果签名有效,模块被允许加载;如果无效或不存在,加载操作会失败,并通常会在 dmesg 中记录一条错误信息。
CONFIG_MODULE_SIG 相关的其他选项 CONFIG_MODULE_SIG 只是一个总开关,它还有一些配套的选项来调整其行为:
- CONFIG_MODULE_SIG_FORCE: 如果启用,会强制要求所有模块都必须被签名,即使内核本身没有被 Secure Boot 保护。
- CONFIG_MODULE_SIG_ALL: 自动为所有模块进行签名。
- CONFIG_MODULE_SIG_SHA512: 指定使用的哈希算法(例如 SHA-512)。
- CONFIG_MODULE_SIG_KEY: 允许您指定一个自定义的密钥文件,而不是使用自动生成的密钥。
509.genkey
509.genkey 是一个在内核编译过程中用来生成自签名 X.509 证书和私钥的配置文件。
这个生成出来的密钥对主要用于两个关键的内核安全功能:
- 内核模块签名 (Kernel Module Signing)
- 内核完整性测量架构 (IMA/EVM)
openssl 命令执行后,会生成两个至关重要的文件:
- signing_key.pem: 这是私钥。它被严格保密,用于对内核模块(.ko 文件)进行数字签名。
- signing_key.x509: 这是公钥证书。这个公钥会被编译进内核本身 (vmlinuz)。
默认情况下,每次运行内核构建,openssl 都会生成一对全新的、随机的密钥对。即使 x509.genkey 配置文件完全相同,生成的密钥也是不同的。
模块签名
CONFIG_MODULE_SIG
🧀 modinfo kvm
filename: /lib/modules/6.1.0-rc3nosec-d79dcde0bc41+/kernel/arch/x86/kvm/kvm.ko
license: GPL
author: Qumranet
srcversion: EC75D48D2C855EB880CE255
depends: irqbypass
retpoline: Y
intree: Y
name: kvm
vermagic: 6.1.0-rc3nosec-d79dcde0bc41+ SMP preempt mod_unload modversions
sig_id: PKCS#7
signer: Build time autogenerated kernel key
sig_key: 4D:AE:B1:D2:43:C6:43:95:07:FC:0A:30:18:E1:61:D5:E6:0E:C4:6A
sig_hashalgo: sha256
signature: 0D:C5:43:AB:60:75:FE:56:D4:18:B9:E7:BA:FD:16:AF:9C:3B:F6:06:
DF:34:BE:0F:F7:09:AE:DB:04:0A:D1:C5:B0:75:D3:2A:EF:47:EB:E5:
DD:D8:6B:27:DE:E1:9E:B8:F5:96:9A:E5:ED:E2:DF:22:9C:82:17:F4:
DE:72:25:0E:E5:03:73:7F:5B:CA:61:DF:86:F2:48:52:4D:DE:B5:94:
2B:27:76:8F:70:03:A9:79:BE:CE:C6:4F:AE:D2:77:49:87:92:80:5D:
14:35:CA:A3:09:8A:E8:21:F2:4F:2A:FF:F1:38:41:9B:F5:25:B9:17:
D0:77:15:77:A4:78:56:84:BB:C4:9C:2D:9D:FD:EB:62:7C:10:C8:77:
69:AD:F5:52:A9:03:A0:15:9F:5B:D4:01:1F:F7:AB:F1:DF:5C:8A:02:
F4:CB:D4:3D:06:76:C3:F5:46:38:D1:37:A1:BF:DE:45:7A:B6:7A:AC:
1D:B9:A3:3E:2A:E2:5B:82:EA:8B:25:39:A1:85:40:21:4A:D3:80:C3:
A5:18:EF:4F:4C:5E:21:8E:50:98:04:10:E4:40:10:20:F8:FE:38:13:
4B:8F:61:68:16:80:BA:FA:13:E2:0E:2D:DC:D5:7A:B4:E6:05:39:DA:
BE:1A:DD:57:2E:4D:BB:FC:94:19:C6:23:1E:62:24:33:F2:03:B9:E4:
32:1E:38:0D:8C:68:E6:93:3E:9E:0D:9E:C5:2F:65:2A:26:58:4D:2D:
C7:64:1E:DF:62:DA:9F:EF:0D:A2:61:F1:A5:15:31:1D:65:FF:AF:14:
AC:43:82:10:2B:65:73:72:8B:B9:1E:DF:90:B6:F1:41:83:F0:6A:40:
97:4A:CE:3E:87:35:73:29:BB:28:87:B8:AF:52:DB:92:E2:A1:C1:87:
A3:ED:AA:B3:3E:7A:63:8B:0C:4D:C1:2B:6F:20:A4:50:ED:74:5F:BC:
56:0B:96:71:DD:9F:70:92:B9:22:6E:21:92:AB:29:FB:A5:71:03:F6:
AF:CE:2F:B0:D4:23:F5:0A:11:FC:16:C3:7F:3D:C5:DD:16:DB:F0:BE:
8C:F4:EB:44:FA:5C:5D:F0:BF:0D:E7:0A:85:1B:30:FA:42:27:46:C6:
3F:9D:BB:61:D1:2E:7B:F0:7A:C3:78:8B:28:35:27:34:5E:29:57:FF:
C8:51:69:D9:ED:D2:54:49:5E:B2:9E:9A:AC:BF:F1:BB:26:3E:47:F3:
3C:5A:00:9B:6B:99:A1:4D:0D:F7:26:AB:A1:5B:AE:94:CD:94:29:84:
12:0A:F4:D2:13:EC:9C:07:1F:F0:08:69:1A:BE:F1:55:B0:FD:49:3C:
5F:8E:70:4E:69:92:89:60:B5:BC:E4:D3
parm: tdp_mmu:bool
parm: mmio_caching:bool
parm: flush_on_reuse:bool
parm: ignore_msrs:bool
parm: report_ignored_msrs:bool
parm: min_timer_period_us:uint
parm: kvmclock_periodic_sync:bool
parm: tsc_tolerance_ppm:uint
parm: lapic_timer_advance_ns:int
parm: vector_hashing:bool
parm: enable_vmware_backdoor:bool
parm: force_emulation_prefix:int
parm: pi_inject_timer:bint
parm: enable_pmu:bool
parm: eager_page_split:bool
parm: halt_poll_ns:uint
parm: halt_poll_ns_grow:uint
parm: halt_poll_ns_grow_start:uint
parm: halt_poll_ns_shrink:uint
打开了 CONFIG_MODULE_SIG 之后,会有这个警告:
linux login: martins3: loading out-of-tree module taints kernel.
martins3: module verification failed: signature and/or required key missing - tainting kernel
[martins3:greeter_init:747]
action = 0 current=tee
应该是没有打开的 CONFIG_MODULE_SIG_FORCE ,所以还是可以安装驱动的。
例如,这里的 nvidia 是我自己编译的,而 kvm 是自带的
🧀 modinfo nvidia
filename: /lib/modules/7.0.8-200.fc44.x86_64/kernel/drivers/video/nvidia.ko
import_ns: DMA_BUF
alias: char-major-195-*
description: NVIDIA core GPU kernel module
version: 595.71.05
supported: external
license: Dual MIT/GPL
firmware: nvidia/595.71.05/gsp_tu10x.bin
firmware: nvidia/595.71.05/gsp_ga10x.bin
softdep: pre: ecdh_generic,ecdsa_generic
srcversion: 58D233B8E3F4A2973D73151
alias: pci:v000010DEd*sv*sd*bc06sc80i00*
alias: pci:v000010DEd*sv*sd*bc03sc02i00*
alias: pci:v000010DEd*sv*sd*bc03sc00i00*
alias: of:N*T*Cnvidia,tegra264-displayC*
alias: of:N*T*Cnvidia,tegra264-display
alias: of:N*T*Cnvidia,tegra234-displayC*
alias: of:N*T*Cnvidia,tegra234-display
depends:
name: nvidia
retpoline: Y
vermagic: 7.0.8-200.fc44.x86_64 SMP preempt mod_unload
parm: NvSwitchRegDwords:NvSwitch regkey (charp)
parm: NvSwitchBlacklist:NvSwitchBlacklist=uuid[,uuid...] (charp)
parm: NVreg_ResmanDebugLevel:int
parm: NVreg_RmLogonRC:int
parm: NVreg_ModifyDeviceFiles:int
parm: NVreg_DeviceFileUID:int
parm: NVreg_DeviceFileGID:int
parm: NVreg_DeviceFileMode:int
parm: NVreg_InitializeSystemMemoryAllocations:int
parm: NVreg_UsePageAttributeTable:int
parm: NVreg_EnablePCIeGen3:int
parm: NVreg_EnableMSI:int
parm: NVreg_EnableStreamMemOPs:int
parm: NVreg_RestrictProfilingToAdminUsers:int
parm: NVreg_PreserveVideoMemoryAllocations:int
parm: NVreg_EnableS0ixPowerManagement:int
parm: NVreg_S0ixPowerManagementVideoMemoryThreshold:int
parm: NVreg_DynamicPowerManagement:int
parm: NVreg_DynamicPowerManagementVideoMemoryThreshold:int
parm: NVreg_EnableGpuFirmware:int
parm: NVreg_EnableGpuFirmwareLogs:int
parm: NVreg_OpenRmEnableUnsupportedGpus:int
parm: NVreg_EnableUserNUMAManagement:int
parm: NVreg_MemoryPoolSize:int
parm: NVreg_KMallocHeapMaxSize:int
parm: NVreg_VMallocHeapMaxSize:int
parm: NVreg_IgnoreMMIOCheck:int
parm: NVreg_NvLinkDisable:int
parm: NVreg_EnablePCIERelaxedOrderingMode:int
parm: NVreg_RegisterPCIDriver:int
parm: NVreg_RegisterPlatformDeviceDriver:int
parm: NVreg_EnableResizableBar:int
parm: NVreg_EnableDbgBreakpoint:int
parm: NVreg_TegraGpuPgMask:int
parm: NVreg_EnableNonblockingOpen:int
parm: NVreg_ExcludeAllGpus:int
parm: NVreg_GpuInitOnProbe:int
parm: NVreg_CoherentGPUMemoryMode:charp
parm: NVreg_RegistryDwords:charp
parm: NVreg_RegistryDwordsPerDevice:charp
parm: NVreg_RmMsg:charp
parm: NVreg_GpuBlacklist:charp
parm: NVreg_TemporaryFilePath:charp
parm: NVreg_ExcludedGpus:charp
parm: NVreg_DmaRemapPeerMmio:int
parm: NVreg_RmNvlinkBandwidth:charp
parm: NVreg_RmNvlinkBandwidthLinkCount:int
parm: NVreg_ImexChannelCount:int
parm: NVreg_CreateImexChannel0:int
parm: NVreg_GrdmaPciTopoCheckOverride:int
parm: NVreg_EnableSystemMemoryPools:int
parm: NVreg_UseKernelSuspendNotifiers:int
parm: rm_firmware_active:charp
🧀 modinfo kvm
filename: /lib/modules/7.0.8-200.fc44.x86_64/kernel/arch/x86/kvm/kvm.ko.xz
license: GPL
description: Kernel-based Virtual Machine (KVM) Hypervisor
author: Qumranet
depends: irqbypass
intree: Y
name: kvm
retpoline: Y
vermagic: 7.0.8-200.fc44.x86_64 SMP preempt mod_unload
sig_id: PKCS#7
signer: Fedora kernel signing key
sig_key: 10:B0:04:6C:03:AA:74:67:7C:B8:06:61:94:42:E4:16:E1:78:2E:89
sig_hashalgo: sha256
signature: 32:10:CB:46:DF:E5:F2:E1:EB:4B:74:4A:1B:DF:6B:9D:CB:29:FA:C4:
15:05:4B:C3:FF:1E:F5:8C:36:7F:66:2A:B7:2B:C6:13:FD:D9:B0:44:
9A:3A:10:95:1A:EA:7D:71:F9:91:CB:5F:43:7A:A5:73:9F:C7:AF:8C:
20:89:F5:37:B1:E4:A6:F0:1B:9B:8E:D4:E5:D9:CE:60:D4:76:7F:15:
F7:2F:C6:D1:E1:A2:53:15:81:AD:FB:97:64:82:FF:A6:38:2C:E0:1A:
81:56:0D:6D:4D:E0:39:40:67:38:F3:DC:BD:22:F0:29:3F:4D:07:9F:
92:C3:1D:84:69:BF:52:D6:EF:10:5A:2E:7D:FF:18:08:90:2F:37:F9:
F6:D3:0D:41:4B:47:C4:D7:55:AE:52:AA:19:20:37:7C:3B:9E:AE:EE:
51:27:BE:8E:F4:04:7C:1F:F8:9B:83:F7:CF:DC:A6:4B:1F:32:2A:28:
7D:BE:45:44:51:67:86:8E:2C:35:20:33:02:7D:50:7F:5F:1A:91:2C:
68:97:89:40:BB:A5:F3:34:E8:81:D8:FF:15:2F:64:C1:64:0F:F8:C9:
A5:5A:F5:E9:E1:C3:AB:C5:21:DD:E6:98:24:99:22:0C:87:A0:B5:D2:
64:8A:27:DA:8A:4D:32:C4:D6:8A:F0:11:F4:9F:E4:87:45:3A:03:F2:
5B:67:89:1A:5F:30:62:40:B7:0E:7E:74:48:5B:30:E5:95:E7:25:B8:
D6:A0:5D:61:B9:9C:DC:E9:D7:B3:3C:6C:55:80:91:BF:73:69:D1:F1:
18:94:E5:12:65:7E:D0:94:9F:9B:45:25:E6:19:FC:D9:70:42:AA:07:
81:7A:76:D2:A2:47:31:FE:66:C2:5A:99:EB:33:6F:77:23:DA:6F:78:
99:8D:4E:F3:46:04:9C:48:92:9B:D6:E3:4D:57:76:80:74:1A:75:AC:
32:9F:E4:94:4F:92:81:E8:72:B1:2A:87:2F:40:58:2D:A6:D0:27:2A:
78:85:7D:67:F7:97:E8:AC:AC:DB:11:D0:04:5E:F3:64:12:7F:0A:46:
12:21:CA:C8:6A:20:33:E5:92:C4:46:67:2F:55:D9:40:3D:53:D1:1A:
D6:E4:9C:BD:63:EC:C7:D4:DA:7C:26:9C:EF:71:5E:A5:48:DC:FD:D5:
66:B0:E3:AC:2E:9E:1D:C9:C0:D2:D5:6C:97:6E:7B:BD:99:8E:EA:1B:
E7:BF:5B:63:8F:23:02:39:21:72:A9:F9:42:DA:E1:2D:48:70:1E:05:
D1:55:4D:E6:59:F7:64:52:25:B5:36:5B:6A:D4:D1:DA:B1:B9:29:59:
50:EF:2B:2C:C2:3C:D7:E6:C1:03:C8:56
parm: mmio_caching:bool
parm: nx_huge_pages:bool
parm: nx_huge_pages_recovery_ratio:uint
parm: nx_huge_pages_recovery_period_ms:uint
parm: flush_on_reuse:bool
parm: tdp_mmu:bool
parm: lapic_timer_advance:bool
parm: vector_hashing:bool
parm: ignore_msrs:bool
parm: report_ignored_msrs:bool
parm: min_timer_period_us:uint
parm: tsc_tolerance_ppm:uint
parm: enable_vmware_backdoor:bool
parm: force_emulation_prefix:int
parm: pi_inject_timer:bint
parm: enable_pmu:bool
parm: eager_page_split:bool
parm: mitigate_smt_rsb:bool
parm: halt_poll_ns:uint
parm: halt_poll_ns_grow:uint
parm: halt_poll_ns_grow_start:uint
parm: halt_poll_ns_shrink:uint
parm: allow_unsafe_mappings:bool
parm: enable_virt_at_load:bool
本站所有文章转发 CSDN 将按侵权追究法律责任,其它情况随意。