ลด 50% ทุกแพ็กเกจ เวลาจำกัด เริ่มต้นที่ $2.48/mo
เหลืออีก 15 นาที
เครื่องมือสำหรับนักพัฒนาและ DevOps

ข้อผิดพลาดด้านความปลอดภัย Docker ที่ควรหลีกเลี่ยงในปี 2026

เรกซา ไซรัส By เรกซา ไซรัส อ่าน 15 นาที อัปเดตเมื่อ 23 วันที่แล้ว
กล่องโลหะที่ล้อมรอบด้วยโดมโครงลวดสีฟ้าเรืองแสง พร้อมชื่อบทความและโลโก้ Cloudzy บนพื้นหลังสีน้ำเงินเข้ม

คุณอาจรัน Docker ใน production มาหลายเดือนโดยไม่พบปัญหาที่มองเห็นได้ container เริ่มทำงาน แอปตอบสนอง ทุกอย่างดูปกติ แต่แค่ port ที่เปิดทิ้งไว้หรือสิทธิ์ที่ตั้งค่าผิดพลาดเพียงจุดเดียว ก็เปิดช่องให้ผู้โจมตีเข้ามาได้โดยไม่ต้องพยายามมาก ข้อผิดพลาดด้านความปลอดภัยส่วนใหญ่ใน Docker ไม่ได้ดูเหมือนข้อผิดพลาด จนกว่าจะเกิดเหตุการณ์จริง

บทความนี้ครอบคลุมการตั้งค่าเฉพาะที่ทำให้สภาพแวดล้อม container มีความเสี่ยง อธิบายว่าแต่ละการตั้งค่าเปิดช่องให้ผู้โจมตีทำอะไรได้บ้าง และปิดท้ายด้วย checklist ที่คุณนำไปตรวจสอบ setup ของตัวเองได้ทันที

ทำไมความปลอดภัยของ Docker จึงยากกว่าที่คิด

Container ให้ความรู้สึกว่าแยกตัวออกจากกัน คุณสร้างมันขึ้นมา มันรัน process space ของตัวเอง และจากภายใน container หนึ่งก็ไม่รู้จัก container อื่นเลย แต่การแยกตัวนั้นเป็นเพียงบางส่วน เพราะ container ใช้ kernel ของ host ร่วมกัน นั่นหมายความว่า process ภายใน container สามารถเข้าถึง host system ได้ทั้งหมดภายใต้เงื่อนไขบางอย่าง

Docker ถูกตั้งค่าเริ่มต้นมาเพื่อความสะดวกของนักพัฒนา ไม่ใช่เพื่อความปลอดภัยในระดับ production เปิด root access ไว้ ทุก port สามารถ bind กับทุก interface ไม่มี runtime monitoring นักพัฒนาส่วนใหญ่ยอมรับการตั้งค่าเหล่านั้น deploy container ออกไป แล้วก็ผ่านไป วิธีนี้สมเหตุสมผลสำหรับการเริ่มต้น แต่ไม่ใช่ security posture ที่สมบูรณ์

ตามที่ รายงาน 2024 State of Kubernetes Security ของ Red Hatองค์กรถึง 67% ล่าช้าหรือชะลอการ deploy แอปพลิเคชันเนื่องจากความกังวลด้านความปลอดภัยของ container หรือ Kubernetes ส่วนใหญ่ความล่าช้านั้นไม่ได้มาจากการถูกโจมตี แต่มาจากทีมที่ค้นพบว่า container setup ของตัวเองต้องการการ hardening ที่ยังไม่ได้ทำไว้

เราพบบ่อยครั้งที่ container รันใน production ด้วยการตั้งค่าชุดเดิมกับที่ใช้บนเครื่องของนักพัฒนา นั่นคือจุดที่ความผิดพลาดด้านความปลอดภัยของ Docker สะสมอย่างเงียบๆ โดยไม่มีสัญญาณใดๆ จนกว่าจะมีการตรวจสอบหรือเกิดปัญหาขึ้น

ความผิดพลาดที่ก่อให้เกิดช่องโหว่เหล่านั้นมีลักษณะเฉพาะ คาดเดาได้ และส่วนใหญ่หลีกเลี่ยงได้ตั้งแต่ระดับการตั้งค่า

ความผิดพลาดในการตั้งค่า Docker ที่พบบ่อย

การละเมิดความปลอดภัยของ container ส่วนใหญ่ไม่ได้เริ่มจาก zero-day exploit แต่เริ่มจากการตั้งค่าที่ทำไว้ตั้งแต่วันแรก โดยไม่ได้คิดมากเรื่อง network exposure หรือขอบเขตสิทธิ์

