ทุกสิ่งที่คุณต้องการมีการอธิบายไว้ที่นี่
KERNEL MODULE การลงนามสิ่งอำนวยความสะดวก
สารบัญ
- ภาพรวม
- การกำหนดค่าการเซ็นชื่อโมดูล
- กำลังสร้างกุญแจเซ็น
- กุญแจสาธารณะในเคอร์เนล
- การเซ็นชื่อโมดูลด้วยตนเอง
- โมดูลที่ลงนามและการปอก
- กำลังโหลดโมดูลที่เซ็นชื่อ
- ลายเซ็นที่ไม่ถูกต้องและโมดูลที่ไม่ได้ลงชื่อ
- การจัดการ / การปกป้องคีย์ส่วนตัว
ภาพรวม
สิ่งอำนวยความสะดวกการลงนามโมดูลเคอร์เนลเซ็นชื่อโมดูลการเข้ารหัสระหว่างการติดตั้งและจากนั้นตรวจสอบลายเซ็นเมื่อโหลดโมดูล สิ่งนี้ทำให้การรักษาความปลอดภัยเคอร์เนลเพิ่มขึ้นโดยไม่อนุญาตให้โหลดโมดูลหรือโมดูลที่ไม่ได้รับการเซ็นรับรองด้วยคีย์ที่ไม่ถูกต้อง การเซ็นชื่อโมดูลเพิ่มความปลอดภัยโดยทำให้การโหลดโมดูลที่เป็นอันตรายเข้าไปในเคอร์เนลได้ยากขึ้น การตรวจสอบลายเซ็นของโมดูลทำได้โดยเคอร์เนลเพื่อไม่ให้มีบิตผู้ใช้ที่เชื่อถือได้
สิ่งอำนวยความสะดวกนี้ใช้ใบรับรองมาตรฐาน X.509 ITU-T เพื่อเข้ารหัสกุญแจสาธารณะที่เกี่ยวข้อง ลายเซ็นต์นั้นไม่ได้เข้ารหัสด้วยตนเองในรูปแบบมาตรฐานอุตสาหกรรมใด ๆ ขณะนี้เครื่องมืออำนวยความสะดวกรองรับมาตรฐานการเข้ารหัสคีย์สาธารณะของ RSA เท่านั้น (แม้ว่าจะเสียบปลั๊กได้และอนุญาตให้ผู้อื่นใช้งานได้) อัลกอริทึมการแฮชที่เป็นไปได้ที่สามารถใช้ได้คือ SHA-1, SHA-224, SHA-256, SHA-384 และ SHA-512 (อัลกอริทึมถูกเลือกโดยข้อมูลในลายเซ็น)
การกำหนดค่าการลงชื่อโมดูล
สิ่งอำนวยความสะดวกการเซ็นชื่อโมดูลถูกเปิดใช้งานโดยไปที่ส่วน "เปิดใช้งานการสนับสนุนโมดูลที่ใส่ได้" ของการกำหนดค่าเคอร์เนลและการเปิด
CONFIG_MODULE_SIG "Module signature verification"
มีตัวเลือกให้เลือกมากมาย:
"ต้องใช้โมดูลที่จะเซ็นอย่างถูกต้อง" (CONFIG_MODULE_SIG_FORCE)
สิ่งนี้ระบุว่าเคอร์เนลควรจัดการกับโมดูลที่มีลายเซ็นซึ่งไม่รู้จักคีย์หรือโมดูลที่ไม่ได้ลงนาม
หากสิ่งนี้ถูกปิด (เช่น "อนุญาต") ดังนั้นโมดูลที่คีย์ไม่พร้อมใช้งานและโมดูลที่ไม่ได้รับอนุญาตจะได้รับอนุญาต แต่เคอร์เนลจะถูกทำเครื่องหมายว่าไม่บริสุทธิ์และโมดูลที่เกี่ยวข้องจะถูกทำเครื่องหมายว่าไม่บริสุทธิ์แสดง ด้วยตัวละคร 'E'
หากนี่เป็น (เช่น "จำกัด ") เฉพาะโมดูลที่มีลายเซ็นที่ถูกต้องที่สามารถตรวจสอบได้โดยกุญแจสาธารณะในความครอบครองของเคอร์เนลเท่านั้นที่จะถูกโหลด โมดูลอื่น ๆ ทั้งหมดจะสร้างข้อผิดพลาด
โดยไม่คำนึงถึงการตั้งค่าที่นี่หากโมดูลมีบล็อกลายเซ็นที่ไม่สามารถแยกวิเคราะห์มันจะถูกปฏิเสธจากมือ
"ลงชื่อโมดูลทั้งหมดโดยอัตโนมัติ" (CONFIG_MODULE_SIG_ALL)
หากเปิดใช้งานโมดูลจะมีการเซ็นชื่อโดยอัตโนมัติระหว่างเฟส modules_install ของบิลด์ หากนี่เป็นปิดโมดูลจะต้องลงนามด้วยตนเองโดยใช้:
scripts/sign-file
"โมดูลแฮชของอัลกอริธึมใดควรลงนามด้วย"
สิ่งนี้นำเสนอทางเลือกสำหรับอัลกอริทึมแฮชที่ขั้นตอนการติดตั้งจะเซ็นชื่อโมดูลด้วย:
CONFIG_MODULE_SIG_SHA1 "Sign modules with SHA-1"
CONFIG_MODULE_SIG_SHA224 "Sign modules with SHA-224"
CONFIG_MODULE_SIG_SHA256 "Sign modules with SHA-256"
CONFIG_MODULE_SIG_SHA384 "Sign modules with SHA-384"
CONFIG_MODULE_SIG_SHA512 "Sign modules with SHA-512"
อัลกอริทึมที่เลือกที่นี่จะถูกสร้างขึ้นในเคอร์เนล (แทนที่จะเป็นโมดูล) เพื่อให้โมดูลที่เซ็นชื่อด้วยอัลกอริทึมนั้นสามารถตรวจสอบลายเซ็นของพวกเขาได้โดยไม่ทำให้เกิดลูปพึ่งพา
"ชื่อไฟล์หรือ PKCS # 11 URI ของคีย์การเซ็นชื่อโมดูล" (CONFIG_MODULE_SIG_KEY)
การตั้งค่าตัวเลือกนี้เป็นอย่างอื่นที่ไม่ใช่ค่าเริ่มต้นของ "certs / registration_key.pem" จะปิดใช้งานการสร้างคีย์การเซ็นอัตโนมัติและอนุญาตให้เคอร์เนลโมดูลถูกเซ็นชื่อด้วยคีย์ที่คุณเลือก สตริงที่ระบุควรระบุไฟล์ที่มีทั้งกุญแจส่วนตัวและใบรับรอง X.509 ที่เกี่ยวข้องในรูปแบบ PEM หรือ - ในระบบที่ OpenSSL ENGINE_pkcs11 ทำงานได้ - PKCS # 11 URI ตามที่กำหนดโดย RFC7512 ในกรณีหลังนี้ PKCS # 11 URI ควรอ้างอิงทั้งใบรับรองและรหัสส่วนตัว
หากไฟล์ PEM ที่มีรหัสส่วนตัวถูกเข้ารหัสหรือถ้าโทเค็น PKCS # 11 ต้องการรหัส PIN สามารถจัดเตรียมได้ในเวลาบิลด์โดยใช้ตัวแปร KBUILD_SIGN_PIN
"คีย์ X.509 เพิ่มเติมสำหรับพวงกุญแจระบบเริ่มต้น" (CONFIG_SYSTEM_TRUSTED_KEYS)
ตัวเลือกนี้สามารถตั้งค่าเป็นชื่อไฟล์ของไฟล์ที่เข้ารหัส PEM ที่มีใบรับรองเพิ่มเติมซึ่งจะรวมอยู่ในพวงกุญแจระบบโดยค่าเริ่มต้น
โปรดทราบว่าการเปิดใช้งานการเซ็นชื่อโมดูลจะเพิ่มการพึ่งพาแพคเกจ OpenSSL devel ให้กับกระบวนการสร้างเคอร์เนลสำหรับเครื่องมือที่ทำการลงนาม
สร้างกุญแจลงนาม
ต้องใช้คู่รหัสการเข้ารหัสลับในการสร้างและตรวจสอบลายเซ็น ไพรเวตคีย์ใช้เพื่อสร้างลายเซ็นและใช้พับลิกคีย์ที่เกี่ยวข้องเพื่อตรวจสอบ จำเป็นต้องใช้คีย์ส่วนตัวในระหว่างการสร้างหลังจากนั้นจะสามารถลบหรือเก็บอย่างปลอดภัย พับลิกคีย์จะถูกสร้างขึ้นในเคอร์เนลเพื่อให้สามารถใช้ตรวจสอบลายเซ็นได้ขณะที่โหลดโมดูล
ภายใต้สภาวะปกติเมื่อ CONFIG_MODULE_SIG_KEY ไม่เปลี่ยนแปลงจากค่าเริ่มต้นการสร้างเคอร์เนลจะสร้าง keypair ใหม่โดยอัตโนมัติโดยใช้ openssl หากไม่มีอยู่ในไฟล์:
certs/signing_key.pem
ระหว่างการสร้าง vmlinux (ส่วนสาธารณะของคีย์ต้องถูกสร้างไว้ใน vmlinux) โดยใช้พารามิเตอร์ใน:
certs/x509.genkey
ไฟล์ (ซึ่งถูกสร้างขึ้นด้วยหากยังไม่มีอยู่)
ขอแนะนำอย่างยิ่งให้คุณให้ไฟล์ x509.genkey ของคุณเอง
ที่สะดุดตาที่สุดในไฟล์ x509.genkey ส่วน req_distinguished_name ควรเปลี่ยนจากค่าเริ่มต้น:
[ req_distinguished_name ]
#O = Unspecified company
CN = Build time autogenerated kernel key
#emailAddress = unspecified.user@unspecified.company
ขนาดคีย์ RSA ที่สร้างขึ้นสามารถตั้งค่าด้วย:
[ req ]
default_bits = 4096
นอกจากนี้ยังเป็นไปได้ที่จะสร้างไฟล์ไพรเวต / พับลิกคีย์ด้วยตนเองโดยใช้ไฟล์คอนฟิกูเรชันการสร้างคีย์ x509.genkey ในโหนดรูทของทรีเคอร์เนลลินุกซ์เคอร์เนลและคำสั่ง openssl ต่อไปนี้เป็นตัวอย่างในการสร้างไฟล์กุญแจสาธารณะ / ส่วนตัว:
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 ที่สร้างอัตโนมัติ
กุญแจสาธารณะในเมล็ด
เคอร์เนลมีวงแหวนของกุญแจสาธารณะที่รูตสามารถดูได้ พวกเขาอยู่ในพวงกุญแจที่เรียกว่า ".system_keyring" ซึ่งสามารถมองเห็นได้โดย:
[root@deneb ~]# cat /proc/keys
...
223c7853 I------ 1 perm 1f030000 0 0 keyring .system_keyring: 1
302d2d52 I------ 1 perm 1f010000 0 0 asymmetri Fedora kernel signing key: d69a84e6bce3d216b979e9505b3e3ef9a7118079: X509.RSA a7118079 []
...
นอกเหนือจากพับลิกคีย์ที่สร้างขึ้นโดยเฉพาะสำหรับการลงนามโมดูลใบรับรองที่เชื่อถือได้เพิ่มเติมสามารถระบุในไฟล์ที่เข้ารหัส PEM ซึ่งอ้างอิงโดยตัวเลือกการกำหนดค่า CONFIG_SYSTEM_TRUSTED_KEYS
เพิ่มเติมรหัสสถาปัตยกรรมอาจใช้กุญแจสาธารณะจากร้านฮาร์ดแวร์และเพิ่มใน (เช่นจากฐานข้อมูลคีย์ UEFI)
ในที่สุดก็เป็นไปได้ที่จะเพิ่มกุญแจสาธารณะเพิ่มเติมโดยทำ:
keyctl padd asymmetric "" [.system_keyring-ID] <[key-file]
เช่น:
keyctl padd asymmetric "" 0x223c7853 <my_public_key.x509
อย่างไรก็ตามโปรดทราบว่าเคอร์เนลจะอนุญาตให้เพิ่มคีย์ใน. system_keyring เท่านั้นหาก wrapper X.509 ของคีย์ใหม่นั้นลงชื่ออย่างถูกต้องโดยคีย์ที่มีอยู่ใน. system_keyring ในเวลาที่มีการเพิ่มคีย์
โมดูลการลงชื่อด้วยตนเอง
หากต้องการลงนามโมดูลด้วยตนเองให้ใช้เครื่องมือสคริปต์ / sign-file ที่มีอยู่ในทรีของเคอร์เนล Linux สคริปต์ต้องการ 4 อาร์กิวเมนต์:
1. The hash algorithm (e.g., sha256)
2. The private key filename or PKCS#11 URI
3. The public key filename
4. The kernel module to be signed
ต่อไปนี้เป็นตัวอย่างในการเซ็นโมดูลเคอร์เนล:
scripts/sign-file sha512 kernel-signkey.priv \
kernel-signkey.x509 module.ko
อัลกอริทึมแฮชที่ใช้ไม่จำเป็นต้องตรงกับที่ตั้งค่าไว้ แต่หากไม่เป็นเช่นนั้นคุณควรตรวจสอบให้แน่ใจว่าอัลกอริทึมแฮชนั้นมีอยู่ในเคอร์เนลหรือสามารถโหลดได้โดยไม่ต้องใช้ตัวมันเอง
หากคีย์ส่วนตัวต้องการวลีรหัสผ่านหรือ PIN สามารถจัดเตรียมไว้ในตัวแปรสภาพแวดล้อม $ KBUILD_SIGN_PIN
โมดูลที่ลงนามและการรัด
โมดูลที่ลงนามมีลายเซ็นดิจิทัลต่อท้ายเพียงแค่ สตริง "~ โมดูลลายเซ็นต่อท้าย ~." ในตอนท้ายของไฟล์โมดูลยืนยันว่ามีลายเซ็น แต่ไม่ยืนยันว่าลายเซ็นนั้นถูกต้อง!
โมดูลที่ลงนามคือ BRITTLE เนื่องจากลายเซ็นอยู่นอกคอนเทนเนอร์ ELF ที่กำหนดไว้ ดังนั้นพวกเขาอาจไม่ถูกปล้นเมื่อมีการคำนวณและแนบลายเซ็น โปรดทราบว่าโมดูลทั้งหมดเป็นส่วนของข้อมูลที่ลงนามซึ่งรวมถึงข้อมูลการดีบักใด ๆ และทั้งหมดที่มีอยู่ ณ เวลาที่ลงชื่อ
โมดูลการโหลด
โมดูลถูกโหลดด้วย insmod, modprobe, init_module () หรือ finit_module () เหมือนกับโมดูลที่ไม่ได้ลงนามเนื่องจากไม่มีการดำเนินการใด ๆ ใน userspace การตรวจสอบลายเซ็นเสร็จสิ้นภายในเคอร์เนล
ลายเซ็นที่ไม่ถูกต้องและโมดูลที่ไม่ได้ลงนาม
หากเปิดใช้งาน CONFIG_MODULE_SIG_FORCE หรือ enforcemodulesig = 1 จะถูกระบุบนบรรทัดคำสั่งเคอร์เนลเคอร์เนลจะโหลดเฉพาะโมดูลที่ลงนามอย่างถูกต้องซึ่งมีคีย์สาธารณะ มิฉะนั้นจะโหลดโมดูลที่ไม่ได้ลงชื่อด้วย โมดูลใด ๆ ที่เคอร์เนลมีคีย์ แต่ที่พิสูจน์ว่ามีลายเซ็นที่ไม่ตรงกันจะไม่ได้รับอนุญาตให้โหลด
โมดูลใด ๆ ที่มีลายเซ็นที่ไม่สามารถตรวจสอบได้จะถูกปฏิเสธ
การจัดการ / ป้องกันคีย์ส่วนตัว
เนื่องจากใช้ไพรเวตคีย์เพื่อลงนามโมดูลไวรัสและมัลแวร์จึงสามารถใช้ไพรเวตคีย์เพื่อลงนามโมดูลและประนีประนอมระบบปฏิบัติการ ไพรเวตคีย์ต้องถูกทำลายหรือย้ายไปยังตำแหน่งที่ปลอดภัยและไม่ถูกเก็บไว้ในโหนดรูทของแผนผังต้นทางเคอร์เนล