คุณสามารถรัน Docker ในการผลิตเป็นเวลาหลายเดือนโดยไม่มีปัญหาที่เห็นได้ชัดเจน คอนเทนเนอร์เริ่มทำงาน แอปตอบสนอง ไม่มีอะไรเสียหาย จากนั้นพอร์ตที่เปิดเผยหนึ่งพอร์ตหรือการอนุญาตที่กำหนดค่าไม่ถูกต้องจะสร้างฐานที่มั่นซึ่งผู้โจมตีไม่จำเป็นต้องได้รับ ข้อผิดพลาดด้านความปลอดภัยของ Docker ส่วนใหญ่จะไม่ดูเหมือนเป็นข้อผิดพลาดจนกว่าจะมีสิ่งผิดปกติเกิดขึ้น
บทความนี้ครอบคลุมถึงการกำหนดค่าเฉพาะที่ทำให้สภาพแวดล้อมคอนเทนเนอร์ตกอยู่ในความเสี่ยง สิ่งที่แต่ละอย่างเปิดใช้งานสำหรับผู้โจมตี และปิดท้ายด้วยรายการตรวจสอบที่คุณสามารถใช้กับการตั้งค่าของคุณเองในปัจจุบัน
เหตุใด Docker Security จึงยากกว่าที่คิด
ตู้คอนเทนเนอร์ให้ความรู้สึกโดดเดี่ยว คุณเริ่มต้นระบบ มันจะรันพื้นที่กระบวนการของตัวเอง และไม่มีคอนเทนเนอร์ถัดไปจากภายใน คุณรู้สึกโดดเดี่ยวแต่เพียงบางส่วนเท่านั้น คอนเทนเนอร์ใช้เคอร์เนลของโฮสต์ร่วมกัน ซึ่งหมายความว่ากระบวนการภายในคอนเทนเนอร์สามารถเข้าถึงระบบโฮสต์ทั้งหมดได้ภายใต้เงื่อนไขเฉพาะ
เรือนักเทียบท่าได้รับการกำหนดค่าเพื่อความสะดวกของนักพัฒนา ไม่ใช่การทำให้การผลิตแข็งแกร่งขึ้น การเข้าถึงรูทเปิดอยู่ พอร์ตทั้งหมดสามารถผูกเข้ากับอินเทอร์เฟซทั้งหมดได้ ไม่มีการตรวจสอบรันไทม์ นักพัฒนาส่วนใหญ่ยอมรับการตั้งค่าเหล่านั้น จัดส่งคอนเทนเนอร์ และดำเนินการต่อ นั่นเป็นแนวทางที่สมเหตุสมผลในการเริ่มต้น มันไม่ใช่มาตรการรักษาความปลอดภัยที่สมบูรณ์
ตาม รายงานสถานะความปลอดภัย Kubernetes ประจำปี 2024 ของ Red Hat, 67% ขององค์กรปรับใช้แอปพลิเคชันล่าช้าหรือช้าลงเนื่องจากความกังวลด้านความปลอดภัยของคอนเทนเนอร์หรือ Kubernetes การเสียดสีนั้นมักจะไม่ได้มาจากการโจมตี มาจากทีมที่ค้นพบว่าการตั้งค่าคอนเทนเนอร์ของตนจำเป็นต้องมีการเสริมความแข็งแกร่งโดยที่พวกเขาไม่ได้ติดตั้งไว้
เรามักจะเห็นคอนเทนเนอร์ที่ใช้งานจริงโดยมีการกำหนดค่าเดียวกันกับที่มีในเครื่องภายในของนักพัฒนา นั่นคือจุดที่ข้อผิดพลาดด้านความปลอดภัยของ Docker มักจะปะทุขึ้นอย่างเงียบๆ โดยไม่มีอาการใดๆ ให้เห็นจนกว่าจะมีการตรวจสอบหรือล้มเหลว
ข้อผิดพลาดที่สร้างช่องว่างเหล่านั้นมีความเฉพาะเจาะจง คาดเดาได้ และส่วนใหญ่สามารถหลีกเลี่ยงได้ โดยเริ่มต้นที่ระดับการกำหนดค่า
ข้อผิดพลาดในการกำหนดค่า Docker ทั่วไป
การละเมิดคอนเทนเนอร์ส่วนใหญ่ไม่ได้เริ่มต้นด้วยการหาช่องโหว่แบบซีโรเดย์ โดยเริ่มต้นด้วยการกำหนดค่าที่ตั้งไว้ในวันแรก โดยไม่ต้องคำนึงถึงการเปิดเผยเครือข่ายหรือขอบเขตสิทธิ์มากนัก
การตั้งค่า Docker เริ่มต้นถูกสร้างขึ้นมาเพื่อให้ใช้งานได้ ช่องว่างระหว่างการทำงานและการรักษาความปลอดภัยคือจุดที่ความเสี่ยงด้านความปลอดภัยของคอนเทนเนอร์ Docker สะสม โดยเฉพาะอย่างยิ่งในการตั้งค่าที่โฮสต์เองซึ่งมีการใช้งานและไม่เคยกลับมาอีก
เราเห็นรูปแบบนี้บ่อยครั้ง: คอนเทนเนอร์บนเซิร์ฟเวอร์ IP สาธารณะที่มีการผูกพอร์ต การตั้งค่าผู้ใช้ และการกำหนดค่าเครือข่ายเหมือนกับตอนการใช้งานครั้งแรกทุกประการ
การรันคอนเทนเนอร์ในฐานะรูท
เมื่อคุณเริ่มต้นคอนเทนเนอร์ Docker โดยไม่ระบุผู้ใช้ คอนเทนเนอร์นั้นจะรันในฐานะรูท นั่นหมายถึงกระบวนการใดๆ ภายในคอนเทนเนอร์ รวมถึงแอปพลิเคชันของคุณ จะมีสิทธิ์ระดับรูทภายในเนมสเปซของคอนเทนเนอร์