การตั้งค่าเริ่มต้นของ Docker ถูกออกแบบมาให้ใช้งานได้ ความเสี่ยงด้านความปลอดภัยของ Docker container สะสมอยู่ในช่องว่างระหว่าง "ใช้งานได้" กับ "ปลอดภัย" โดยเฉพาะใน self-hosted setup ที่ deploy แล้วไม่เคยกลับมาตรวจสอบอีก

เราเห็น pattern นี้บ่อยครั้ง: container บน server ที่มี public IP พร้อม port binding, การตั้งค่า user และ network configuration เหมือนกันทุกอย่างกับตอนที่ deploy ครั้งแรก

การรัน Container ในฐานะ Root

เมื่อคุณสร้าง Docker container โดยไม่ระบุ user มันจะรันในฐานะ root นั่นหมายความว่า process ทุกตัวภายใน container รวมถึงแอปพลิเคชันของคุณ จะมีสิทธิ์ระดับ root ภายใน namespace ของ container

ภาพ visualization ทางเทคนิคที่แสดงรายละเอียดสูง แสดง Docker container ที่ถูกจำกัดด้วยสัญลักษณ์ล็อกสีแดง "ACCESS DENIED" จาก host kernel ที่บังคับใช้ "NON-ROOT USER PRIVILEGES" (UID 1000)
การเป็น root ภายใน container ไม่เท่ากับการเป็น root บน host แต่การแยกส่วนนั้นไม่สมบูรณ์ Privilege escalation exploit ที่มุ่งเป้า runtime เช่น runc CVE-2019-5736 ที่มีเอกสารอ้างอิงชัดเจน และ runtime flaw ในลักษณะเดียวกัน มักต้องการ root container process เพื่อให้สำเร็จ

Container ที่ไม่ใช้ root จะตัดเงื่อนไขที่ exploit เหล่านั้นต้องพึ่งพาออกไป ซึ่งช่วยลด attack surface สำหรับช่องโหว่ประเภทนั้นได้อย่างมีนัยสำคัญ แม้จะไม่ได้กำจัดความเสี่ยงของ container escape ออกไปทั้งหมด

การเพิ่ม USER directive ใน Dockerfile ของคุณแก้ปัญหานี้ได้ image ทางการบางตัวมาพร้อม unprivileged user ที่คุณเปิดใช้งานได้ด้วย USER directive แต่หลายตัวยังคง default เป็น root โดยไม่มี app user สำเร็จรูป ในกรณีนั้น คุณต้องสร้าง user ใน Dockerfile ก่อนแล้วค่อย switch ไปใช้ สำหรับ self-hosted setup ส่วนใหญ่ การเปลี่ยนแปลงเพียงอย่างเดียวนี้ช่วยตัดความเสี่ยงจากการ escalation ทั้งหมวดออกไปได้

การเปิด Port มากเกินไปสู่ Public Internet

เมื่อคุณ publish port ด้วย Docker มันจะเขียน iptables rules โดยตรง rules เหล่านั้นทำงานก่อน firewall rules ระดับ host นี่คือ พฤติกรรมที่ community รายงานและรู้จักกันดี และ มีเอกสารใน packet filtering guide ของ Dockerไม่ใช่การตั้งค่าผิด และนั่นหมายความว่า UFW และเครื่องมือในลักษณะเดียวกันจะไม่บล็อก port ที่ Docker เปิดไว้แล้ว

shield หกเหลี่ยมขนาดใหญ่ที่เรืองแสงมีป้ายกำกับว่า "SECURE REVERSE PROXY" ทำหน้าที่เบี่ยงเบน traffic สีแดงที่ไม่น่าเชื่อถือ พร้อมแยก port binding ภายใน loopback เฉพาะออกจากกัน

Docker เขียนตรงไปที่ iptables โดยข้าม UFW และค่าเริ่มต้นของ firewalld บน Linux host หลายตัว นั่นหมายความว่า port ที่ bind กับ 0.0.0.0 อาจเข้าถึงได้จากสาธารณะแม้ firewall ของคุณดูเหมือนตั้งค่าแล้ว Cloud security group และ DOCKER-USER chain rules ยังสามารถบล็อก traffic นั้นได้ ดังนั้น exposure จริงขึ้นอยู่กับ network setup เฉพาะของคุณ

ผูก service ไว้กับ 127.0.0.1 ทุกครั้งที่ทำได้ ส่ง traffic สาธารณะผ่าน reverse proxy และเปิดเผยเฉพาะสิ่งที่ต้องการการเข้าถึงจากภายนอกจริงๆ reverse proxy คือวิธีที่เชื่อถือได้ที่สุดในการควบคุมว่าอะไรบ้างที่มองเห็นได้จากภายนอก host

การละเลยการแยก Network ระหว่าง Container

container ทุกตัวบน network เดียวกันสามารถเข้าถึงกันได้อย่างอิสระโดยไม่มีข้อจำกัด default bridge ไม่มีการกรอง traffic ระหว่าง container ที่ใช้งานร่วมกัน และส่วนใหญ่ไม่เคยเปลี่ยนการตั้งค่านี้

