← Documents Documentation/admin-guide/module-signing.rst GitHub 원문 ↗

Linux 6.18.37 · Administration / Modules

Kernel module signing facility

Kernel module의 X.509 기반 서명, Kconfig 정책, 키 생성·배포, 수동 서명, 적재 검증과 private key 보호 절차를 설명합니다.

Source pathDocumentation/admin-guide/module-signing.rst
Source versionLinux v6.18.37
TranslationDUJINLABS 전문 번역 + 해설

요약·해설과 원문, 전문 번역을 서로 분리했습니다. API 이름, symbol, source path는 원문 표기를 사용합니다.

1. 요약·해설

원문의 핵심 논리와 kernel programming 관점의 보충 설명입니다. 아래의 전문 번역과는 별도로 작성했습니다.

운영 핵심

module-signing.rst:1-290

Module signing은 설치 시 signature를 붙이고 load 시 kernel이 검증하는 공급망 통제입니다. 강제 정책을 사용하려면 신뢰할 공개 키를 kernel keyring에 넣고 private key를 build 환경에서 엄격히 분리해야 합니다.

관점핵심
검증 위치Module 설치 때 서명하고 load 때 kernel 내부에서 검증하므로 trusted userspace 구성 요소가 필요하지 않습니다.
지원 키X.509 certificate로 RSA 또는 NIST P-384 ECDSA 공개 키를 전달합니다.
정책`CONFIG_MODULE_SIG_FORCE` 또는 `module.sig_enforce=1`로 유효한 서명을 강제합니다.
서명 도구자동 `modules_install` 서명 또는 `scripts/sign-file` 수동 서명을 사용합니다.
신뢰 저장소`.builtin_trusted_keys`, `CONFIG_SYSTEM_TRUSTED_KEYS`, UEFI key database에서 공개 키를 얻습니다.
운영 주의서명된 module은 strip할 수 없으며 private key는 build 후 폐기하거나 안전한 위치로 옮겨야 합니다.

2. 영어 원문 전체

번역 기준이 된 Linux v6.18.37 원문입니다. 줄 번호는 이 버전의 파일 좌표입니다.