การรูทภายในคอนเทนเนอร์นั้นไม่เหมือนกับการรูทบนโฮสต์ แต่การแยกจะไม่แน่นอน การหาประโยชน์จากการยกระดับสิทธิ์โดยกำหนดเป้าหมายไปที่รันไทม์ เช่น runc CVE-2019-5736 ที่มีการบันทึกไว้อย่างดีและข้อบกพร่องรันไทม์ที่คล้ายกัน มักต้องใช้กระบวนการรูทคอนเทนเนอร์จึงจะสำเร็จ
คอนเทนเนอร์ที่ไม่ใช่รูทจะลบข้อกำหนดกระบวนการรูทที่ช่องโหว่เหล่านั้นต้องพึ่งพา ซึ่งจะทำให้พื้นที่การโจมตีแคบลงอย่างมากสำหรับระดับช่องโหว่นั้น แม้ว่าพวกมันจะไม่ได้กำจัดความเสี่ยงในการหลบหนีของคอนเทนเนอร์ทั้งหมดก็ตาม
การเพิ่มคำสั่ง USER ให้กับ Dockerfile ของคุณช่วยแก้ไขปัญหานี้ รูปภาพที่เป็นทางการบางภาพจัดส่งมาพร้อมกับผู้ใช้ที่ไม่มีสิทธิพิเศษ คุณสามารถเปิดใช้งานได้ด้วยคำสั่ง USER แต่หลายภาพยังคงใช้ค่าเริ่มต้นในการรูทโดยไม่มีผู้ใช้แอปสำเร็จรูป ในกรณีดังกล่าว คุณจะต้องสร้างผู้ใช้ใน Dockerfile ก่อนที่จะเปลี่ยนไปใช้ สำหรับการตั้งค่าที่โฮสต์เองส่วนใหญ่ การเปลี่ยนแปลงเพียงครั้งเดียวนี้จะขจัดความเสี่ยงในการยกระดับประเภททั้งหมด
การเปิดเผยพอร์ตมากเกินไปสู่อินเทอร์เน็ตสาธารณะ
เมื่อคุณเผยแพร่พอร์ตด้วย Docker นักเทียบท่าจะเขียนกฎ iptables ของตัวเองโดยตรง กฎเหล่านั้นทำงานก่อนกฎไฟร์วอลล์ระดับโฮสต์ นี่คือก พฤติกรรมที่รู้จักกันดีรายงานโดยชุมชน และ บันทึกไว้ในคู่มือการกรองแพ็กเก็ตของ Dockerไม่ใช่การกำหนดค่าที่ไม่ถูกต้อง และหมายความว่า UFW และเครื่องมือที่คล้ายกันไม่ได้บล็อกสิ่งที่ Docker เปิดไว้แล้ว