ภาพประกอบทางเทคนิคของ "ISOLATED CONTAINER NETWORKS" ที่แสดงการแยกทางกายภาพและเสมือนระหว่างสอง network zone (Subnet A และ Subnet B)

หาก container ตัวใดตัวหนึ่งถูกโจมตี การสื่อสารที่เปิดกว้างนั้นจะกลายเป็นเส้นทางสำหรับการเคลื่อนตัวข้างใน container ฝั่ง frontend สามารถเข้าถึง database, API ภายใน หรืออะไรก็ตามบน default bridge network เดียวกัน แม้ว่าการเข้าถึงนั้นจะไม่เคยตั้งใจให้เกิดขึ้นก็ตาม

User-defined network ให้คุณควบคุมได้อย่างชัดเจนว่า container ไหนสื่อสารกันได้บ้าง แต่ custom network เดียวที่ใช้ร่วมกันทั้งหมดก็ยังเปิดให้ traffic ไหลเวียนระหว่าง container ได้อย่างอิสระ การแยกที่แท้จริงต้องวาง service ที่ไม่ควรสื่อสารกันไว้บน network แยกกัน การปิด default bridge คือจุดเริ่มต้น ไม่ใช่จุดสุดท้าย

การมองข้าม Docker Socket

Docker socket ที่ /var/run/docker.sock คือ interface สำหรับควบคุม Docker engine ทั้งหมด การ mount เข้าไปใน container จะให้ container นั้นเข้าถึง API daemon ที่รันอยู่บน host โดยตรง

ภาพแสดง "Docker Socket" (การเข้าถึง API) ที่ได้รับการป้องกันอย่างแน่นหนา แต่ถูกเจาะผ่าน "SOCKET MOUNT PATHWAY" ซึ่งเทียบเท่ากับ "ROOT PRIVILEGE"

ด้วยการเข้าถึงนั้น container สามารถเริ่ม container ใหม่ mount directory ของ host ตรวจสอบและแก้ไข container ที่กำลังรันอยู่ และควบคุม host machine ได้อย่างมีประสิทธิภาพ พื้นที่โจมตีเทียบเท่ากับ root บน host ดังนั้นเครื่องมือใดที่ต้องการเข้าถึง socket จึงควรได้รับการพิจารณาอย่างรอบคอบ

สำหรับกรณีใช้งานส่วนใหญ่ มีทางเลือกที่ปลอดภัยกว่า เช่น API แบบกำหนดขอบเขต หรือ เครื่องมือจัดการ Docker ที่ไม่จำเป็นต้องเข้าถึง socket Docker-in-Docker มีข้อแลกเปลี่ยนด้านความปลอดภัยและการดำเนินงานของตัวเอง และไม่ใช่ทางเลือกทดแทนที่ตรงไปตรงมา

ความผิดพลาดด้าน configuration สร้างช่องโหว่เริ่มต้น ส่วนการเลือก image และ dependency กำหนดว่าช่องโหว่นั้นจะขยายตัวอย่างไรตามเวลา

ความผิดพลาดด้าน Image และ Secret ที่ยังคงอยู่แม้ Container จะหยุดทำงาน

เมื่อคุณหยุด container ความผิดพลาดด้าน configuration ภายในก็หยุดไปด้วย แต่เมื่อคุณ rebuild จาก image ที่มีช่องโหว่หรือ credential ที่ฝังค่าไว้ตายตัว ปัญหาก็จะกลับมาพร้อมกับ container ความผิดพลาดในระดับ image ไม่ได้ถูก reset ระหว่างการ deploy

ความผิดพลาดเหล่านั้นติดไปกับ image ทุกสภาพแวดล้อมที่ดึง image ไปใช้ ทุก registry ที่จัดเก็บ และทุกคนในทีมที่รัน image นั้น ความถาวรนี้ทำให้การจัดการ image และ secret เป็นความเสี่ยงประเภทหนึ่งที่แยกออกมาต่างหาก และควรตรวจสอบแยกจาก configuration

รูปแบบนี้เกิดขึ้นบ่อย นั่นคือ image ที่เลือกอย่างระมัดระวังตั้งแต่เริ่มโปรเจกต์และไม่เคย rebuild อีกเลย ค่อยๆ ห่างจาก baseline ด้านความปลอดภัยที่เคยเป็นอยู่

การใช้ Image ที่ไม่น่าเชื่อถือหรือล้าสมัย

ทุกคนสามารถอัปโหลดไปยัง public registry ได้ มี image อันตรายที่ถูกแจกจ่ายผ่าน Docker Hub โดยฝัง crypto-miner และ backdoor ไว้ใน layer history ที่ยังคงอยู่แม้ container จะ restart การตรวจสอบก่อนดึง image มาใช้จึงสำคัญมาก โดยเฉพาะ image จากผู้เผยแพร่ที่ไม่เป็นทางการหรือไม่รู้จัก

