CVE Mitigations
Cluster operations — Reference for the administrators and operators who run Nautilus.
This document is the guideline to mitigate CVEs that do not have a released kernel patch.
The repo is in https://gitlab.nrp-nautilus.io/prp/cve-mitigations. It implements one DaemonSet to mitigate multiple CVEs, upon one ConfigMap per CVE. The runner on every node discovers all ConfigMaps labelled mitigation.security/cve and runs each mitigate.sh every CHECK_INTERVAL seconds, so all active mitigations stay enforced.
| File | Contents |
|---|---|
base.yaml | RBAC, runner + shared lib, DaemonSet |
cves/cve-*.yaml | One ConfigMap per CVE (the only files you normally touch) |
cve-template.yaml | Starting point for a new CVE |
Setup
The nrp-security namespace must already exist and allow privileged pods (Pod Security Admission enforce: privileged); base.yaml doesn’t create it. The runner image (alpine:3.20) installs curl/jq at startup; for air-gapped clusters, build an image with them preinstalled and set it in base.yaml.
These scripts run as root on every node, so review changes to cves/ and base.yaml before applying them.
Deploy
Pull the repo from https://gitlab.nrp-nautilus.io/prp/cve-mitigations, update base.yaml or any files in cves if needed, then deploy the changed to the cluster.
Manual deployment
Run these commands to apply updates:
kubectl diff -f base.yaml -f cves/ kubectl apply -f base.yaml -f cves/New or changed CVE ConfigMaps are picked up on the next cycle (CHECK_INTERVAL).
Restart the DaemonSet to apply them now, and always after changing the lib ConfigMap in base.yaml (a running runner keeps the runner.sh it started with):
kubectl rollout restart ds/kernel-cve-mitigation -n nrp-securityCheck that every node reports and nothing is exposed or failed:
kubectl logs -n nrp-security -l app.kubernetes.io/name=kernel-cve-mitigation --prefix | grep SUMMARYDeployment through ArgoCD
The repo is provisioned by ArgoCD(https://argocd.nrp-nautilus.io).
Push all updates to the repo https://gitlab.nrp-nautilus.io/prp/cve-mitigations, and watch the progress of deployment at https://argocd.nrp-nautilus.io/applications/argo/cve-mitigations?resource=
Managing CVE mitigtions
Add a CVE mitigation. Copy cve-template.yaml to cves/cve-yyyy-nnnnn.yaml (the file name, metadata.name, and the lowercased mitigation.security/cve label must match), write the script, and deploy. cve-template.yaml is a template of mitigation in the simpliest case. It unloads and disable modules exploited by a specific CVE. Investigate each new CVE for specific mitigation processes, and customized scripts for individual cases.
Pause a CVE mitigation. Set mitigation.security/enabled: "false" in the corresponding cves/cve-yyyy-nnnnn.yaml file and deploy. On its next cycle the runner stops running it and removes its /etc/modprobe.d / /etc/sysctl.d file.
Retire a CVE mitigation. (nodes patched). Delete its the corresponding cves/cve-yyyy-nnnnn.yaml file from the repo, and the ConfigMap in the kubernetes cluster (kubectl apply never removes it):
kubectl delete cm cve-yyyy-nnnnn -n nrp-securityOn its next cycle the runner removes the config files regarding the CVE in /etc/modprobe.d and /etc/sysctl.d on every node.
Script contract
Sourced after common.sh with $CVE, $HOST, $NODE_NAME, $FORCE_UNLOAD set. Run once and be idempotent. Exit 0 = mitigated, 1 = exposed, other = error. Scripts time out after SCRIPT_TIMEOUT seconds and never block each other. If the kubernetes API is unreachable, the last fetched scripts keep running and nothing is cleaned up.

This work was supported in part by National Science Foundation (NSF) awards CNS-1730158, ACI-1540112, ACI-1541349, OAC-1826967, OAC-2112167, CNS-2100237, CNS-2120019.