นักเทียบท่าเขียนโดยตรงไปยัง iptables โดยข้ามค่าเริ่มต้นของ UFW และไฟร์วอลล์บนโฮสต์ Linux จำนวนมาก นั่นหมายความว่าพอร์ตที่ผูกไว้กับ 0.0.0.0 สามารถเข้าถึงได้แบบสาธารณะแม้ว่าไฟร์วอลล์ของคุณจะถูกกำหนดค่าไว้ก็ตาม กลุ่มความปลอดภัยบนคลาวด์และกฎลูกโซ่ DOCKER-USER ยังคงสามารถบล็อกการรับส่งข้อมูลนั้นได้ ดังนั้นความเสี่ยงที่เกิดขึ้นจริงจะขึ้นอยู่กับการตั้งค่าเครือข่ายเฉพาะของคุณ
เชื่อมโยงบริการกับ 127.0.0.1 หากเป็นไปได้ กำหนดเส้นทางการรับส่งข้อมูลแบบสาธารณะผ่านพร็อกซีย้อนกลับ และเผยแพร่เฉพาะสิ่งที่ต้องการการเข้าถึงจากภายนอกอย่างแท้จริง Reverse proxy เป็นวิธีที่น่าเชื่อถือที่สุดในการควบคุมสิ่งที่เปิดเผยจากภายนอกโฮสต์
ละเว้นการแยกเครือข่ายระหว่างคอนเทนเนอร์
คอนเทนเนอร์ใดๆ บนเครือข่ายนั้นสามารถเข้าถึงคอนเทนเนอร์อื่นๆ บนเครือข่ายนั้นได้โดยไม่มีข้อจำกัด บริดจ์เริ่มต้นจะไม่ใช้การกรองการรับส่งข้อมูลระหว่างคอนเทนเนอร์ที่แชร์ และการตั้งค่าส่วนใหญ่จะไม่เปลี่ยนการกำหนดค่านั้น

หากคอนเทนเนอร์หนึ่งถูกโจมตี การสื่อสารแบบเปิดนั้นจะกลายเป็นเส้นทางการเคลื่อนที่ด้านข้าง คอนเทนเนอร์ฟรอนท์เอนด์สามารถเข้าถึงฐานข้อมูล, API ภายใน หรือสิ่งอื่นใดบนเครือข่ายบริดจ์เริ่มต้นเดียวกัน แม้ว่าจะไม่มีเจตนาให้เข้าถึงก็ตาม
เครือข่ายที่ผู้ใช้กำหนดช่วยให้คุณควบคุมได้อย่างชัดเจนว่าคอนเทนเนอร์ใดสามารถสื่อสารได้ แต่เครือข่ายที่กำหนดเองเพียงเครือข่ายเดียวที่แชร์โดยบริการทั้งหมดของคุณยังคงอนุญาตให้มีการรับส่งข้อมูลระหว่างคอนเทนเนอร์ได้ฟรี การแยกตัวอย่างแท้จริงจำเป็นต้องมีการให้บริการที่ไม่ควรสื่อสารกันบนเครือข่ายที่แยกจากกัน การปิดสะพานเริ่มต้นคือจุดเริ่มต้น ไม่ใช่เส้นชัย
มองเห็น Docker Socket
ซ็อกเก็ต Docker ที่ /var/run/docker.sock เป็นอินเทอร์เฟซการควบคุมสำหรับกลไก Docker ทั้งหมด การติดตั้งลงในคอนเทนเนอร์จะทำให้คอนเทนเนอร์นั้นสามารถเข้าถึง API โดยตรงไปยัง daemon ที่ทำงานบนโฮสต์