ภาพ scanner ดิจิทัลที่กำลังตรวจสอบ "Official Image" พร้อมกับปฏิเสธ block "UNTRUSTED OR OUTDATED IMAGE" ที่มีสัญญาณผิดปกติ สนับสนุนด้วยกราฟข้อมูล "95% FIX AVAILABLE"

อีกปัญหาหนึ่งคือความล้าสมัย official image ที่คุณดึงมาเมื่อหกเดือนก่อนและไม่เคย rebuild นั้น กำลังสะสมช่องโหว่ Docker ที่ยังไม่ได้แก้ไขทุกครั้งที่มีการเปิดเผย CVE กับ package ของมัน image ไม่ได้เสียหาย เพียงแต่ไม่ทันสมัยอีกต่อไป

รายงาน Sonatype's 2024 State of the Software Supply Chain พบว่า 95% ของเวลาที่มีการใช้งาน component ที่มีช่องโหว่ จะมี version ที่แก้ไขแล้วพร้อมให้ใช้งาน และ 80% ของ dependency ในแอปพลิเคชันยังไม่ได้รับการอัปเกรดมานานกว่าหนึ่งปี รูปแบบนี้เกี่ยวข้องกับ Docker base image เช่นกัน เนื่องจากใช้ open-source package ชุดเดียวกัน

ใช้ official image จากผู้เผยแพร่ที่ผ่านการตรวจสอบและระบุ version tag ที่แน่นอนแทนการใช้ "latest" วางแผน rebuild อย่างสม่ำเสมอเพื่อให้ image ของคุณทันสมัยอยู่เสมอ

การ Hardcode Secret ใน Docker Files และ Compose Files

Credential ที่เขียนตรงลงใน ENV หรือ ARG instruction ของ Docker file, hardcode ไว้ใน Compose environment block, ส่งผ่านเป็น build argument หรือเก็บในไฟล์ .env ที่ commit เข้า version control นั้นไม่ได้หายไปพร้อมกับการหยุด container แต่ยังคงอยู่ใน image layer history หรือ source control ซึ่งใครก็ตามที่เข้าถึงสิ่งเหล่านั้นได้ก็สามารถดูข้อมูลได้

ภาพ 3D แบบ photorealistic แสดง vault ของ "RUNTIME SECRETS MANAGER" ที่กำลังส่ง cryptographic key ผ่าน pipeline พร้อมข้อความยืนยันว่า "SECRETS REMOVED FROM BUILD LAYERS"

นี่คือข้อผิดพลาดด้านความปลอดภัยของ Docker ที่ถูกมองข้ามมากที่สุด เพราะในระหว่าง development จะไม่เห็นปัญหาใดๆ API key ใน ENV instruction ทำงานได้ปกติ แต่มันก็อยู่ใน repository ของคุณ ฝังอยู่ใน image และกระจายไปทุกที่ที่ image นั้นถูกใช้งาน

Docker Compose รุ่นใหม่รองรับ secrets mechanism แบบ native ที่ mount credential ในเวลา runtime โดยไม่ต้องฝังไว้ใน image Docker secrets API และ external secrets manager ก็ใช้หลักการเดียวกัน วิธีการเหล่านี้ช่วยให้ credential ไม่ปรากฏใน build artifact หรือไฟล์ที่ commit เข้า repository เลย

การใช้ environment variable ในเวลา runtime ดีกว่าการ hardcode credential แต่ยังคงถูกเปิดเผยผ่าน Docker inspect output, log และ crash dump ถือเป็นการพัฒนาขึ้นจากการฝัง secret ไว้ใน image แต่ยังไม่ใช่แนวทางที่สมบูรณ์

การไม่อัปเดต Container Image อย่างสม่ำเสมอ

การรัน image เดิมนานหลายเดือนเป็นเรื่องที่พบบ่อย ทุกวันที่ผ่านไปหลังจากมีการเปิดเผยช่องโหว่ใหม่ แต่ก่อนที่คุณจะ rebuild นั้น container ของคุณมีช่วงเวลาที่เสี่ยงต่อการถูกโจมตีและยิ่งนานขึ้นเรื่อยๆ โดยไม่มีสัญญาณใดให้เห็น

วางแผนตาราง rebuild ที่สม่ำเสมอ ทำให้เป็น automation ทุกที่ที่ทำได้ และรัน vulnerability scanner กับ image ปัจจุบันเป็นระยะ เป้าหมายไม่ใช่ความสมบูรณ์แบบ แต่คือการลดช่วงเวลาระหว่างการปล่อย patch กับการ deploy จริง