원문 전체 펼치기
1 Kernel module signing facility
2 ------------------------------
3
4 .. CONTENTS
5 ..
6 .. - Overview.
7 .. - Configuring module signing.
8 .. - Generating signing keys.
9 .. - Public keys in the kernel.
10 .. - Manually signing modules.
11 .. - Signed modules and stripping.
12 .. - Loading signed modules.
13 .. - Non-valid signatures and unsigned modules.
14 .. - Administering/protecting the private key.
15
16
17 ========
18 Overview
19 ========
20
21 The kernel module signing facility cryptographically signs modules during
22 installation and then checks the signature upon loading the module. This
23 allows increased kernel security by disallowing the loading of unsigned modules
24 or modules signed with an invalid key. Module signing increases security by
25 making it harder to load a malicious module into the kernel. The module
26 signature checking is done by the kernel so that it is not necessary to have
27 trusted userspace bits.
28
29 This facility uses X.509 ITU-T standard certificates to encode the public keys
30 involved. The signatures are not themselves encoded in any industrial standard
31 type. The built-in facility currently only supports the RSA & NIST P-384 ECDSA
32 public key signing standard (though it is pluggable and permits others to be
33 used). The possible hash algorithms that can be used are SHA-2 and SHA-3 of
34 sizes 256, 384, and 512 (the algorithm is selected by data in the signature).
35
36
37 ==========================
38 Configuring module signing
39 ==========================
40
41 The module signing facility is enabled by going to the
42 :menuselection:`Enable Loadable Module Support` section of
43 the kernel configuration and turning on::
44
45 CONFIG_MODULE_SIG "Module signature verification"
46
47 This has a number of options available:
48
49 (1) :menuselection:`Require modules to be validly signed`
50 (``CONFIG_MODULE_SIG_FORCE``)
51
52 This specifies how the kernel should deal with a module that has a
53 signature for which the key is not known or a module that is unsigned.
54
55 If this is off (ie. "permissive"), then modules for which the key is not
56 available and modules that are unsigned are permitted, but the kernel will
57 be marked as being tainted, and the concerned modules will be marked as
58 tainted, shown with the character 'E'.
59
60 If this is on (ie. "restrictive"), only modules that have a valid
61 signature that can be verified by a public key in the kernel's possession
62 will be loaded. All other modules will generate an error.
63
64 Irrespective of the setting here, if the module has a signature block that
65 cannot be parsed, it will be rejected out of hand.
66
67
68 (2) :menuselection:`Automatically sign all modules`
69 (``CONFIG_MODULE_SIG_ALL``)
70
71 If this is on then modules will be automatically signed during the
72 modules_install phase of a build. If this is off, then the modules must
73 be signed manually using::
74
75 scripts/sign-file
76
77
78 (3) :menuselection:`Which hash algorithm should modules be signed with?`
79
80 This presents a choice of which hash algorithm the installation phase will
81 sign the modules with:
82
83 =============================== ==========================================
84 ``CONFIG_MODULE_SIG_SHA256`` :menuselection:`Sign modules with SHA-256`
85 ``CONFIG_MODULE_SIG_SHA384`` :menuselection:`Sign modules with SHA-384`
86 ``CONFIG_MODULE_SIG_SHA512`` :menuselection:`Sign modules with SHA-512`
87 ``CONFIG_MODULE_SIG_SHA3_256`` :menuselection:`Sign modules with SHA3-256`
88 ``CONFIG_MODULE_SIG_SHA3_384`` :menuselection:`Sign modules with SHA3-384`
89 ``CONFIG_MODULE_SIG_SHA3_512`` :menuselection:`Sign modules with SHA3-512`
90 =============================== ==========================================
91
92 The algorithm selected here will also be built into the kernel (rather
93 than being a module) so that modules signed with that algorithm can have
94 their signatures checked without causing a dependency loop.
95
96
97 (4) :menuselection:`File name or PKCS#11 URI of module signing key`
98 (``CONFIG_MODULE_SIG_KEY``)
99
100 Setting this option to something other than its default of
101 ``certs/signing_key.pem`` will disable the autogeneration of signing keys
102 and allow the kernel modules to be signed with a key of your choosing.
103 The string provided should identify a file containing both a private key
104 and its corresponding X.509 certificate in PEM form, or — on systems where
105 the OpenSSL ENGINE_pkcs11 is functional — a PKCS#11 URI as defined by
106 RFC7512. In the latter case, the PKCS#11 URI should reference both a
107 certificate and a private key.
108
109 If the PEM file containing the private key is encrypted, or if the
110 PKCS#11 token requires a PIN, this can be provided at build time by
111 means of the ``KBUILD_SIGN_PIN`` variable.
112
113
114 (5) :menuselection:`Additional X.509 keys for default system keyring`
115 (``CONFIG_SYSTEM_TRUSTED_KEYS``)
116
117 This option can be set to the filename of a PEM-encoded file containing
118 additional certificates which will be included in the system keyring by
119 default.
120
121 Note that enabling module signing adds a dependency on the OpenSSL devel
122 packages to the kernel build processes for the tool that does the signing.
123
124
125 =======================
126 Generating signing keys
127 =======================
128
129 Cryptographic keypairs are required to generate and check signatures. A
130 private key is used to generate a signature and the corresponding public key is
131 used to check it. The private key is only needed during the build, after which
132 it can be deleted or stored securely. The public key gets built into the
133 kernel so that it can be used to check the signatures as the modules are
134 loaded.
135
136 Under normal conditions, when ``CONFIG_MODULE_SIG_KEY`` is unchanged from its
137 default, the kernel build will automatically generate a new keypair using
138 openssl if one does not exist in the file::
139
140 certs/signing_key.pem
141
142 during the building of vmlinux (the public part of the key needs to be built
143 into vmlinux) using parameters in the::
144
145 certs/x509.genkey
146
147 file (which is also generated if it does not already exist).
148
149 One can select between RSA (``MODULE_SIG_KEY_TYPE_RSA``) and ECDSA
150 (``MODULE_SIG_KEY_TYPE_ECDSA``) to generate either RSA 4k or NIST
151 P-384 keypair.
152
153 It is strongly recommended that you provide your own x509.genkey file.
154
155 Most notably, in the x509.genkey file, the req_distinguished_name section
156 should be altered from the default::
157
158 [ req_distinguished_name ]
159 #O = Unspecified company
160 CN = Build time autogenerated kernel key
161 #emailAddress = [email protected]
162
163 The generated RSA key size can also be set with::
164
165 [ req ]
166 default_bits = 4096
167
168
169 It is also possible to manually generate the key private/public files using the
170 x509.genkey key generation configuration file in the root node of the Linux
171 kernel sources tree and the openssl command. The following is an example to
172 generate the public/private key files::
173
174 openssl req -new -nodes -utf8 -sha256 -days 36500 -batch -x509 \
175 -config x509.genkey -outform PEM -out kernel_key.pem \
176 -keyout kernel_key.pem
177
178 The full pathname for the resulting kernel_key.pem file can then be specified
179 in the ``CONFIG_MODULE_SIG_KEY`` option, and the certificate and key therein will
180 be used instead of an autogenerated keypair.
181
182
183 =========================
184 Public keys in the kernel
185 =========================
186
187 The kernel contains a ring of public keys that can be viewed by root. They're
188 in a keyring called ".builtin_trusted_keys" that can be seen by::
189
190 [root@deneb ~]# cat /proc/keys
191 ...
192 223c7853 I------ 1 perm 1f030000 0 0 keyring .builtin_trusted_keys: 1
193 302d2d52 I------ 1 perm 1f010000 0 0 asymmetri Fedora kernel signing key: d69a84e6bce3d216b979e9505b3e3ef9a7118079: X509.RSA a7118079 []
194 ...
195
196 Beyond the public key generated specifically for module signing, additional
197 trusted certificates can be provided in a PEM-encoded file referenced by the
198 ``CONFIG_SYSTEM_TRUSTED_KEYS`` configuration option.
199
200 Further, the architecture code may take public keys from a hardware store and
201 add those in also (e.g. from the UEFI key database).
202
203 Finally, it is possible to add additional public keys by doing::
204
205 keyctl padd asymmetric "" [.builtin_trusted_keys-ID] <[key-file]
206
207 e.g.::
208
209 keyctl padd asymmetric "" 0x223c7853 <my_public_key.x509
210
211 Note, however, that the kernel will only permit keys to be added to
212 ``.builtin_trusted_keys`` **if** the new key's X.509 wrapper is validly signed by a key
213 that is already resident in the ``.builtin_trusted_keys`` at the time the key was added.
214
215
216 ========================
217 Manually signing modules
218 ========================
219
220 To manually sign a module, use the scripts/sign-file tool available in
221 the Linux kernel source tree. The script requires 4 arguments:
222
223 1. The hash algorithm (e.g., sha256)
224 2. The private key filename or PKCS#11 URI
225 3. The public key filename
226 4. The kernel module to be signed
227
228 The following is an example to sign a kernel module::
229
230 scripts/sign-file sha512 kernel-signkey.priv \
231 kernel-signkey.x509 module.ko
232
233 The hash algorithm used does not have to match the one configured, but if it
234 doesn't, you should make sure that hash algorithm is either built into the
235 kernel or can be loaded without requiring itself.
236
237 If the private key requires a passphrase or PIN, it can be provided in the
238 $KBUILD_SIGN_PIN environment variable.
239
240
241 ============================
242 Signed modules and stripping
243 ============================
244
245 A signed module has a digital signature simply appended at the end. The string
246 ``~Module signature appended~.`` at the end of the module's file confirms that a
247 signature is present but it does not confirm that the signature is valid!
248
249 Signed modules are BRITTLE as the signature is outside of the defined ELF
250 container. Thus they MAY NOT be stripped once the signature is computed and
251 attached. Note the entire module is the signed payload, including any and all
252 debug information present at the time of signing.
253
254
255 ======================
256 Loading signed modules
257 ======================
258
259 Modules are loaded with insmod, modprobe, ``init_module()`` or
260 ``finit_module()``, exactly as for unsigned modules as no processing is
261 done in userspace. The signature checking is all done within the kernel.
262
263
264 =========================================
265 Non-valid signatures and unsigned modules
266 =========================================
267
268 If ``CONFIG_MODULE_SIG_FORCE`` is enabled or module.sig_enforce=1 is supplied on
269 the kernel command line, the kernel will only load validly signed modules
270 for which it has a public key. Otherwise, it will also load modules that are
271 unsigned. Any module for which the kernel has a key, but which proves to have
272 a signature mismatch will not be permitted to load.
273
274 Any module that has an unparsable signature will be rejected.
275
276
277 =========================================
278 Administering/protecting the private key
279 =========================================
280
281 Since the private key is used to sign modules, viruses and malware could use
282 the private key to sign modules and compromise the operating system. The
283 private key must be either destroyed or moved to a secure location and not kept
284 in the root node of the kernel source tree.
285
286 If you use the same private key to sign modules for multiple kernel
287 configurations, you must ensure that the module version information is
288 sufficient to prevent loading a module into a different kernel. Either
289 set ``CONFIG_MODVERSIONS=y`` or ensure that each configuration has a different
290 kernel release string by changing ``EXTRAVERSION`` or ``CONFIG_LOCALVERSION``.
291

