Skip to content

Commit 67c567d

Browse files
authored
Merge pull request #56972 from StephenJamesSmith/TELCODOCS-1065
TELCODOCS-1065: Create KMMO doc: Secure Boot
2 parents 321012d + 5988cc8 commit 67c567d

7 files changed

+292
-1
lines changed

hardware_enablement/kmm-kernel-module-management.adoc

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ include::_attributes/common-attributes.adoc[]
55
:context: kernel-module-management-operator
66

77

8-
toc::[]
8+
toc::[]
99

1010
Learn about the Kernel Module Management (KMM) Operator and how you can use it to deploy out-of-tree kernel modules and device plugins on {product-title} clusters.
1111

@@ -16,3 +16,13 @@ include::modules/kmm-installation.adoc[leveloffset=+1]
1616
include::modules/kmm-installing-using-web-console.adoc[leveloffset=+2]
1717
include::modules/kmm-installing-using-cli.adoc[leveloffset=+2]
1818
include::modules/kmm-installing-older-versions.adoc[leveloffset=+2]
19+
// Added for TELCODOCS-1065
20+
include::modules/kmm-using-signing-with-kmm.adoc[leveloffset=+1]
21+
include::modules/kmm-adding-the-keys-for-secureboot.adoc[leveloffset=+1]
22+
include::modules/kmm-checking-the-keys.adoc[leveloffset=+2]
23+
include::modules/kmm-signing-a-prebuilt-driver-container.adoc[leveloffset=+1]
24+
include::modules/kmm-building-and-signing-a-moduleloader-container-image.adoc[leveloffset=+1]
25+
.Additional resources
26+
For information on creating a service account, see xref:https://docs.openshift.com/container-platform/4.12/authentication/understanding-and-creating-service-accounts.html#service-accounts-managing_understanding-service-accounts[Creating service accounts].
27+
28+
include::modules/kmm-debugging-and-troubleshooting.adoc[leveloffset=+1]
Lines changed: 78 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,78 @@
1+
// Module included in the following assemblies:
2+
//
3+
// * hardware_enablement/kmm-kernel-module-management.adoc
4+
5+
:_content-type: PROCEDURE
6+
[id="kmm-adding-the-keys-for-secureboot_{context}"]
7+
= Adding the keys for secureboot
8+
9+
To use KMM Kernel Module Management (KMM) to sign kernel modules, a certificate and private key are required. For details on how to create these, see link:https://access.redhat.com/documentation/en-us/red_hat_enterprise_linux/9/html/managing_monitoring_and_updating_the_kernel/signing-a-kernel-and-modules-for-secure-boot_managing-monitoring-and-updating-the-kernel#generating-a-public-and-private-key-pair_signing-a-kernel-and-modules-for-secure-boot[Generating a public and private key pair].
10+
11+
For details on how to extract the public and private key pair, see link:https://access.redhat.com/documentation/en-us/red_hat_enterprise_linux/9/html/managing_monitoring_and_updating_the_kernel/signing-a-kernel-and-modules-for-secure-boot_managing-monitoring-and-updating-the-kernel#signing-kernel-modules-with-the-private-key_signing-a-kernel-and-modules-for-secure-boot[Signing kernel modules with the private key]. Use steps 1 through 4 to extract the keys into files.
12+
13+
.Procedure
14+
15+
. Create the `sb_cert.cer` file that contains the certificate and the `sb_cert.priv` file that contains the private key:
16+
+
17+
[source,terminal]
18+
----
19+
$ openssl req -x509 -new -nodes -utf8 -sha256 -days 36500 -batch -config configuration_file.config -outform DER -out my_signing_key_pub.der -keyout my_signing_key.priv
20+
----
21+
22+
. Add the files by using one of the following methods:
23+
+
24+
* Add the files as link:https://kubernetes.io/docs/concepts/configuration/secret/[secrets] directly:
25+
+
26+
[source,terminal]
27+
----
28+
$ oc create secret generic my-signing-key --from-file=key=<my_signing_key.priv>
29+
----
30+
+
31+
[source,terminal]
32+
----
33+
$ oc create secret generic my-signing-key-pub --from-file=key=<my_signing_key_pub.der>
34+
----
35+
+
36+
* Add the files by base64 encoding them:
37+
+
38+
[source,terminal]
39+
----
40+
$ cat sb_cert.priv | base64 -w 0 > my_signing_key2.base64
41+
----
42+
+
43+
[source,terminal]
44+
----
45+
$ cat sb_cert.cer | base64 -w 0 > my_signing_key_pub.base64
46+
----
47+
48+
. Add the encoded text to a YAML file:
49+
+
50+
[source,yaml]
51+
----
52+
apiVersion: v1
53+
kind: Secret
54+
metadata:
55+
name: my-signing-key-pub
56+
namespace: default <1>
57+
type: Opaque
58+
data:
59+
cert: <base64_encoded_secureboot_public_key>
60+
61+
---
62+
apiVersion: v1
63+
kind: Secret
64+
metadata:
65+
name: my-signing-key
66+
namespace: default <1>
67+
type: Opaque
68+
data:
69+
key: <base64_encoded_secureboot_private_key>
70+
----
71+
<1> `namespace` - Replace `default` with a valid namespace.
72+
73+
. Apply the YAML file:
74+
+
75+
[source,terminal]
76+
----
77+
$ oc apply -f <yaml_filename>
78+
----
Lines changed: 85 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,85 @@
1+
// Module included in the following assemblies:
2+
//
3+
// * hardware_enablement/kmm-kernel-module-management.adoc
4+
5+
:_content-type: PROCEDURE
6+
[id="kmm-building-and-signing-a-moduleloader-container-image_{context}"]
7+
= Building and signing a ModuleLoader container image
8+
9+
Use this procedure if you have source code and must build your image first.
10+
11+
The following YAML file builds a new container image using the source code from the repository. The image produced is saved back in the registry with a temporary name, and this temporary image is then signed using the parameters in the `sign` section.
12+
13+
The temporary image name is based on the final image name and is set to be `<containerImage>:<tag>-<namespace>_<module name>_kmm_unsigned`.
14+
15+
For example, using the following YAML file, Kernel Module Management (KMM) builds an image named `example.org/repository/minimal-driver:final-default_example-module_kmm_unsigned` containing the build with unsigned kmods and push it to the registry. Then it creates a second image named `example.org/repository/minimal-driver:final` that contains the signed kmods. It is this second image that is loaded by the `DaemonSet` object and deploys the kmods to the cluster nodes.
16+
17+
After it is signed, the temporary image can be safely deleted from the registry. It will be rebuilt, if needed.
18+
19+
.Prerequisites
20+
21+
* The `keySecret` and `certSecret` secrets have been created.
22+
23+
.Procedure
24+
25+
. Apply the YAML file:
26+
+
27+
[source,yaml]
28+
----
29+
---
30+
apiVersion: v1
31+
kind: ConfigMap
32+
metadata:
33+
name: example-module-dockerfile
34+
namespace: default <1>
35+
data:
36+
Dockerfile: |
37+
ARG DTK_AUTO
38+
ARG KERNEL_VERSION
39+
FROM ${DTK_AUTO} as builder
40+
WORKDIR /build/
41+
RUN git clone -b main --single-branch https://github.com/rh-ecosystem-edge/kernel-module-management.git
42+
WORKDIR kernel-module-management/ci/kmm-kmod/
43+
RUN make
44+
FROM registry.access.redhat.com/ubi8/ubi:latest
45+
ARG KERNEL_VERSION
46+
RUN yum -y install kmod && yum clean all
47+
RUN mkdir -p /opt/lib/modules/${KERNEL_VERSION}
48+
COPY --from=builder /build/kernel-module-management/ci/kmm-kmod/*.ko /opt/lib/modules/${KERNEL_VERSION}/
49+
RUN /usr/sbin/depmod -b /opt
50+
---
51+
apiVersion: kmm.sigs.x-k8s.io/v1beta1
52+
kind: Module
53+
metadata:
54+
name: example-module
55+
namespace: default <1>
56+
spec:
57+
moduleLoader:
58+
serviceAccountName: default <2>
59+
container:
60+
modprobe:
61+
moduleName: simple_kmod
62+
kernelMappings:
63+
- regexp: '^.*\.x86_64$'
64+
containerImage: < the name of the final driver container to produce>
65+
build:
66+
dockerfileConfigMap:
67+
name: example-module-dockerfile
68+
sign:
69+
keySecret:
70+
name: <private key secret name>
71+
certSecret:
72+
name: <certificate secret name>
73+
filesToSign:
74+
- /opt/lib/modules/4.18.0-348.2.1.el8_5.x86_64/kmm_ci_a.ko
75+
imageRepoSecret: <3>
76+
name: repo-pull-secret
77+
selector: # top-level selector
78+
kubernetes.io/arch: amd64
79+
----
80+
81+
<1> `namespace` - Replace `default` with a valid namespace.
82+
83+
<2> `serviceAccountName` - The default `serviceAccountName` does not have the required permissions to run a module that is privileged. For information on creating a service account, see "Creating service accounts" in the "Additional resources" of this section.
84+
85+
<3> `imageRepoSecret` - Used as `imagePullSecrets` in the `DaemonSet` object and to pull and push for the build and sign features.

modules/kmm-checking-the-keys.adoc

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
// Module included in the following assemblies:
2+
//
3+
// * hardware_enablement/kmm-kernel-module-management.adoc
4+
5+
:_content-type: PROCEDURE
6+
[id="kmm-checking-the-keys_{context}"]
7+
= Checking the keys
8+
9+
After you have added the keys, you must check them to ensure they are set correctly.
10+
11+
.Procedure
12+
13+
. Check to ensure the public key secret is set correctly:
14+
+
15+
[source,terminal]
16+
----
17+
$ oc get secret -o yaml <certificate secret name> | awk '/cert/{print $2; exit}' | base64 -d | openssl x509 -inform der -text
18+
----
19+
+
20+
This should display a certificate with a Serial Number, Issuer, Subject, and more.
21+
22+
. Check to ensure the private key secret is set correctly:
23+
+
24+
[source,terminal]
25+
----
26+
$ oc get secret -o yaml <private key secret name> | awk '/key/{print $2; exit}' | base64 -d
27+
----
28+
+
29+
This should display the key enclosed in the `-----BEGIN PRIVATE KEY-----` and `-----END PRIVATE KEY-----` lines.
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
// Module included in the following assemblies:
2+
//
3+
// * hardware_enablement/kmm-kernel-module-management.adoc
4+
5+
:_content-type: CONCEPT
6+
[id="kmm-debugging-and-troubleshooting_{context}"]
7+
= Debugging and troubleshooting
8+
9+
If the kmods in your driver container are not signed or are signed with the wrong key, then the container can enter a `PostStartHookError` or `CrashLoopBackOff` status. You can verify by running the `oc describe` command on your container, which displays the following message in this scenario:
10+
11+
[source,terminal]
12+
----
13+
modprobe: ERROR: could not insert '<your_kmod_name>': Required key not available
14+
----
Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
// Module included in the following assemblies:
2+
//
3+
// * hardware_enablement/kmm-kernel-module-management.adoc
4+
5+
:_content-type: PROCEDURE
6+
[id="kmm-signing-a-prebuilt-driver-container_{context}"]
7+
= Signing a pre-built driver container
8+
9+
Use this procedure if you have a pre-built image, such as an image either distributed by a hardware vendor or built elsewhere.
10+
11+
The following YAML file adds the public/private key-pair as secrets with the required key names - `key` for the private key, `cert` for the public key. The cluster then pulls down the `unsignedImage` image, opens it, signs the kernel modules listed in `filesToSign`, adds them back, and pushes the resulting image as `containerImage`.
12+
13+
14+
Kernel Module Management (KMM) should then deploy the DaemonSet that loads the signed kmods onto all the nodes that match the selector. The driver containers should run successfully on any nodes that have the public key in their MOK database, and any nodes that are not secure-boot enabled, which ignore the signature. They should fail to load on any that have secure-boot enabled but do not have that key in their MOK database.
15+
16+
.Prerequisites
17+
18+
* The `keySecret` and `certSecret` secrets have been created.
19+
20+
.Procedure
21+
22+
. Apply the YAML file:
23+
+
24+
[source,yaml]
25+
----
26+
---
27+
apiVersion: kmm.sigs.x-k8s.io/v1beta1
28+
kind: Module
29+
metadata:
30+
name: example-module
31+
spec:
32+
moduleLoader:
33+
serviceAccountName: default
34+
container:
35+
modprobe: <1>
36+
moduleName: '<your module name>'
37+
kernelMappings:
38+
# the kmods will be deployed on all nodes in the cluster with a kernel that matches the regexp
39+
- regexp: '^.*\.x86_64$'
40+
# the container to produce containing the signed kmods
41+
containerImage: <image name e.g. quay.io/myuser/my-driver:<kernelversion>-signed>
42+
sign:
43+
# the image containing the unsigned kmods (we need this because we are not building the kmods within the cluster)
44+
unsignedImage: <image name e.g. quay.io/myuser/my-driver:<kernelversion> >
45+
keySecret: # a secret holding the private secureboot key with the key 'key'
46+
name: <private key secret name>
47+
certSecret: # a secret holding the public secureboot key with the key 'cert'
48+
name: <certificate secret name>
49+
filesToSign: # full path within the unsignedImage container to the kmod(s) to sign
50+
- /opt/lib/modules/4.18.0-348.2.1.el8_5.x86_64/kmm_ci_a.ko
51+
imageRepoSecret:
52+
# the name of a secret containing credentials to pull unsignedImage and push containerImage to the registry
53+
name: repo-pull-secret
54+
selector:
55+
kubernetes.io/arch: amd64
56+
----
57+
58+
<1> `modprobe` - The name of the kmod to load.
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
// Module included in the following assemblies:
2+
//
3+
// * hardware_enablement/kmm-kernel-module-management.adoc
4+
5+
:_content-type: CONCEPT
6+
[id="kmm-using-signing-with-kmm_{context}"]
7+
= Using signing with Kernel Module Management (KMM)
8+
9+
On a Secure Boot enabled system, all kernel modules (kmods) must be signed with a public/private key-pair enrolled into the Machine Owner's Key (MOK) database. Drivers distributed as part of a distribution should already be signed by the distribution's private key, but for kernel modules build out-of-tree, KMM supports signing kernel modules using the `sign` section of the kernel mapping.
10+
11+
For more details on using Secure Boot, see link:https://access.redhat.com/documentation/en-us/red_hat_enterprise_linux/9/html/managing_monitoring_and_updating_the_kernel/signing-a-kernel-and-modules-for-secure-boot_managing-monitoring-and-updating-the-kernel#generating-a-public-and-private-key-pair_signing-a-kernel-and-modules-for-secure-boot[Generating a public and private key pair]
12+
13+
.Prerequisites
14+
15+
* A public private key pair in the correct (DER) format.
16+
* At least one secure-boot enabled node with the public key enrolled in its MOK database.
17+
* Either a pre-built driver container image, or the source code and `Dockerfile` needed to build one in-cluster.

0 commit comments

Comments
 (0)