Access control และ monitoring มักถูกลดลำดับความสำคัญในการ deploy ที่รวดเร็ว และนี่คือหมวดหมู่ที่เหตุการณ์ด้านความปลอดภัยมักถูกตรวจพบช้าที่สุด

ช่องว่างด้าน Access Control และ Visibility

เมื่อ container ทำงานด้วย configuration ที่ดีและ image ที่เป็นปัจจุบันแล้ว ยังมีปัญหาสองประเภทที่หลงเหลืออยู่ ทั้งสองมองไม่เห็นโดยธรรมชาติ คุณจะไม่รู้ว่า access control อ่อนแอจนกว่าจะมีคนใช้ประโยชน์จากมัน และจะไม่รู้ว่ามี monitoring gap จนกว่าจะต้องสืบสวนกิจกรรมที่ไม่เคยถูกบันทึกไว้

เหมือนกัน งานวิจัยของ Red Hat ปี 2024 พบว่า 42% ของทีมขาดความสามารถเพียงพอในการรับมือกับความปลอดภัยของ container และภัยคุกคามที่เกี่ยวข้อง

เราพบว่า monitoring gap มักปรากฏให้เห็นในระหว่างการสืบสวนเหตุการณ์ ไม่ใช่ก่อนหน้านั้น กว่าจะตระหนักว่า visibility สำคัญ มักเป็นตอนที่กำลังตอบสนองต่อเหตุการณ์แล้ว ไม่ใช่การป้องกันล่วงหน้า

การ Authentication ที่อ่อนแอและ Management Dashboard ที่เปิดเผย

ถ้า container management dashboard วางอยู่บน public IP โดยไม่มีการ authenticate ผู้โจมตีไม่จำเป็นต้องมีทักษะสูง แค่รู้ address ก็พอ ซึ่งเป็นเงื่อนไขที่ง่ายกว่าที่หลายทีมคิด

ภาพแสดง management console ที่ไม่มีการป้องกัน (9 nodes, 1100 containers) ที่มี "DEFAULT CREDENTIALS" นำตรงไปสู่ "PUBLIC INTERNET ACCESS" โดยไม่มีข้อจำกัดใดๆ

เครื่องมือ monitoring และ management แบบ self-hosted มักมาพร้อม web interface ที่เข้าถึงได้จากทุก network interface การทิ้งไว้บน public IP โดยไม่มีการ authenticate นั้นเหมือนกับการปล่อยให้ admin panel ของ container เปิดค้างไว้โดยไม่ล็อก

Authentication, reverse proxy และการวาง management tool ไว้ใน private network คือพื้นฐานที่ต้องมี Access control เป็นขั้นตอน configuration ที่ต้องเพิ่มเองในทุก management interface ไม่ใช่สิ่งที่เปิดใช้งานมาให้แต่แรก

หลักการเดียวกันนี้ใช้กับ Docker CLI และ GUI managementการเข้าถึงระดับ admin ต่อ daemon นั้นมีความเสี่ยงเท่ากันไม่ว่าจะใช้ interface แบบใด

การไม่ตรวจสอบกิจกรรมของ Container

ถ้า container ถูก compromise กิจกรรมของผู้โจมตีจะทิ้งร่องรอยไว้เสมอ: พฤติกรรมของ process ที่เปลี่ยนไป การเชื่อมต่อเครือข่ายที่ผิดปกติ และการแก้ไขไฟล์ที่ไม่คาดคิด หากไม่มีการเก็บ log ไว้ ร่องรอยเหล่านั้นก็ไม่มีอยู่ในรูปแบบที่คุณจะนำไปใช้ดำเนินการได้

การรวบรวม log แบบรวมศูนย์ เครื่องมือตรวจสอบ audit log ของ container และการมอนิเตอร์ runtime จะให้ข้อมูลที่จำเป็นสำหรับตรวจจับพฤติกรรมผิดปกติก่อนที่จะลุกลาม เป้าหมายไม่ใช่การวิเคราะห์ทุก log line แต่คือการมีข้อมูลพร้อมเมื่อต้องสืบสวนปัญหา

Container ที่รันอยู่บน production โดยไม่มี log pipeline และไม่มี alert ไม่ได้หมายความว่าดูแลง่าย แต่หมายความว่าไม่มีใครตรวจสอบ ทั้งสองสถานะนี้แตกต่างกันโดยสิ้นเชิง

ทำไมสภาพแวดล้อมของโครงสร้างพื้นฐานจึงสำคัญ

ความปลอดภัยของ container เริ่มต้นที่การตั้งค่า แต่การตั้งค่านั้นรันอยู่บนโครงสร้างพื้นฐาน host ที่มีปัญหาด้าน network configuration, ทรัพยากรที่ใช้ร่วมกัน หรือขาด network-level filtering จะสร้างเงื่อนไขที่ส่งผลกระทบต่อทุก container ที่รันอยู่บนมัน การตั้งค่า container ให้ถูกต้องและการตั้งค่า server ให้ถูกต้องเป็นงานคนละส่วนกัน