3. 한국어 전문 번역

영어 원문의 문단 순서와 의미를 유지한 전체 번역입니다. 코드, 함수명, symbol과 URL은 원문 표기를 유지합니다.

문서 제목과 원문 목차

1-15

이 문서는 kernel module signing facility의 구성, 키 생성과 배포, module 서명·적재 정책, 개인 키 보호를 다룹니다. 원문의 RST 주석에는 다음 항목이 목차로 남아 있습니다.

원문 목차 항목다루는 내용
Overview기능의 보안 목적과 지원 인증서·서명·해시 알고리즘
Configuring module signingKconfig 정책, 자동 서명, 해시와 키 선택
Generating signing keys자동·수동 X.509 keypair 생성
Public keys in the kernel내장 trusted keyring 조회와 키 추가
Manually signing modules`scripts/sign-file` 인자와 사용 예
Signed modules and stripping서명 배치 방식과 strip 금지
Loading signed modules일반 module loading 경로와 kernel 내부 검증
Non-valid signatures and unsigned modules강제 정책, unsigned module, signature mismatch 처리
Administering/protecting the private key개인 키 폐기·보관과 여러 kernel 구성에서의 격리

개요

16-35

Kernel module signing facility는 설치할 때 module에 cryptographic signature를 붙이고 module을 load할 때 그 signature를 검사합니다. 따라서 unsigned module이나 유효하지 않은 키로 서명된 module의 load를 막아 악성 module을 kernel에 넣기 어렵게 만듭니다. 검사는 kernel이 직접 수행하므로 신뢰할 userspace 구성 요소가 따로 필요하지 않습니다.