ด้วยการเข้าถึงดังกล่าว คอนเทนเนอร์สามารถเริ่มคอนเทนเนอร์ใหม่ ติดตั้งไดเร็กทอรีโฮสต์ ตรวจสอบและแก้ไขคอนเทนเนอร์ที่ทำงานอยู่ และควบคุมเครื่องโฮสต์ได้อย่างมีประสิทธิภาพ พื้นผิวการโจมตีเทียบเท่ากับการรูทบนโฮสต์ ซึ่งเป็นเหตุผลว่าทำไมเครื่องมือใดๆ ที่ต้องใช้การเข้าถึงซ็อกเก็ตจึงสมควรได้รับการประเมินอย่างรอบคอบ
สำหรับกรณีการใช้งานส่วนใหญ่ มีทางเลือกอื่นที่ปลอดภัยกว่า: API ที่กำหนดขอบเขตหรือ เครื่องมือการจัดการนักเทียบท่า ที่ไม่ต้องมีการเข้าถึงซ็อกเก็ต Docker-in-Docker มีการรักษาความปลอดภัยและการแลกเปลี่ยนการปฏิบัติงานของตนเอง และไม่ได้ทดแทนโดยตรง
ข้อผิดพลาดในการกำหนดค่าทำให้เกิดความเสี่ยงเบื้องต้น ตัวเลือกรูปภาพและการขึ้นต่อกันจะกำหนดว่าการสัมผัสจะผสมกันอย่างไรเมื่อเวลาผ่านไป
ข้อผิดพลาดด้านภาพและความลับที่อยู่ได้นานกว่าคอนเทนเนอร์
เมื่อคุณหยุดคอนเทนเนอร์ ข้อผิดพลาดในการกำหนดค่าภายในคอนเทนเนอร์จะหยุดตามไปด้วย เมื่อคุณสร้างใหม่จากรูปภาพที่มีช่องโหว่หรือข้อมูลประจำตัวแบบฮาร์ดโค้ด ปัญหาจะเริ่มต้นใหม่พร้อมกับคอนเทนเนอร์ ข้อผิดพลาดระดับรูปภาพจะไม่ถูกรีเซ็ตระหว่างการใช้งาน
พวกเขาเดินทางพร้อมกับอิมเมจไปยังทุกสภาพแวดล้อมที่ดึงอิมเมจ ทุกรีจีสทรีที่จัดเก็บอิมเมจ และสมาชิกในทีมทุกคนที่รันอิมเมจ ความคงอยู่ดังกล่าวทำให้การจัดการภาพและความลับเป็นหมวดหมู่ความเสี่ยงที่แตกต่างกัน ซึ่งคุ้มค่ากับการตรวจสอบแยกต่างหากจากการกำหนดค่า
เราเห็นรูปแบบนี้บ่อยครั้ง: รูปภาพที่เลือกอย่างระมัดระวังเมื่อเริ่มต้นโปรเจ็กต์และไม่เคยสร้างใหม่ตั้งแต่นั้นมา โดยค่อย ๆ ลอยไปจากพื้นฐานความปลอดภัยที่แสดงในตอนแรก
การใช้รูปภาพที่ไม่น่าเชื่อถือหรือล้าสมัย
ทะเบียนสาธารณะเปิดให้ทุกคน รูปภาพที่เป็นอันตรายได้รับการเผยแพร่ผ่าน Docker Hub ซึ่งมีตัวขุด crypto และประตูหลังที่ฝังอยู่ในประวัติเลเยอร์ที่ยังคงมีอยู่ตลอดการรีสตาร์ทคอนเทนเนอร์ การตรวจสอบก่อนดึงเรื่อง โดยเฉพาะภาพจากผู้เผยแพร่ที่ไม่เป็นทางการหรือไม่รู้จัก

ปัญหาที่แยกจากกันคือความจืดชืด อิมเมจอย่างเป็นทางการที่คุณดึงมาเมื่อหกเดือนก่อนและไม่เคยสร้างขึ้นใหม่นับตั้งแต่มีการสะสมช่องโหว่ Docker ที่ไม่ได้รับแพตช์ โดย CVE แต่ละตัวถูกเปิดเผยกับแพ็คเกจของมัน ภาพไม่แตก มันไม่ใช่ปัจจุบันอีกต่อไป
รายงานสถานะห่วงโซ่อุปทานซอฟต์แวร์ปี 2024 ของ Sonatype พบว่า 95% ของเวลาที่มีการใช้ส่วนประกอบที่มีช่องโหว่ มีเวอร์ชันคงที่อยู่แล้ว และ 80% ของการพึ่งพาแอปพลิเคชันยังคงไม่ได้รับการอัปเกรดเป็นเวลานานกว่าหนึ่งปี รูปแบบนั้นเกี่ยวข้องกับอิมเมจฐาน Docker เช่นกัน เนื่องจากต้องใช้แพ็คเกจโอเพ่นซอร์สเดียวกัน
ใช้รูปภาพอย่างเป็นทางการจากผู้เผยแพร่ที่ได้รับการยืนยันและปักหมุดแท็กเวอร์ชันเฉพาะ แทนที่จะอาศัย "ล่าสุด" สร้างจังหวะการสร้างใหม่เป็นประจำเพื่อให้รูปภาพของคุณเป็นปัจจุบัน
ความลับในการเข้ารหัสฮาร์ดโค้ดใน Dockerfiles และไฟล์เขียน
ข้อมูลประจำตัวที่เขียนลงในคำสั่ง Dockerfile ENV หรือ ARG, ฮาร์ดโค้ดลงในบล็อกสภาพแวดล้อมการเขียน, ส่งผ่านเป็นอาร์กิวเมนต์ของบิลด์ หรือจัดเก็บไว้ในไฟล์ .env ที่คอมมิตกับการควบคุมเวอร์ชันจะไม่หายไปเมื่อคุณหยุดคอนเทนเนอร์ โดยจะยังคงอยู่ในประวัติเลเยอร์รูปภาพหรือการควบคุมแหล่งที่มา ซึ่งใครก็ตามที่สามารถเข้าถึงได้สามารถเข้าถึงได้