ช่องโหว่ความปลอดภัยของ Docker หลายอย่างถูกขยายให้รุนแรงขึ้นจากเงื่อนไขที่ container รับมาโดยตรง ได้แก่

  • server แบบ shared-tenancy ที่ไม่มีการแยก hardware ระหว่าง tenant
  • host kernel ที่ยังไม่ได้ติดตั้ง patch
  • host ที่ไม่มี network-level filtering ในตัว

สิ่งนี้ไม่ได้ตัดความจำเป็นในการทำ configuration ตามขั้นตอนข้างต้น เพราะการ harden container อย่างถูกต้องยังคงสำคัญไม่ว่า infrastructure layer จะเป็นอะไรก็ตาม การเริ่มต้นบน isolated infrastructure ช่วยตัดความกังวลออกไปหนึ่งชั้น

ที่ Cloudzy เรามีสองแนวทางให้เลือกตามความต้องการของคุณ:

  • Linux VPS: สภาพแวดล้อมที่พร้อมให้ deploy Docker เองและทำ hardening ตามขั้นตอนในบทความนี้
  • Portainer VPS: ตัวเลือกแบบคลิกเดียวที่ติดตั้ง Portainer มาให้แล้ว เมื่อ server บูทเสร็จคุณก็เข้า dashboard ได้เลย

ทั้งสองตัวเลือกรันบน infrastructure เดียวกัน: KVM virtualization, AMD Ryzen 9 CPU ความเร็ว boost clock สูงสุด 5.7 GHz, หน่วยความจำ DDR5, พื้นที่จัดเก็บ NVMe SSD, เครือข่ายสูงสุด 40 Gbps และการป้องกัน DDoS ฟรีผ่าน BuyVM filtering ครอบคลุม 12 ที่ตั้งทั่วโลก พร้อม uptime SLA ที่ 99.95%

สำหรับรายละเอียดเพิ่มเติมเกี่ยวกับการรัน Portainer บน VPS เราได้เขียนไว้ในบทความเฉพาะแล้ว

Checklist ความปลอดภัยเชิงปฏิบัติสำหรับการ deploy Docker

ข้อผิดพลาดด้านความปลอดภัยของ Docker ส่วนใหญ่มาจากการตัดสินใจตั้งค่าครั้งเดียวแล้วไม่เคยกลับมาทบทวน การรัน checklist นี้กับ setup ที่มีอยู่จะช่วยจับช่องโหว่เหล่านั้นได้ ใช้เป็น audit ไม่ใช่คู่มือ deploy

แนวปฏิบัติด้านความปลอดภัยของ Docker เหล่านี้ครอบคลุมวิธีป้องกัน Docker container จากความผิดพลาดในการตั้งค่าที่พบบ่อยที่สุดตามที่อธิบายไว้ข้างต้น

Quick Reference: ข้อผิดพลาดทั้ง 9 ข้อ

ความผิดพลาด หมวดหมู่ วิธีแก้แบบสั้น
ทำงานเป็น root การตั้งค่า เพิ่ม USER directive ใน Dockerfile ของคุณ
พอร์ตที่ผูกมัดกับ 0.0.0.0 การตั้งค่า Bind กับ 127.0.0.1 และส่งผ่าน reverse proxy
ไม่มีการแยกเครือข่าย การตั้งค่า แยก service ไปยัง network ที่กำหนดเองแต่ละอันตามสิทธิ์การเข้าถึง
Docker socket ที่ mount อยู่ การตั้งค่า ลบ mount ออก แล้วใช้ API แบบจำกัดขอบเขตหรือตัวเลือกอื่นแทน
image ที่ไม่น่าเชื่อถือหรือล้าสมัย รูปภาพ ใช้ official image พร้อมระบุ version tag แบบตรึงค่าไว้
ข้อมูลลับที่ฝังแข็ง รูปภาพ ย้าย credentials ไปไว้ใน runtime env vars หรือ secrets manager
ไม่มีกำหนดการ rebuild image รูปภาพ กำหนด cadence การ rebuild รายเดือน และทำให้เป็นอัตโนมัติเท่าที่ทำได้
แดชบอร์ดที่ไม่ได้รับการยืนยันตัวตน การเข้าถึง เพิ่มการยืนยันตัวตนและย้าย management UI ไปไว้ใน private network
ไม่มีการเก็บ container log การเข้าถึง ตั้งค่าระบบ logging แบบรวมศูนย์และการ monitoring แบบ runtime

แนะนำให้ลองรันกับระบบที่ใช้งานอยู่แล้วก่อน เพราะช่องโหว่มักซ่อนอยู่ในส่วนนั้น