공개 키는 X.509 ITU-T 표준 certificate로 인코딩합니다. Signature 자체는 산업 표준 형식으로 인코딩되지 않습니다. Built-in facility가 현재 지원하는 공개 키 서명 표준은 RSA와 NIST P-384 ECDSA이며, 구조는 pluggable이어서 다른 방식도 추가할 수 있습니다. Hash는 signature 안의 데이터가 선택하며 SHA-2와 SHA-3의 256·384·512 bit를 사용할 수 있습니다.

Module signing 구성

36-124

Kernel configuration의 `Enable Loadable Module Support`에서 다음 항목을 켜 module signature verification을 활성화합니다.

CONFIG_MODULE_SIG	"Module signature verification"
설정메뉴 항목동작과 운영 의미
`CONFIG_MODULE_SIG_FORCE`Require modules to be validly signedOff인 permissive mode에서는 알 수 없는 키로 서명됐거나 unsigned인 module도 허용하지만 kernel과 module을 `E` taint로 표시합니다. On인 restrictive mode에서는 kernel이 보유한 공개 키로 유효하게 검증되는 module만 load합니다. 어느 mode든 signature block을 parse할 수 없으면 즉시 거부합니다.
`CONFIG_MODULE_SIG_ALL`Automatically sign all modulesOn이면 build의 `modules_install` 단계에서 모든 module을 자동 서명합니다. Off이면 `scripts/sign-file`로 수동 서명해야 합니다.
Module signing hash 선택Which hash algorithm should modules be signed with?설치 단계의 서명 hash를 SHA-2 또는 SHA-3의 256·384·512 bit 중에서 고릅니다. 선택한 알고리즘은 dependency loop 없이 signature를 검사할 수 있도록 module이 아니라 kernel에 built-in됩니다.
`CONFIG_MODULE_SIG_KEY`File name or PKCS#11 URI of module signing key기본 `certs/signing_key.pem`을 다른 값으로 바꾸면 자동 key 생성을 끄고 지정한 키를 사용합니다. 값은 private key와 대응 X.509 certificate를 함께 담은 PEM 파일이거나, OpenSSL `ENGINE_pkcs11`이 동작하는 시스템에서는 certificate와 private key를 모두 가리키는 RFC7512 PKCS#11 URI여야 합니다. 암호화된 PEM의 passphrase 또는 token PIN은 `KBUILD_SIGN_PIN`으로 제공합니다.
`CONFIG_SYSTEM_TRUSTED_KEYS`Additional X.509 keys for default system keyring기본 system keyring에 포함할 추가 certificate를 담은 PEM 파일 이름을 지정합니다.