นี่เป็นหนึ่งในข้อผิดพลาดด้านความปลอดภัยของ Docker ที่ถูกมองข้ามมากที่สุด เนื่องจากไม่ก่อให้เกิดปัญหาที่มองเห็นได้ในระหว่างการพัฒนา คีย์ API ในคำสั่ง ENV ทำงานได้อย่างถูกต้อง นอกจากนี้ยังอยู่ในพื้นที่เก็บข้อมูลของคุณ ฝังอยู่ในรูปภาพของคุณ และกระจายไปทุกที่ที่รูปภาพนั้นเดินทางไป
Modern Docker Compose รองรับกลไกความลับดั้งเดิมที่เมานต์ข้อมูลประจำตัว ณ รันไทม์โดยไม่ต้องใส่เข้าไปในรูปภาพ API ความลับของ Docker และผู้จัดการความลับภายนอกเป็นไปตามหลักการเดียวกัน ตัวเลือกเหล่านี้คือตัวเลือกที่จะเก็บข้อมูลประจำตัวทั้งหมดออกจากส่วนที่สร้างขึ้นและไฟล์ที่คอมมิต
ตัวแปรสภาพแวดล้อมรันไทม์ได้รับการปรับปรุงให้ดีขึ้นกว่าข้อมูลประจำตัวแบบฮาร์ดโค้ด แต่ยังคงเปิดเผยผ่าน Docker ตรวจสอบเอาต์พุต บันทึก และดัมพ์ พวกเขากำลังก้าวขึ้นมาจากความลับที่อบอวลอยู่ ไม่ใช่วิธีแก้ปัญหาที่เสร็จสิ้นแล้ว
ไม่อัปเดตอิมเมจคอนเทนเนอร์เป็นประจำ
การแสดงภาพเดิมๆ เป็นเวลาหลายเดือนเป็นนิสัยที่พบบ่อย ในแต่ละวันที่ผ่านไปหลังจากมีการเปิดเผยช่องโหว่ใหม่ แต่ก่อนที่คุณจะสร้างใหม่ คอนเทนเนอร์ของคุณจะมีหน้าต่างเปิดรับแสงที่ขยายใหญ่ขึ้นโดยไม่มีการเปลี่ยนแปลงที่มองเห็นได้
สร้างกำหนดการสร้างใหม่ที่สอดคล้องกัน ทำให้กระบวนการนั้นเป็นอัตโนมัติเมื่อเป็นไปได้ และเรียกใช้เครื่องสแกนช่องโหว่กับอิมเมจปัจจุบันของคุณเป็นระยะ เป้าหมายไม่ใช่ความสมบูรณ์แบบ เป็นการลดระยะเวลาระหว่างการเผยแพร่แพตช์และการใช้งาน
การควบคุมการเข้าถึงและการตรวจสอบอาจถูกลดความสำคัญลงในการปรับใช้ที่รวดเร็ว นอกจากนี้ยังเป็นหมวดหมู่ที่ตรวจไม่พบเหตุการณ์ต่างๆ ได้นานที่สุดอีกด้วย
การควบคุมการเข้าถึงและช่องว่างในการมองเห็น
หลังจากที่คอนเทนเนอร์ทำงานด้วยการกำหนดค่าที่มั่นคงและอิมเมจปัจจุบัน ความล้มเหลวสองประเภทจะยังคงอยู่ ทั้งสองสิ่งนี้มองไม่เห็นโดยธรรมชาติ: คุณจะไม่สังเกตเห็นปัญหาการควบคุมการเข้าถึงที่อ่อนแอจนกว่าจะมีคนใช้งาน และคุณจะไม่สังเกตเห็นช่องว่างในการตรวจสอบจนกว่าคุณจะต้องตรวจสอบกิจกรรมที่ไม่เคยถูกบันทึก
เหมือนกัน งานวิจัยของเรดแฮท 2024 พบว่า 42% ของทีมขาดความสามารถเพียงพอที่จะจัดการกับความปลอดภัยของคอนเทนเนอร์และภัยคุกคามที่เกี่ยวข้อง
เราพบว่าช่องว่างในการติดตามมักจะปรากฏขึ้นในระหว่างการสืบสวนเหตุการณ์ ไม่ใช่ก่อนหน้านี้ เมื่อการมองเห็นกลายเป็นสิ่งที่สำคัญที่สุด ก็มักจะตอบสนองต่อบางสิ่งมากกว่าที่จะป้องกันมัน
การตรวจสอบสิทธิ์ที่อ่อนแอและแดชบอร์ดการจัดการที่เปิดเผย
แดชบอร์ดการจัดการคอนเทนเนอร์บน IP สาธารณะที่ไม่มีการตรวจสอบสิทธิ์ไม่จำเป็นต้องมีผู้โจมตีที่เชี่ยวชาญ มันต้องการให้พวกเขารู้ที่อยู่ นั่นเป็นแถบที่ต่ำกว่าที่ทีมส่วนใหญ่ตระหนัก