Container ที่รันในโหมด non-root: ตรวจสอบ Docker ไฟล์ว่ามี USER directive หรือไม่ ถ้าไม่มี container จะรันในฐานะ root

Port binding จำกัดไว้ที่ localhost หรือผ่าน proxy: รัน docker ps แล้วตรวจสอบ port binding หาก entry เป็น 0.0.0.0:PORT จะสามารถเข้าถึงได้จากภายนอก ในกรณีที่ไม่มี security group, firewall ภายนอก หรือ rule ของ DOCKER-USER chain มาบล็อกไว้

กำลังใช้งาน custom bridge network: Container บน default bridge ของ Docker สามารถติดต่อกันได้อย่างอิสระ Container บน user-defined bridge เดียวกันก็ยังคุยกันได้ ดังนั้นควรแยก service ออกเป็น network ต่างๆ ตาม trust boundary เพื่อให้ได้ isolation ที่แท้จริง

ไม่มีการ mount Docker socket เข้าไปใน container: ตรวจสอบ Compose file และ argument ที่ใช้รัน หาก /var/run/docker.sock ปรากฏเป็น volume ให้ยืนยันว่าจำเป็นและตั้งใจให้เป็นแบบนั้น

Base image จาก publisher ที่ได้รับการยืนยัน พร้อมระบุ version แบบตรึงค่าไว้: การใช้ FROM ubuntu:latest จะดึง version ที่ไม่แน่นอนและอาจล้าสมัย ควรระบุ release ที่ต้องการให้ชัดเจน

ไม่มี secret ใน Docker ไฟล์, Compose file หรือ build argument: ประวัติ layer ของ image จะเก็บ credentials ไว้แม้จะลบ container ไปแล้ว ให้ใช้ Compose secrets, Swarm secrets, build secret mount หรือ external secrets manager แทน การใช้ runtime environment variable ดีกว่าการ hardcode แต่ยังคงปรากฏใน inspect output และ log

กำหนด schedule การ rebuild image ไว้แล้ว: Image เก่าสะสม vulnerability ไปเรื่อยๆ การ rebuild รายเดือนช่วยให้ช่วงเวลาที่เสี่ยงอยู่ในระดับที่จัดการได้สำหรับส่วนใหญ่

Management interface อยู่หลังระบบยืนยันตัวตน: Dashboard ที่เปิดบน public IP โดยไม่มีการยืนยันตัวตนถือเป็นช่องทางเข้าที่เปิดโล่ง การวางไว้ใน private network จะดีกว่าเสมอหากทำได้

กำลังเก็บ container log อยู่: ถ้าไม่มี log pipeline การตรวจจับเหตุการณ์ผิดปกติจะรอให้ระบบแสดงอาการก่อน ซึ่งนั่นช้าเกินไปสำหรับการรับมือ


สรุป

การตั้งค่าเริ่มต้นของ Docker ออกแบบมาเพื่อความสะดวก ไม่ใช่ความปลอดภัย ข้อผิดพลาดส่วนใหญ่ในบทความนี้มีต้นเหตุจากการตั้งค่าที่ไม่เคยถูกเปลี่ยนหลัง deploy ครั้งแรก ไม่ใช่จากการโจมตีที่ซับซ้อนแต่อย่างใด

การแก้ไขส่วนใหญ่เป็นการตัดสินใจตั้งค่าครั้งเดียว: USER directive, การเปลี่ยน port binding, custom network, หรือกำหนดตารางการ rebuild สำหรับระบบส่วนใหญ่ไม่จำเป็นต้องใช้เครื่องมือใหม่เลย

การตั้งค่า container ให้ถูกต้องคือสิ่งแรกที่ต้องทำ โครงสร้างพื้นฐานที่รัน container นั้นคือสิ่งที่สอง ทั้งสองส่วนสำคัญเท่ากัน และไม่มีอันไหนทดแทนกันได้

คำถามที่พบบ่อย

Docker ปลอดภัยตั้งแต่ต้นหรือไม่?

ไม่ใช่ Docker ถูกตั้งค่ามาเพื่อให้ติดตั้งได้เร็ว ไม่ใช่เพื่อความปลอดภัย สิทธิ์ root เปิดอยู่โดยค่าเริ่มต้น และไม่มีการ monitor runtime รวมมาด้วย การเข้าถึงระหว่าง container และการเปิด port ขึ้นอยู่กับวิธีที่คุณเริ่ม container หรือตั้งค่า Compose project แต่ค่าเริ่มต้นเอื้อต่อการเปิดกว้างมากกว่าการจำกัดสิทธิ์

นักพัฒนามักทำข้อผิดพลาดด้านความปลอดภัยของ Docker อะไรบ้าง?

