ทำไมคอนเทนเนอร์ไม่ควรทำงานเป็น Root โดยค่าเริ่มต้น?
เรียนรู้ว่าเหตุใดการเรียกใช้คอนเทนเนอร์เป็น root จึงเป็นอันตรายและวิธีการบังคับใช้ผู้ใช้ที่มีสิทธิ์น้อยที่สุด ความสามารถ และนโยบายในสภาแวดล้อมการผลิต
การเรียกใช้คอนเทนเนอร์เป็น root เป็นหนึ่งในการกำหนดค่าที่ผิดพลาดทั่วไปที่สุด และอันตรายที่สุด ในสภาแวดล้อมการผลิต มันขยายพื้นผิวการโจมตีของทุกเวิร์กโหลดอย่างเงียบ ๆ และทีมส่วนใหญ่ไม่ได้ตระหนักถึงเรื่องนี้จนกว่าจะมีเหตุการณ์ที่บังคับให้ต้องจัดการกับปัญหา
"Running as Root" หมายความว่าอะไรจริง ๆ
โดยค่าเริ่มต้น ภาพ container หลายภาพ (โดยเฉพาะแบบน้อยที่สุดหรือแบบเก่า) เรียกใช้กระบวนการหลักของพวกมันเป็น UID 0 ภายในคอนเทนเนอร์ เนื่องจากคอนเทนเนอร์แชร์เคอร์เนล host กับคอนเทนเนอร์อื่น ๆ และ host เอง root ภายในคอนเทนเนอร์จึงไม่เหมือนกับ root บนเครื่องเสมือนแบบแยกโดยสิ้นเชิง — แต่มันยังคงทรงพลังกว่าที่ควรจะเป็นมาก หากผู้โจมตีบรรลุการเรียกใช้โค้ดภายในคอนเทนเนอร์ที่เป็นเจ้าของโดย root พวกเขาจะได้รับ:
- การเข้าถึงการอ่านและเขียนแบบเต็มรูปแบบไปยังไฟล์ใด ๆ ที่เชื่อมไปยังคอนเทนเนอร์ โดยไม่คำนึงถึงสิทธิ์ที่ตั้งใจไว้
- ความสามารถในการติดตั้งแพ็คเกจ แก้ไขไบนารี่ หรือแปลงแอปพลิเคชันสถานะ
- เส้นทางที่ง่ายมากขึ้นไปยัง container breakout หากมีความเสี่ยงด้านเคอร์เนลหรือ runtime ที่สามารถใช้ประโยชน์ได้
- ประโยชน์ที่สูงขึ้นเมื่อรวมกับปริมาณที่กำหนดค่าผิด เช่น Docker socket ที่เชื่อมไว้หรือ host filesystem path
แม้ว่าจะไม่มีเคอร์เนล exploit แต่การเข้าถึง root ภายในคอนเทนเนอร์ก็เพิ่มรัศมีการระเบิดของการทำงานผิดพลาดในระดับแอปพลิเคชัน (SSRF, deserialization bugs, arbitrary file write เป็นต้น) อย่างมาก
ทำไมสิ่งนี้จึงมีความสำคัญมากขึ้นในสภาแวดล้อมที่มีการจัดการ
ในกลุ่ม Kubernetes คอนเทนเนอร์ root ที่รวมกับความสามารถ Linux ที่มากเกินไปหรือ security context ที่อนุญาตอาจให้ผู้โจมตี:
- แก้ไข
/procหรือ/sysในลักษณะที่ส่งผลกระทบต่อ host - เพิ่มสิทธิ์ถ้า
hostPID,hostNetwork, หรือhostIPCถูกเปิดใช้งาน - ใช้ประโยชน์จาก service account token ที่เชื่อมไว้เพื่อหมุนไปทั่วทั้งกลุ่ม
- หลีกหนีไปยังโหนดหากตั้งค่า
privileged: trueหรือให้ความสามารถอันตรายเช่นSYS_ADMIN
ผู้ใช้ root เองไม่ใช่ความเสี่ยงเสมอ — มันคือ การรวมกัน ของ root บวกกับความสามารถเคอร์เนลที่ใจกว้าง host mounts หรือ namespace sharing ที่เปลี่ยนการประนีประนวม contained เป็นการประนีประนวมที่ขยายไปทั่วทั้งกลุ่ม
ขั้นตอนการแข็งตัวในทางปฏิบัติ
1. ตั้งค่าผู้ใช้ที่ไม่ใช่ Root ในภาพ
กำหนดผู้ใช้ที่ไม่ใช่ root ไว้อย่างชัดเจนใน Dockerfile แทนที่จะพึ่งพาค่าเริ่มต้น:
FROM node:20-slim
RUN useradd --uid 10001 --shell /usr/sbin/nologin appuser
USER appuser
2. บังคับใช้ในระดับ Orchestrator
อย่าเพียงแค่เชื่อใจภาพ — บังคับใช้นโยบายในขณะทำงาน ใน Kubernetes ให้ใช้ securityContext:
securityContext:
runAsNonRoot: true
runAsUser: 10001
allowPrivilegeEscalation: false
readOnlyRootFilesystem: true
capabilities:
drop: ["ALL"]
runAsNonRoot: true ทำให้ pod ล้มเหลวในการยอมรับหากภาพพยายามเรียกใช้เป็น UID 0 ซึ่งให้ค่าประกันที่ยากแน่นแบบ hard rather than a best-effort convention
3. วางความสามารถที่ไม่จำเป็น
แอปพลิเคชันส่วนใหญ่ไม่ต้องการความสามารถ Linux ที่ค่าเริ่มต้นใดที่มอบให้กับคอนเทนเนอร์ วางทั้งหมดออกแล้วเพิ่มเฉพาะสิ่งที่จำเป็นอย่างแน่นอน (กรณีที่หายากเช่นการผูกพันกับพอร์ตต่ำอาจต้องการ NET_BIND_SERVICE)
4. หลีกเลี่ยง Privileged Mode และ Host Namespace Sharing
privileged: true, hostNetwork: true, และ hostPID: true ควรสงวนไว้สำหรับเวิร์กโหลด infrastructure ที่เฉพาะเจาะจงมาก (เช่น agents CNI หรือ monitoring บางตัว) — ไม่เคยสำหรับคอนเทนเนอร์แอปพลิเคชันทั่วไป
5. สแกนและบังคับใช้ด้วยเครื่องมือนโยบาย
ใช้ admission controllers หรือ policy engines (เช่น Kyverno, OPA/Gatekeeper) เพื่อปฏิเสธ deployments ที่ละเมิดกฎเหล่านี้โดยอัตโนมัติ แทนที่จะพึ่งพา code review ด้วยตนเอง จับคู่กับการสแกนภาพใน CI เพื่อจับภาพผู้ใช้ root ก่อนที่จะเข้าถึงกลุ่ม
การป้องกันแบบแบ่งชั้น ไม่ใช่แบบสมบูรณ์
การเรียกใช้เป็นผู้ใช้ที่ไม่ใช่ root ไม่ได้ขจัดความเสี่ยงโดยสิ้นเชิง — container escapes ในระดับเคอร์เนลมีอยู่โดยไม่ขึ้นอยู่กับผู้ใช้ในคอนเทนเนอร์ — แต่มันลบออกคลาสขนาดใหญ่ของเทคนิค privilege escalation และ lateral movement ที่มีความพยายามน้อย เมื่อรวมกับ read-only filesystems ความสามารถที่ลดลง และ network policies ที่ผ่อนคลาย มันจะสร้างหนึ่งในชั้น defense-in-depth container security strategy ที่ราคาถูกและมีประสิทธิภาพสูงสุด
ต้องการเจาะลึกเพิ่มเติมเกี่ยวกับการแข็งตัวของเวิร์กโหลด cloud-native? สำรวจส่วน Korra Studio ที่เกี่ยวข้องเกี่ยวกับ Cloud security และ DevOps pipeline hardening เพื่อสร้างส่วนที่เหลือของกลยุทธ์ defense-in-depth ของคุณ
เขียนด้วยความช่วยเหลือของ AI ตรวจสอบและเผยแพร่โดย Michal Pilch (CISSP), Korra Studio
นี่คือบันทึกหนึ่งจากฐานความรู้ของ Korra Studio — แพลตฟอร์มจับคู่หัวข้อแต่ละหัวข้อกับการฝึกสอนแบบ 1-to-1
เริ่มใช้งานฟรีarrow_forward