เครื่องมือตรวจสอบและการจัดการที่โฮสต์ด้วยตนเองมักจะมาพร้อมกับอินเทอร์เฟซเว็บที่สามารถเข้าถึงได้จากอินเทอร์เฟซเครือข่ายทั้งหมด การปล่อยให้สิ่งเหล่านั้นอยู่บน IP สาธารณะโดยไม่มีการตรวจสอบสิทธิ์ต่อหน้าพวกเขานั้นเปรียบได้กับการปลดล็อคแผงผู้ดูแลระบบทิ้งไว้
การรับรองความถูกต้อง พร็อกซีย้อนกลับ และตำแหน่งเครือข่ายส่วนตัวเป็นพื้นฐาน การควบคุมการเข้าถึงเป็นขั้นตอนการกำหนดค่าที่คุณเพิ่มลงในอินเทอร์เฟซการจัดการใดๆ ไม่ใช่สิ่งที่เปิดใช้งานในการจัดส่ง
หลักการเดียวกันนี้ใช้กับ การจัดการ Docker CLI และ GUI; การเข้าถึง daemon ระดับผู้ดูแลระบบจะมีความเสี่ยงเท่ากันโดยไม่คำนึงถึงอินเทอร์เฟซ
ไม่ติดตามว่าคอนเทนเนอร์ของคุณกำลังทำอะไรอยู่
หากคอนเทนเนอร์ถูกโจมตี กิจกรรมของผู้โจมตีจะสร้างร่องรอย: การเปลี่ยนแปลงพฤติกรรมของกระบวนการ การเชื่อมต่อเครือข่ายที่ผิดปกติ และการแก้ไขไฟล์ที่ไม่คาดคิด หากไม่มีการรวบรวมบันทึก เส้นทางนั้นก็จะไม่มีอยู่ในแบบฟอร์มที่คุณสามารถดำเนินการได้
การรวบรวมบันทึกแบบรวมศูนย์ การบันทึกการตรวจสอบคอนเทนเนอร์ และเครื่องมือตรวจสอบรันไทม์จะให้ข้อมูลแก่คุณเพื่อตรวจจับกิจกรรมที่ผิดปกติก่อนที่จะรวมเข้าด้วยกัน เป้าหมายไม่ได้วิเคราะห์ทุกบรรทัด มีข้อมูลเมื่อคุณต้องการตรวจสอบ
การตั้งค่าคอนเทนเนอร์ที่ทำงานแบบเงียบๆ ในการผลิตโดยไม่มีไปป์ไลน์บันทึกและไม่มีการแจ้งเตือนถือว่ามีการบำรุงรักษาต่ำ พวกเขาไม่ได้รับการตรวจสอบ สิ่งเหล่านี้เป็นสถานะการปฏิบัติงานที่แตกต่างกันสองสถานะ
เหตุใดสภาพแวดล้อมโครงสร้างพื้นฐานจึงมีความสำคัญเช่นกัน
การรักษาความปลอดภัยของคอนเทนเนอร์เริ่มต้นด้วยการกำหนดค่า แต่การกำหนดค่าจะทำงานบนโครงสร้างพื้นฐาน โฮสต์ที่มีเครือข่ายที่กำหนดค่าไม่ถูกต้อง ทรัพยากรที่ใช้ร่วมกัน หรือไม่มีการกรองระดับเครือข่ายจะสร้างเงื่อนไขที่ส่งผลต่อทุกคอนเทนเนอร์ที่อยู่ด้านบน การทำให้การตั้งค่าคอนเทนเนอร์ถูกต้องและการกำหนดค่าเซิร์ฟเวอร์ถูกต้องเป็นงานสองงานที่แยกจากกัน
ช่องว่างด้านความปลอดภัยของ Docker จำนวนมากถูกขยายตามเงื่อนไขที่คอนเทนเนอร์สืบทอดมา:
- เซิร์ฟเวอร์ผู้เช่าที่ใช้ร่วมกันโดยไม่มีการแยกฮาร์ดแวร์ระหว่างผู้เช่า
- เคอร์เนลโฮสต์ทำงานไม่ได้รับการแก้ไข
- โฮสต์ที่ไม่มีการกรองระดับเครือข่ายในตัว
การดำเนินการนี้ไม่ได้ขจัดความจำเป็นในขั้นตอนการกำหนดค่าข้างต้น เนื่องจากการเสริมความแข็งแกร่งของคอนเทนเนอร์ที่เหมาะสมนั้นมีความสำคัญโดยไม่คำนึงถึงเลเยอร์โครงสร้างพื้นฐาน การเริ่มต้นบนโครงสร้างพื้นฐานแบบแยกเดี่ยวจะขจัดข้อกังวลหนึ่งชั้นออกจากสมการ
ที่ Cloudzy เรามีสองเส้นทางขึ้นอยู่กับการตั้งค่าที่คุณต้องการ:
- ลินุกซ์ วีพีเอส: สภาพแวดล้อมที่สะอาดเพื่อปรับใช้ Docker ด้วยตัวคุณเอง และใช้ขั้นตอนการทำให้แข็งขึ้นในบทความนี้
- ปอร์เทนเนอร์ VPS: ตัวเลือกคลิกเดียวพร้อม Portainer ที่ติดตั้งไว้ล่วงหน้า เซิร์ฟเวอร์บูท และคุณอยู่ในแดชบอร์ดแล้ว
ตัวเลือกทั้งสองทำงานบนโครงสร้างพื้นฐานเดียวกัน: การจำลองเสมือน KVM, CPU AMD Ryzen 9 ที่ความเร็วสัญญาณนาฬิกาสูงสุด 5.7 GHz, หน่วยความจำ DDR5, ที่เก็บข้อมูล NVMe SSD, เครือข่ายสูงสุด 40 Gbps และการป้องกัน DDoS ฟรีผ่านการกรอง BuyVM ใน 12 แห่งทั่วโลกด้วย SLA ความพร้อมในการทำงาน 99.95%
หากต้องการเจาะลึกยิ่งขึ้นเกี่ยวกับการใช้งาน Portainer บน VPS เราจะอธิบายไว้ในบทความเฉพาะ
รายการตรวจสอบความปลอดภัยที่ใช้งานได้จริงสำหรับการปรับใช้ Docker
ข้อผิดพลาดด้านความปลอดภัยของ Docker ข้างต้นส่วนใหญ่มาจากการตัดสินใจกำหนดค่าเพียงครั้งเดียวและไม่เคยกลับมาแก้ไขอีก การเรียกใช้รายการตรวจสอบนี้กับการตั้งค่าที่มีอยู่จะช่วยลดช่องว่างเหล่านั้น โดยทำหน้าที่เป็นการตรวจสอบ ไม่ใช่แนวทางในการปรับใช้
แนวทางปฏิบัติที่ดีที่สุดด้านความปลอดภัยของ Docker เหล่านี้ครอบคลุมวิธีการรักษาความปลอดภัยคอนเทนเนอร์ Docker จากความล้มเหลวในการกำหนดค่าทั่วไปส่วนใหญ่ที่อธิบายไว้ข้างต้น
การอ้างอิงด่วน: ข้อผิดพลาดทั้ง 9 ข้อ
| ความผิดพลาด | หมวดหมู่ | การแก้ไขบรรทัดเดียว |
| ทำงานเป็นรูท | การกำหนดค่า | เพิ่ม ผู้ใช้ คำสั่งไปยัง Dockerfile ของคุณ |
| พอร์ตเชื่อมโยงกับ 0.0.0.0 | การกำหนดค่า | เชื่อมโยงกับ 127.0.0.1 และกำหนดเส้นทางผ่านพร็อกซีย้อนกลับ |
| ไม่มีการแยกเครือข่าย | การกำหนดค่า | แยกบริการข้ามเครือข่ายที่ผู้ใช้กำหนดตามความต้องการในการเข้าถึง |
| ติดตั้งซ็อกเก็ตนักเทียบท่า | การกำหนดค่า | ถอดที่ยึด; ใช้ API ที่กำหนดขอบเขตหรือทางเลือกอื่น |
| รูปภาพที่ไม่น่าเชื่อถือหรือล้าสมัย | ภาพ | ใช้รูปภาพอย่างเป็นทางการพร้อมแท็กเวอร์ชันที่ปักหมุดไว้ |
| ความลับแบบฮาร์ดโค้ด | ภาพ | ย้ายข้อมูลรับรองไปที่ runtime env vars หรือผู้จัดการข้อมูลลับ |
| ไม่มีกำหนดการสร้างอิมเมจใหม่ | ภาพ | กำหนดจังหวะการสร้างใหม่ทุกเดือน อัตโนมัติเมื่อเป็นไปได้ |
| แดชบอร์ดที่ไม่ได้รับการรับรองความถูกต้อง | เข้าถึง | เพิ่มการตรวจสอบสิทธิ์และย้าย UI การจัดการไปยังเครือข่ายส่วนตัว |
| ไม่มีการรวบรวมบันทึกคอนเทนเนอร์ | เข้าถึง | ตั้งค่าการบันทึกแบบรวมศูนย์และการตรวจสอบรันไทม์ |
เราขอแนะนำให้รันกับการตั้งค่าที่มีอยู่ก่อน เนื่องจากเป็นจุดที่มักมีช่องว่างอยู่แล้ว
คอนเทนเนอร์ที่ทำงานโดยไม่ใช่รูท: ตรวจสอบ Dockerfiles ของคุณเพื่อดูคำสั่ง USER หากไม่มีอยู่ คอนเทนเนอร์จะรันในฐานะรูท
การเชื่อมโยงพอร์ตจำกัดเฉพาะ localhost หรือพรอกซี: เรียกใช้ docker ps และตรวจสอบการเชื่อมโยงพอร์ต รายการ 0.0.0.0:PORT สามารถเข้าถึงได้แบบสาธารณะบนโฮสต์ที่ไม่มีกลุ่มความปลอดภัยอัปสตรีม ไฟร์วอลล์ภายนอก หรือกฎลูกโซ่ DOCKER-USER บล็อกไว้
เครือข่ายบริดจ์แบบกำหนดเองที่ใช้งานอยู่: คอนเทนเนอร์บนบริดจ์เริ่มต้นของ Docker สามารถติดต่อกันได้อย่างอิสระ คอนเทนเนอร์บนบริดจ์ที่ผู้ใช้กำหนดเดียวกันยังคงสามารถสื่อสารระหว่างกันได้ ดังนั้นควรแยกบริการต่างๆ บนเครือข่ายที่แยกจากกันตามขอบเขตความน่าเชื่อถือเพื่อการแยกออกตามจริง
ซ็อกเก็ตนักเทียบท่าไม่ได้ติดตั้งในคอนเทนเนอร์: ตรวจสอบเขียนไฟล์และเรียกใช้อาร์กิวเมนต์ หาก /var/run/docker.sock ปรากฏเป็นโวลุ่ม ให้ยืนยันว่าจำเป็นและตั้งใจ
ภาพฐานจากผู้เผยแพร่ที่ได้รับการยืนยันพร้อมเวอร์ชันที่ปักหมุด: A FROM ubuntu:latest ดึงเวอร์ชันที่ไม่ระบุและอาจล้าสมัย ปักหมุดไปที่รุ่นเฉพาะ
ไม่มีความลับใน Dockerfiles, เขียนไฟล์ หรือสร้างอาร์กิวเมนต์: ประวัติเลเยอร์รูปภาพยังคงมีข้อมูลรับรองหลังจากการลบคอนเทนเนอร์ ใช้เขียนความลับ ความลับแบบ Swarm สร้างพาหนะลับ หรือตัวจัดการความลับภายนอก ตัวแปรสภาพแวดล้อมรันไทม์ดีกว่าค่าฮาร์ดโค้ด แต่ยังคงปรากฏในการตรวจสอบเอาต์พุตและบันทึก
กำหนดการสร้างอิมเมจใหม่ที่กำหนดไว้: ภาพเก่าสะสมช่องโหว่ จังหวะการสร้างใหม่ทุกเดือนทำให้หน้าต่างการรับแสงสามารถจัดการได้สำหรับการตั้งค่าส่วนใหญ่
อินเทอร์เฟซการจัดการที่อยู่เบื้องหลังการรับรองความถูกต้อง: แดชบอร์ดใดๆ บน IP สาธารณะที่ไม่มีการตรวจสอบสิทธิ์เป็นจุดเข้าใช้งานแบบเปิด ตำแหน่งเครือข่ายส่วนตัวจะดีกว่าหากเป็นไปได้
กำลังรวบรวมบันทึกคอนเทนเนอร์: หากไม่มีไปป์ไลน์บันทึก การตรวจจับเหตุการณ์จะขึ้นอยู่กับผลกระทบของระบบที่มองเห็นได้ นั่นเป็นสัญญาณที่ล่าช้าในการดำเนินการ
บทสรุป
การกำหนดค่าเริ่มต้นของ Docker สร้างขึ้นเพื่อความสะดวก ไม่ใช่ความปลอดภัย ข้อผิดพลาดส่วนใหญ่ที่กล่าวถึงในบทความนี้จะย้อนกลับไปที่การตั้งค่าที่ไม่เคยเปลี่ยนแปลงหลังจากการปรับใช้ครั้งแรก ไม่ใช่การโจมตีที่ซับซ้อน
การแก้ไขส่วนใหญ่เป็นการตัดสินใจกำหนดค่าแบบครั้งเดียว: คำสั่ง USER, การเปลี่ยนแปลงการเชื่อมโยงพอร์ต, เครือข่ายที่กำหนดเอง, กำหนดการสร้างใหม่ ไม่มีสิ่งใดที่ต้องการเครื่องมือใหม่สำหรับการตั้งค่าส่วนใหญ่
การทำให้การกำหนดค่าคอนเทนเนอร์ถูกต้องเป็นงานแรก โครงสร้างพื้นฐานที่ทำงานอยู่นั้นเป็นอย่างที่สอง ทั้งสองมีความสำคัญและไม่สามารถทดแทนสิ่งอื่นได้