ที่พบบ่อยที่สุดได้แก่: รัน container ในฐานะ root, เปิด port สู่สาธารณะโดยไม่มี proxy, ใช้ image ที่ไม่น่าเชื่อถือหรือล้าสมัย, เขียน credentials ตายตัวใน Dockerfile, ไม่แยก network, และปล่อยให้ management dashboard ไม่มีการยืนยันตัวตน

จะเกิดอะไรขึ้นถ้า Docker container รันในฐานะ root?

process ภายใน container จะมีสิทธิ์ระดับ root ใน namespace นั้น หาก process นั้นโจมตีช่องโหว่ของ runtime ได้สำเร็จ อาจยกระดับสิทธิ์ขึ้นไปถึง host ได้ การรันในฐานะ non-root ลดความเสี่ยงนี้และหยุดการโจมตีที่ต้องพึ่งสิทธิ์ root ภายใน container แต่ก็ไม่ได้ปิดทุกช่องทางการยกระดับสิทธิ์ การใช้ rootless mode และการตั้งค่าสิทธิ์ขั้นต่ำช่วยเพิ่มการป้องกันอีกหลายชั้น

จะป้องกันไม่ให้ secrets รั่วไหลใน Docker image ได้อย่างไร?

อย่าใส่ credentials ใน Dockerfile, คำสั่ง ENV, หรือ environment block ใน Compose ให้ใช้ Compose secrets, Swarm secrets, หรือ secrets manager ภายนอกแทน ตัวแปร environment ตอน runtime เป็นทางเลือกสำรองเท่านั้น ไม่ใช่วิธีหลัก เพราะยังมองเห็นได้ใน inspect output อยู่ดี

ทำไมการ mount Docker socket จึงอันตราย?

การ mount /var/run/docker.sock ให้ container เข้าถึง API daemon ของ Docker โดยตรง รวมถึงความสามารถในการเริ่ม container, mount directory ของ host, และแก้ไข container ที่กำลังรันอยู่ ระดับการเข้าถึงนี้เทียบเท่ากับสิทธิ์ root บน host

ควร update Docker image บ่อยแค่ไหน?

การ rebuild ทุกเดือนเป็นเกณฑ์ขั้นต้นที่ใช้งานได้จริงสำหรับระบบ production ส่วนใหญ่ เป้าหมายคือลดช่วงเวลาระหว่างที่ patch พร้อมใช้งานจนถึงตอนที่ deploy จริง pipeline ที่ rebuild อัตโนมัติช่วยตัดช่วงเวลานี้ให้สั้นลงโดยไม่ต้องกำหนดตารางเอง

แชร์

บทความอื่นจากบล็อก

อ่านต่อ

โครงสาม มิติลูกบาศก์เรืองแสงสีน้ำเงินแทน Docker containers พร้อมข้อความ 'Portainer vs Yacht: Which Docker UI Should You Choose' และโลโก้ Cloudzy
เครื่องมือสำหรับนักพัฒนาและ DevOps

Portainer vs Yacht: ควรเลือก Docker UI ตัวไหนในปี 2026?

การจัดการ Docker containers ผ่าน CLI เหมาะกับ setup ขนาดเล็ก แต่เมื่อจำนวน container เพิ่มขึ้น การติดตาม state, log และอัปเดตด้วยตนเองก็เริ่มเกิดข้อผิดพลาด

เรกซา ไซรัสเรกซา ไซรัส อ่าน 13 นาที
เครื่องมือ Continuous Integration
เครื่องมือสำหรับนักพัฒนาและ DevOps

เครื่องมือ CI/CD ที่ดีที่สุดสำหรับ DevOps ในปี 2026

วงการพัฒนาซอฟต์แวร์เปลี่ยนแปลงเร็วกว่าที่เคยเป็นมา ถ้าไม่อยากตามไม่ทัน ควรนำแนวทาง DevOps และ Agile มาใช้

เอดา เลิฟกูดเอดา เลิฟกูด อ่าน 11 นาที
เลือก OS ที่ดีที่สุดสำหรับการเขียนโปรแกรม
เครื่องมือสำหรับนักพัฒนาและ DevOps

OS ที่ดีที่สุดสำหรับการเขียนโปรแกรมและ Coding ปี 2025

การเลือก OS สำหรับเขียนโปรแกรมไม่ใช่เรื่องของการทำตาม influencer ด้านเทคโนโลยีอีกต่อไป ระบบปฏิบัติการที่คุณเลือกกำหนดว่าเครื่องมือไหนใช้งานได้จริง และ

เรกซา ไซรัสเรกซา ไซรัส อ่าน 13 นาที

พร้อม Deploy แล้วหรือยัง? เริ่มต้นที่ $2.48/เดือน

Cloud อิสระ ให้บริการมาตั้งแต่ปี 2008. AMD EPYC, NVMe, 40 Gbps. คืนเงินภายใน 14 วัน