`CONFIG_MODULE_SIG_ALL`을 끈 경우 수동 서명에 사용하는 도구는 다음과 같습니다.

scripts/sign-file
Kconfig symbol설치 단계 서명 hash
`CONFIG_MODULE_SIG_SHA256`SHA-256
`CONFIG_MODULE_SIG_SHA384`SHA-384
`CONFIG_MODULE_SIG_SHA512`SHA-512
`CONFIG_MODULE_SIG_SHA3_256`SHA3-256
`CONFIG_MODULE_SIG_SHA3_384`SHA3-384
`CONFIG_MODULE_SIG_SHA3_512`SHA3-512

선택한 hash algorithm은 signature 검사 중 자신을 load해야 하는 dependency loop가 생기지 않도록 kernel에 built-in됩니다. `CONFIG_MODULE_SIG_KEY`의 PKCS#11 URI는 RFC7512를 따르며 certificate와 private key를 모두 참조해야 합니다.

Module signing을 켜면 서명 도구를 build하기 위해 kernel build process가 OpenSSL development package에 의존합니다.

서명 키 생성

125-181

Signature 생성에는 private key를, 검증에는 대응하는 public key를 사용합니다. Private key는 build 때만 필요하므로 이후 폐기하거나 안전하게 보관할 수 있습니다. Public key는 module load 시 signature를 확인할 수 있도록 kernel에 built-in됩니다.

`CONFIG_MODULE_SIG_KEY`가 기본값이면 vmlinux build 과정에서 다음 파일에 keypair가 없을 때 openssl로 새 keypair를 자동 생성합니다.

certs/signing_key.pem

Public key 부분을 vmlinux에 넣어야 하므로 key 생성에는 다음 설정 파일의 parameter를 사용합니다. 파일이 없으면 이 설정 파일도 자동 생성됩니다.

certs/x509.genkey

`MODULE_SIG_KEY_TYPE_RSA`와 `MODULE_SIG_KEY_TYPE_ECDSA` 중 하나를 선택해 RSA 4k 또는 NIST P-384 keypair를 생성할 수 있습니다. 자체 `x509.genkey` 파일을 제공하는 것을 강하게 권장합니다.

특히 `x509.genkey`의 `req_distinguished_name` section은 기본값에서 조직 환경에 맞게 바꿔야 합니다.

[ req_distinguished_name ]
#O = Unspecified company
CN = Build time autogenerated kernel key
#emailAddress = [email protected]

생성할 RSA key size도 `req` section에서 지정할 수 있습니다.

[ req ]
default_bits = 4096

Linux kernel source tree의 root에 있는 `x509.genkey`와 openssl을 사용해 private/public key 파일을 수동 생성할 수도 있습니다.

openssl req -new -nodes -utf8 -sha256 -days 36500 -batch -x509 \
-config x509.genkey -outform PEM -out kernel_key.pem \
-keyout kernel_key.pem

생성된 `kernel_key.pem`의 전체 경로를 `CONFIG_MODULE_SIG_KEY`에 지정하면 자동 생성 keypair 대신 그 파일의 certificate와 key를 사용합니다.

Kernel의 공개 키

182-214

Kernel에는 root가 볼 수 있는 공개 키 ring이 있습니다. 이름은 `.builtin_trusted_keys`이며 `/proc/keys`에서 다음과 같이 확인합니다.

