ทำไม Docker Security ถึงสำคัญ?
Container ที่ตั้งค่าไม่ดีอาจเป็นช่องโหว่ให้ Attacker โจมตี Server ได้ Docker Security ไม่ใช่เรื่องน่ากลัวแต่เป็นสิ่งที่ต้องใส่ใจจริงๆ
1. ไม่รัน Container ในฐานะ root
# สร้าง User ใน Dockerfile
FROM node:20-alpine
RUN addgroup -g 1001 appgroup && \
adduser -u 1001 -G appgroup -s /bin/sh -D appuser
WORKDIR /app
COPY --chown=appuser:appgroup . .
USER appuser
EXPOSE 3000
CMD ["node", "index.js"]
2. ใช้ Official Image และ Pin Version
# สิ้นเปลือง
FROM node:latest # ไม่บอกเวอร์ชัน
FROM node # ไม่ระบุเวอร์ชัน
# ดีกว่า
FROM node:20.11.0-alpine3.19 # Pin เวอร์ชันครั้งเดียว
# หรือใช้ image digest
FROM node@sha256:abc123...
3. Scan Image หาช่องโหว่
# ด้วย Docker Scout
docker scout cves myapp:latest
# ด้วย Trivy (อิสระ เปิดซอร์ส)
trivy image myapp:latest
# ติดตั้ง Trivy
curl -sfL https://raw.githubusercontent.com/aquasecurity/trivy/main/contrib/install.sh | sh
4. Read-Only Filesystem
docker run --read-only \
--tmpfs /tmp \
--tmpfs /var/run \
myapp:latest
# ใน Docker Compose
services:
app:
image: myapp:latest
read_only: true
tmpfs:
- /tmp
- /var/run
5. จำกัด Capabilities
# ลบ Capabilities ทั้งหมดแล้วเพิ่มเฉพาะที่จำเป็น
docker run --cap-drop ALL --cap-add NET_BIND_SERVICE myapp:latest
# ใน Docker Compose
services:
app:
cap_drop:
- ALL
cap_add:
- NET_BIND_SERVICE
6. ไม่ Mount Docker Socket ใน Container
# อันตราย! ใครที่เข้าถึง Container นี้จะคุม Docker daemon ได้
volumes:
- /var/run/docker.sock:/var/run/docker.sock # หลีกเลี่ยงเว้นมีเหตุผลจำเป็น!
7. ใช้ Secrets แทน Environment Variables
# Docker Secrets (สำหรับ Docker Swarm)
echo "mysecretpassword" | docker secret create db_password -
# ใน Docker Compose (ไม่ใช้เนื้อหาสำหรับไฟล์ .env)
# สร้างไฟล์ .env และไม่commit เข้า git
DB_PASSWORD=securepassword
8. Resource Limits
services:
app:
image: myapp:latest
deploy:
resources:
limits:
cpus: '0.5'
memory: 512M
reservations:
cpus: '0.25'
memory: 256M
9. Network Isolation
services:
frontend:
networks:
- public_net
- internal_net
backend:
networks:
- internal_net
database:
networks:
- internal_net
networks:
public_net:
internal_net:
internal: true # ไม่เชื่อมต่อสู่ภายนอก
10. Security Scanning ใน CI/CD
# GitHub Actions
- name: Scan Image
uses: aquasecurity/trivy-action@master
with:
image-ref: myapp:${{ github.sha }}
format: 'table'
exit-code: '1'
severity: 'CRITICAL,HIGH'
สรุป Checklist
- ✅ รันด้วย non-root user
- ✅ Pin version ของ base image
- ✅ Scan หา CVE สม่ำเสมอ
- ✅ Read-only filesystem ถ้าเป็นไปได้
- ✅ จำกัด Capabilities
- ✅ Resource Limits
- ✅ Network Isolation
- ✅ ไม่ Mount Docker Socket

