
Docker mitigation for CVE-2026-31431 ('Copy Fail') के लिए शमन उपाय। इसमें Kubernetes टेम्पलेट भी शामिल हैं।
सभी Docker कंटेनरों के लिए AF_ALG सॉकेट निर्माण को ब्लॉक करने के लिए इडेम्पोटेंट स्क्रिप्ट, जो CVE-2026-31431 ("Copy Fail") के शमन के रूप में होस्ट पर चलती है।
CVE-2026-31431 Linux कर्नेल के authencesn क्रिप्टोग्राफिक टेम्पलेट में एक स्थानीय विशेषाधिकार वृद्धि है, जो 2017 और अपस्ट्रीम फिक्स (मेनलाइन कमिट a664bf3d603d) की उपलब्धता के बीच निर्मित कर्नेल में मौजूद है। एक अन-प्रिविलेज्ड उपयोगकर्ता AF_ALG सॉकेट ऑपरेशन को splice() के साथ जोड़कर किसी भी पठनीय फ़ाइल के पेज कैश में नियंत्रित 4-बाइट लेखन कर सकता है, जिससे setuid बाइनरी को लक्षित करके रूट शेल प्राप्त किया जा सकता है। एक 732-बाइट Python प्रूफ ऑफ कॉन्सेप्ट इसे बिना रेस या प्रति-डिस्ट्रो ऑफसेट के, प्रभावित कर्नेल वितरित करने वाले हर प्रमुख Linux वितरण पर विश्वसनीय रूप से शोषित करता है।
एक्सप्लॉइट का अनिवार्य पहला चरण AF_ALG सॉकेट खोलना है (socket(AF_ALG, SOCK_SEQPACKET, 0))। seccomp के माध्यम से उस syscall को ब्लॉक करना अनपैच्ड कर्नेल पर भी शोषण को रोकता है। Docker का अंतर्निहित डिफ़ॉल्ट seccomp प्रोफ़ाइल AF_ALG को ब्लॉक नहीं करता है, और RuntimeDefault पर्याप्त नहीं है — परीक्षण किए गए क्लस्टरों ने दिखाया कि PSS Restricted के तहत स्वीकार किए गए पॉड अभी भी AF_ALG सॉकेट खोल सकते हैं।
पूर्ण तकनीकी विवरण और वितरण द्वारा पैच उपलब्धता के लिए मूल शोधकर्ता सलाह https://copy.fail और CERT-EU सलाह https://cert.europa.eu/publications/security-advisories/2026-005/ देखें।
यह स्क्रिप्ट Docker Engine के वैश्विक डेमन कॉन्फ़िगरेशन को कवर करती है। Kubernetes के लिए, नीचे Kubernetes अनुभाग देखें। बेयर-मेटल या VM वर्कलोड (गैर-कंटेनरीकृत) के लिए, इसके बजाय algif_aead कर्नेल मॉड्यूल को अक्षम करें:
echo "install algif_aead /bin/false" > /etc/modprobe.d/disable-algif.conf
rmmod algif_aead 2>/dev/null || true
उस दृष्टिकोण का dm-crypt/LUKS, kTLS, IPsec/XFRM, OpenSSL, GnuTLS, NSS, या SSH पर कोई प्रभाव नहीं पड़ता है।
Docker के सक्रिय अंतर्निहित seccomp प्रोफ़ाइल को निकालता है एक अल्पकालिक कंटेनर के HostConfig.SecurityOpt का निरीक्षण करके। यह किसी दूरस्थ URL पर किसी भी निर्भरता से बचता है और गारंटी देता है कि आधार प्रोफ़ाइल वास्तव में स्थापित Docker संस्करण से मेल खाती है। moby/profiles से GitHub फ़ेच केवल फ़ॉलबैक के रूप में उपयोग किया जाता है यदि कंटेनर निरीक्षण से कुछ नहीं मिलता है।
प्रोफ़ाइल को पैच करता है Docker की अनुमति सूची प्रविष्टि से socket को हटाकर और इसे एक तर्क फ़िल्टर के साथ फिर से जोड़कर जो AF_ALG (मान 38) को छोड़कर सभी एड्रेस फ़ैमिली की अनुमति देता है, SCMP_CMP_NE का उपयोग करके। अन्य सभी Docker डिफ़ॉल्ट seccomp व्यवहार संरक्षित है।
पैच किए गए प्रोफ़ाइल को परमाणु रूप से लिखता है /etc/seccomp/docker-block-af-alg.json पर (अस्थायी फ़ाइल + rename)। यदि डिस्क पर मौजूद सामग्री पहले से समान है तो छोड़ दिया जाता है।
/etc/docker/daemon.json को अपडेट करता है ताकि "seccomp-profile" को पैच किए गए प्रोफ़ाइल पथ पर सेट किया जा सके। पहले संशोधन पर मूल फ़ाइल का बैकअप daemon.json.bak में लिया जाता है। यदि पहले से सही ढंग से कॉन्फ़िगर किया गया है तो छोड़ दिया जाता है।
dockerd को रीलोड करता है systemctl reload docker के माध्यम से (SIGHUP — कोई पुनरारंभ आवश्यक नहीं)। यदि कोई भी फ़ाइल नहीं बदली है तो छोड़ दिया जाता है।
ब्लॉक के सक्रिय होने की पुष्टि करता है एक कंटेनर के अंदर एक प्रोब चलाकर, भले ही उपरोक्त चरणों में कोई परिवर्तन किया गया हो या नहीं।
स्क्रिप्ट इडेम्पोटेंट है: इसे कई बार चलाने से समान परिणाम मिलता है और केवल तभी Docker को रीलोड करता है जब वास्तव में कुछ बदला गया हो।
नोट:
--privilegedकंटेनर इस कॉन्फ़िगरेशन की परवाह किए बिना सभी seccomp प्रोफ़ाइल को बायपास करते हैं। अपनी Compose फ़ाइलों का ऑडिट करें और प्रिविलेज्ड कंटेनरों के लिए कमांड अलग से चलाएं।
PATH में docker CLIPATH में curl (केवल फ़ॉलबैक)systemctl (systemd होस्ट)/etc/seccomp और /etc/docker में लेखन के लिए रूट / sudo, और systemctl reload docker के लिए# शमन लागू करें और सत्यापित करें (सामान्य उपयोग)
sudo python3 harden-docker-seccomp.py
# कुछ भी लिखे या Docker को रीलोड किए बिना दिखाएं कि क्या बदलेगा
sudo python3 harden-docker-seccomp.py --dry-run
# केवल कंटेनर सत्यापन फिर से चलाएं (कोई कॉन्फ़िग परिवर्तन नहीं)
python3 harden-docker-seccomp.py --verify-only
# विस्तृत आउटपुट
sudo python3 harden-docker-seccomp.py --verbose
INFO Written: /etc/seccomp/docker-block-af-alg.json
INFO Updated: /etc/docker/daemon.json
INFO Reloading Docker daemon (SIGHUP)…
INFO Docker daemon reloaded.
INFO Verifying AF_ALG is blocked inside a container…
OK: AF_ALG blocked — [Errno 1] Operation not permitted
INFO All done. CVE-2026-31431 (Copy Fail) mitigation is active.
INFO Profile unchanged: /etc/seccomp/docker-block-af-alg.json
INFO daemon.json already configured correctly.
INFO No changes — Docker daemon reload not required.
INFO Verifying AF_ALG is blocked inside a container…
OK: AF_ALG blocked — [Errno 1] Operation not permitted
INFO All done. CVE-2026-31431 (Copy Fail) mitigation is active.
| कोड | अर्थ |
|---|---|
0 | सफलता — शमन सक्रिय है |
1 | स्क्रिप्ट रूट के रूप में नहीं चलाई गई (पैचिंग करते समय), या अपरिवर्तनीय त्रुटि |
2 | सत्यापन विफल — AF_ALG ब्लॉक नहीं है |
Kubernetes पॉड होस्ट कर्नेल साझा करते हैं, इसलिए वही AF_ALG सॉकेट प्रिमिटिव प्रभावित नोड पर किसी भी पॉड से पहुंच योग्य है। RuntimeDefault seccomp पर्याप्त नहीं है — परीक्षण किए गए क्लस्टरों ने दिखाया कि PSS Restricted के तहत स्वीकार किए गए पॉड अभी भी AF_ALG सॉकेट खोल सकते हैं। स्पष्ट अस्वीकृति नियम के साथ एक Localhost प्रोफ़ाइल आवश्यक है।
शमन के लिए दो चीजों की आवश्यकता होती है: प्रोफ़ाइल JSON हर नोड के फ़ाइल सिस्टम पर मौजूद होना, और हर पॉड स्पेक उसका संदर्भ देना। नीचे दिए गए अनुभाग दोनों को कवर करते हैं, जिसमें व्यक्तिगत पॉड स्पेक को संशोधित किए बिना प्रोफ़ाइल को वैश्विक रूप से इंजेक्ट करने का तरीका भी शामिल है।
kubelet Localhost seccomp प्रोफ़ाइल को अपने seccomp रूट के सापेक्ष हल करता है, जो डिफ़ॉल्ट रूप से /var/lib/kubelet/seccomp है। प्रोफ़ाइल उस पथ पर हर नोड पर मौजूद होनी चाहिए जो वर्कलोड शेड्यूल कर सकता है।
इस रिपॉजिटरी से ConfigMap और DaemonSet लागू करें:
kubectl apply -f templates/configmap-seccomp-profile.yaml
kubectl apply -f templates/daemonset-distribute-profile.yaml
DaemonSet एक init कंटेनर चलाता है जो प्रोफ़ाइल को ConfigMap से नोड के kubelet seccomp रूट में कॉपी करता है, फिर एक न्यूनतम pause कंटेनर पार्क करता है ताकि पॉड स्वास्थ्य निगरानी के लिए दृश्यमान रहे। यह सभी टेंट्स को सहन करता है ताकि यह कंट्रोल-प्लेन नोड्स पर भी चले।
गैर-मानक kubelet seccomp रूट: RKE2
/var/lib/rancher/rke2/agent/kubelet/seccompका उपयोग करता है। लागू करने से पहले DaemonSet के init कंटेनर env मेंNODE_SECCOMP_ROOTसेट करके पथ को ओवरराइड करें।
किसी नोड पर फ़ाइल की उपस्थिति सत्यापित करें:
kubectl -n kube-system exec -it \
$(kubectl -n kube-system get pod -l app.kubernetes.io/name=distribute-af-alg-seccomp \
-o jsonpath='{.items[0].metadata.name}') -- \
cat /var/lib/kubelet/seccomp/block-af-alg.json
व्यक्तिगत पॉड स्पेक या Helm चार्ट को संशोधित करने के बजाय, प्रवेश समय पर seccompProfile को स्वचालित रूप से इंजेक्ट करने के लिए एक म्यूटेटिंग एडमिशन वेबहुक का उपयोग करें। दो विकल्प प्रदान किए गए हैं: Kyverno और OPA Gatekeeper।
दोनों दृष्टिकोण केवल तभी प्रोफ़ाइल इंजेक्ट करते हैं जब पॉड पहले से एक घोषित नहीं करता है, इसलिए स्पष्ट प्रोफ़ाइल वाले पॉड अछूते रहते हैं।
महत्वपूर्ण: मौजूदा चल रहे पॉड पूर्वव्यापी रूप से म्यूटेट नहीं होते हैं। नीति लागू करने के बाद, इंजेक्ट की गई प्रोफ़ाइल को लेने के लिए अपने डिप्लॉयमेंट को रोल करें:
kubectl rollout restart deployment -A