[root@deneb ~]# cat /proc/keys
...
223c7853 I------     1 perm 1f030000     0     0 keyring   .builtin_trusted_keys: 1
302d2d52 I------     1 perm 1f010000     0     0 asymmetri Fedora kernel signing key: d69a84e6bce3d216b979e9505b3e3ef9a7118079: X509.RSA a7118079 []
...

Module signing 전용으로 생성한 공개 키 외에도 `CONFIG_SYSTEM_TRUSTED_KEYS`가 가리키는 PEM 파일의 trusted certificate를 추가할 수 있습니다. Architecture code는 UEFI key database 같은 hardware store의 공개 키도 keyring에 넣을 수 있습니다.

추가 공개 키는 `keyctl padd asymmetric`로 넣습니다.

keyctl padd asymmetric "" [.builtin_trusted_keys-ID] <[key-file]

다음은 `.builtin_trusted_keys` ID가 `0x223c7853`인 경우의 예입니다.

keyctl padd asymmetric "" 0x223c7853 <my_public_key.x509

단, kernel은 새 key의 X.509 wrapper가 추가 시점에 이미 `.builtin_trusted_keys`에 들어 있는 key로 유효하게 서명된 경우에만 그 새 key를 `.builtin_trusted_keys`에 넣도록 허용합니다.

Module 수동 서명

215-239

Linux kernel source tree의 `scripts/sign-file` 도구로 module을 수동 서명합니다. 이 도구에는 다음 네 인자가 필요합니다.

순서인자
1Hash algorithm`sha256`, `sha512` 등
2Private keyPrivate key filename 또는 PKCS#11 URI
3Public keyPublic key filename
4Module서명할 kernel module 파일

다음 예는 SHA-512로 `module.ko`를 서명합니다.

scripts/sign-file sha512 kernel-signkey.priv \
kernel-signkey.x509 module.ko

여기서 사용하는 hash algorithm이 kernel configuration에서 선택한 것과 같을 필요는 없습니다. 다만 다르다면 그 hash algorithm이 kernel에 built-in되어 있거나, 자기 자신이 필요한 module을 load하지 않고도 먼저 load될 수 있어야 합니다.

Private key에 passphrase 또는 PIN이 필요하면 `$KBUILD_SIGN_PIN` environment variable로 제공합니다.

서명된 module과 stripping

240-253

서명된 module은 digital signature를 파일 끝에 단순히 덧붙입니다. Module 파일 끝의 `~Module signature appended~.` 문자열은 signature가 존재한다는 사실만 확인하며, signature가 유효하다는 뜻은 아닙니다.

Signature가 정의된 ELF container 바깥에 있으므로 서명된 module은 구조적으로 취약합니다. Signature를 계산해 붙인 뒤에는 절대로 strip하면 안 됩니다. 서명 시점에 있던 모든 debug information을 포함한 module 전체가 signed payload입니다.

서명된 module 적재

254-262

서명된 module도 unsigned module과 똑같이 `insmod`, `modprobe`, `init_module()`, `finit_module()`로 load합니다. Userspace에서는 별도 처리를 하지 않으며 signature 검사는 전부 kernel 내부에서 수행합니다.

유효하지 않은 signature와 unsigned module

263-275

`CONFIG_MODULE_SIG_FORCE`를 켰거나 kernel command line에 `module.sig_enforce=1`을 주면 kernel은 자신이 공개 키를 보유하고 있고 유효하게 서명된 module만 load합니다. 그렇지 않으면 unsigned module도 load합니다. Kernel이 검증 키를 갖고 있지만 signature mismatch가 확인된 module은 어떤 경우에도 load하지 않습니다.

Parse할 수 없는 signature가 있는 module도 거부합니다.

Private key 관리와 보호

276-290

바이러스나 malware가 private key를 얻으면 악성 module에 서명해 운영 체제를 침해할 수 있습니다. Private key는 폐기하거나 안전한 위치로 옮겨야 하며 kernel source tree의 root에 보관하면 안 됩니다.

여러 kernel configuration의 module을 같은 private key로 서명한다면 module version information이 다른 kernel에 module을 load하지 못하게 할 만큼 충분해야 합니다. `CONFIG_MODVERSIONS=y`를 설정하거나 `EXTRAVERSION` 또는 `CONFIG_LOCALVERSION`을 바꿔 각 configuration에 서로 다른 kernel release string을 사용하십시오.