Security DevSecOps DevOps

DevSecOps — Security พื้นฐานที่ DevOps ต้องรู้ 🔐

By Anirach Mingkhwan DevOps & Vibe Coding 2026
DevSecOps — security dog with locks and shields

ตลอด 9 โพสต์ที่ผ่านมาเราเรียนรู้ DevOps ตั้งแต่ Git, Docker, K8s, IaC, Monitoring ไปจนถึง Linux

แต่ถ้า deploy ทุกอย่างขึ้น production แล้ว โดน hack? ข้อมูล user หลุด? Server ถูกยึด? 😱

Security ไม่ใช่ "เรื่องของทีม security" — มันเป็น เรื่องของทุกคนที่ deploy code ขึ้น production นี่คือ DevSecOps — ฝัง security เข้าไปในทุกขั้นตอนของ DevOps 🔐🐕


DevSecOps คืออะไร?

DevSecOps = Development + Security + Operations — แทนที่จะเช็ค security ตอนท้าย ให้ทำตั้งแต่ต้น:

📝 Plan
Threat modeling
💻 Code
Secret scanning
🔨 Build
SAST + SCA
🧪 Test
DAST + Pen test
🚀 Deploy
Image scanning
📊 Monitor
Runtime protection
💡 Shift Left: ยิ่งเจอ bug/vulnerability เร็ว ยิ่งแก้ถูก — หาตอน code ถูกกว่าหาตอน production 100 เท่า!

OWASP Top 10 — ช่องโหว่ยอดฮิต

OWASP Top 10 คือรายการช่องโหว่ที่พบบ่อยที่สุดใน web applications:

#ช่องโหว่ตัวอย่างป้องกัน
A01Broken Access ControlUser A เข้าถึงข้อมูล User BRBAC, JWT validation
A02Cryptographic FailuresPassword เก็บ plain textbcrypt, AES-256, TLS
A03InjectionSQL Injection, XSSParameterized queries, sanitize
A04Insecure Designไม่ rate limit loginThreat modeling, design review
A05Security MisconfigurationDebug mode on productionHardening, IaC scan
A06Vulnerable Componentsใช้ library เก่าที่มี CVESCA, Dependabot
A07Auth FailuresWeak password, no MFAMFA, strong password policy
A08Data Integrity FailuresUntrusted CI/CD pluginsVerify signatures, pin versions
A09Logging Failuresไม่ log login attemptsAudit logging, SIEM
A10SSRFServer เรียก internal API ให้Allowlist, network segmentation

🔑 Secrets Management — อย่าเก็บ secret ใน code!

Secrets Management คือการจัดการข้อมูลลับ (passwords, API keys, tokens, certificates) อย่างปลอดภัย ข้อผิดพลาดที่พบบ่อยที่สุดคือ hardcode secrets ใน source code แล้ว commit เข้า Git — แม้จะลบภายหลัง Git history ยังเก็บไว้! ตัวอย่างที่เห็นบ่อย:

❌ อย่าทำแบบนี้เด็ดขาด!
# ❌ WRONG — secret ใน code
DATABASE_URL="postgres://admin:P@[email protected]:5432/mydb"
API_KEY="sk-1234567890abcdef"

# ❌ WRONG — secret ใน Dockerfile
ENV AWS_SECRET_KEY=AKIAxxxxxxxxxxx

# ❌ WRONG — secret ใน docker-compose.yml
environment:
  - DB_PASSWORD=mysecretpassword

✅ วิธีที่ถูกต้อง

แทนที่จะ hardcode ให้ใช้ environment variables หรือ secrets manager (AWS Secrets Manager, HashiCorp Vault, GitHub Secrets) เก็บ secrets แยกจาก code ทำให้เปลี่ยน secrets ได้โดยไม่ต้องแก้ code และ secrets ไม่เข้า Git:

# 1. Environment Variables (ง่ายสุด)
export DB_PASSWORD="$(cat /run/secrets/db_password)"

# 2. Docker Secrets
echo "mysecretpassword" | docker secret create db_password -
# → ใช้ใน docker-compose:
services:
  app:
    secrets:
      - db_password
secrets:
  db_password:
    external: true

# 3. HashiCorp Vault (production-grade)
vault kv put secret/myapp db_password="P@ssw0rd"
vault kv get secret/myapp

# 4. AWS Secrets Manager / GCP Secret Manager
aws secretsmanager get-secret-value --secret-id myapp/db_password

# 5. .env file (dev only — อย่า commit!)
# .gitignore ต้องมี:
.env
.env.local
*.pem
*.key

Git Secret Scanning

แม้จะระวังแล้ว บางครั้ง secrets ก็หลุดเข้า Git ได้ Secret scanning ช่วยตรวจจับอัตโนมัติ — ทั้ง pre-commit hook (ป้องกันก่อน commit) และ CI pipeline (ตรวจซ้ำทุก PR) เครื่องมือเช่น Gitleaks และ GitHub Secret Scanning สแกนหา patterns ของ API keys, tokens, passwords:

# ติดตั้ง git-secrets ป้องกัน commit secrets
git secrets --install
git secrets --register-aws     # ตรวจ AWS keys

# ใช้ truffleHog scan repo ทั้งหมด
trufflehog git https://github.com/myorg/myrepo

# ใช้ gitleaks
gitleaks detect --source . --verbose

# GitHub: เปิด Secret Scanning (Settings → Security)
# → แจ้งเตือนทันทีถ้ามี secret หลุดเข้า repo

🐳 Container Security

Containers มีความเสี่ยงด้าน security หลายจุด — base image อาจมี vulnerabilities, Dockerfile อาจ expose secrets, runtime อาจให้สิทธิ์มากเกินไป (root access) การ secure containers ต้องทำทั้ง 3 ระดับ: build time (Dockerfile best practices), registry (image scanning), และ runtime (least privilege, read-only filesystem):

Dockerfile Best Practices

Dockerfile ที่ปลอดภัยต้อง: ใช้ specific version tags (ไม่ใช่ latest), ใช้ non-root user, ใช้ multi-stage builds เพื่อลดขนาดและ attack surface, และอย่า COPY secrets เข้า image:

# ❌ BAD — ใช้ root, image ใหญ่, ไม่ pin version
FROM node:latest
COPY . .
RUN npm install
CMD ["node", "app.js"]

# ✅ GOOD — non-root, minimal image, pinned version, multi-stage
FROM node:20-alpine AS builder
WORKDIR /app
COPY package*.json ./
RUN npm ci --only=production

FROM node:20-alpine
RUN addgroup -S app && adduser -S app -G app
WORKDIR /app
COPY --from=builder /app/node_modules ./node_modules
COPY --chown=app:app . .
USER app
EXPOSE 3000
HEALTHCHECK CMD curl -f http://localhost:3000/health || exit 1
CMD ["node", "app.js"]

Image Scanning

Image scanning ตรวจหา known vulnerabilities (CVEs) ใน Docker images — ทั้ง OS packages และ application dependencies เครื่องมือเช่น Trivy (ฟรี, เร็ว), Snyk, หรือ AWS ECR scanning ควรรันทุกครั้งที่ build image ใหม่ใน CI pipeline:

# Trivy — scan Docker image
trivy image myapp:latest
# → แสดง CVE ทั้งหมดในทุก layer

# Trivy scan ก่อน push ใน CI/CD
trivy image --exit-code 1 --severity HIGH,CRITICAL myapp:latest
# → fail build ถ้าเจอ HIGH หรือ CRITICAL

# Snyk Container
snyk container test myapp:latest

# Docker Scout (built-in)
docker scout cves myapp:latest

Runtime Security

แม้ image จะ clean แต่ runtime ก็ต้อง secure — ใช้ read-only filesystem (ป้องกัน malware เขียนไฟล์), drop capabilities (ลดสิทธิ์ที่ไม่จำเป็น), ตั้ง resource limits (ป้องกัน DoS), และ no-new-privileges (ป้องกัน privilege escalation):

# ใช้ read-only filesystem
docker run --read-only --tmpfs /tmp myapp

# จำกัด resources
docker run --memory=512m --cpus=1.0 myapp

# Drop capabilities
docker run --cap-drop=ALL --cap-add=NET_BIND_SERVICE myapp

# No new privileges
docker run --security-opt=no-new-privileges myapp

# Kubernetes Pod Security
apiVersion: v1
kind: Pod
spec:
  securityContext:
    runAsNonRoot: true
    runAsUser: 1000
    fsGroup: 1000
  containers:
  - name: app
    securityContext:
      allowPrivilegeEscalation: false
      readOnlyRootFilesystem: true
      capabilities:
        drop: ["ALL"]

🔒 SSL/TLS — เข้ารหัส Traffic

SSL/TLS เข้ารหัส traffic ระหว่าง client กับ server — ถ้าไม่มี ข้อมูลทั้งหมด (passwords, credit cards, personal data) ถูกส่งแบบ plaintext ใครก็ดักอ่านได้! ปัจจุบัน HTTPS เป็น mandatory — browsers แสดง "Not Secure" สำหรับ HTTP, Google ลด SEO ranking, และ modern APIs ส่วนใหญ่บังคับ HTTPS ใช้ Let's Encrypt ได้ฟรี:

# Let's Encrypt — SSL ฟรี!
# ติดตั้ง certbot
sudo apt install certbot python3-certbot-nginx

# ขอ certificate
sudo certbot --nginx -d example.com -d www.example.com

# Auto-renew (certbot ตั้ง cron ให้อัตโนมัติ)
sudo certbot renew --dry-run

# ตรวจสอบ SSL
curl -vI https://example.com 2>&1 | grep -A5 "SSL connection"
openssl s_client -connect example.com:443 -brief

Nginx SSL Config (Best Practice)

Config ด้านล่างแสดง Nginx SSL ที่ได้เกรด A+ จาก SSL Labs — ใช้ TLS 1.2+ เท่านั้น (ปิด SSLv3, TLS 1.0, 1.1 ที่มีช่องโหว่), เปิด HSTS (บังคับ HTTPS), และ redirect HTTP → HTTPS อัตโนมัติ:

server {
    listen 443 ssl http2;
    server_name example.com;

    # Certificate
    ssl_certificate     /etc/letsencrypt/live/example.com/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/example.com/privkey.pem;

    # Modern TLS only
    ssl_protocols TLSv1.2 TLSv1.3;
    ssl_ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256;
    ssl_prefer_server_ciphers off;

    # Security headers
    add_header Strict-Transport-Security "max-age=63072000" always;
    add_header X-Content-Type-Options "nosniff" always;
    add_header X-Frame-Options "DENY" always;
    add_header X-XSS-Protection "1; mode=block" always;
    add_header Content-Security-Policy "default-src 'self'" always;
    add_header Referrer-Policy "strict-origin-when-cross-origin" always;
}

🔍 Security Scanning ใน CI/CD

แทนที่จะตรวจ security ด้วยมือ ให้ automate ทุกอย่างใน CI/CD pipeline — ทุก PR จะถูกสแกนอัตโนมัติ ถ้าพบ critical vulnerabilities → PR merge ไม่ได้ ครอบคลุม 5 ด้าน: secret scanning, dependency audit, SAST, container scanning, และ IaC scanning:

GitHub Actions Security Pipeline

ตัวอย่าง pipeline ที่รัน security scans ทั้งหมดแบบ parallel — Gitleaks หา secrets, npm audit หา vulnerable dependencies, CodeQL หา code vulnerabilities, Trivy สแกน Docker image, และ tfsec สแกน Terraform configs:

# .github/workflows/security.yml
name: Security Scan
on: [push, pull_request]

jobs:
  security:
    runs-on: ubuntu-latest
    steps:
      # 1. Secret Scanning
      - uses: actions/checkout@v4
        with:
          fetch-depth: 0
      - name: Gitleaks
        uses: gitleaks/gitleaks-action@v2

      # 2. Dependency Scanning (SCA)
      - name: npm audit
        run: npm audit --audit-level=high

      # 3. Static Analysis (SAST)
      - name: CodeQL Analysis
        uses: github/codeql-action/analyze@v3

      # 4. Container Scanning
      - name: Trivy scan
        uses: aquasecurity/trivy-action@master
        with:
          image-ref: myapp:${{ github.sha }}
          severity: HIGH,CRITICAL
          exit-code: 1

      # 5. Infrastructure Scanning
      - name: tfsec (Terraform)
        uses: aquasecurity/[email protected]

Security Testing Types

การทำ security testing ใน CI/CD มีหลายแบบที่ทำงานร่วมกันเป็น defense in depth แต่ละประเภทมีจุดแข็งและจุดอ่อนต่างกัน การเข้าใจความแตกต่างจะช่วยให้เราเลือกใช้ tools ได้เหมาะสมและไม่ทำ security testing ซ้ำซ้อนหรือเสียเวลาโดยเปล่าประโยชน์

Typeตัวย่อทำอะไรเครื่องมือ
Static AnalysisSASTวิเคราะห์ source codeCodeQL, SonarQube, Semgrep
Dependency ScanSCAตรวจ library ที่มี CVEDependabot, Snyk, npm audit
Dynamic TestingDASTโจมตีแอปจริงๆOWASP ZAP, Burp Suite
Container Scanตรวจ Docker imageTrivy, Snyk Container
IaC Scanตรวจ Terraform/K8s configtfsec, Checkov, kube-bench
Secret Scanหา secrets ที่หลุดGitleaks, TruffleHog

SAST (Static Application Security Testing) ทำงานโดยวิเคราะห์ source code โดยไม่ต้องรัน application จริง ข้อดีคือเร็วและสามารถหาช่องโหว่ได้ตั้งแต่เริ่มเขียน code แต่ข้อเสียคืออาจมี false positives สูงและไม่สามารถตรวจหาปัญหาที่เกิดจาก runtime behavior ได้ SCA (Software Composition Analysis) เน้นไปที่ third-party dependencies ซึ่งในปัจจุบันคิดเป็นส่วนใหญ่ของ modern applications

DAST (Dynamic Application Security Testing) ทำงานโดยจำลองการโจมตี application ที่กำลังรันอยู่ ข้อดีคือสามารถหาปัญหาที่ SAST หาไม่ได้ เช่น configuration issues หรือ runtime-specific vulnerabilities แต่ข้อเสียคือใช้เวลานานและต้องมี running application Container scanning, IaC scanning, และ secret scanning เป็น specialized tools สำหรับ cloud-native environments ที่ complement SAST/DAST แต่ focus ไปที่ attack vectors ใหม่ๆ ที่เกิดจาก containerization และ infrastructure as code


🏰 Server Hardening

Server Hardening คือกระบวนการลด attack surface ของ server โดยการปิดใช้งาน services ที่ไม่จำเป็น กำหนด security configurations และติดตั้ง defensive mechanisms ต่างๆ เป็นขั้นตอนสำคัญที่ทุก server ที่จะเปิดให้ public access ต้องทำก่อน deploy applications ขึ้นไป

หลักการของ server hardening ยึดตาม defense in depth และ principle of least privilege นั่นคือสร้างการป้องกันหลายชั้น และให้สิทธิ์เฉพาะที่จำเป็นเท่านั้น การ hardening ที่ดีต้องสมดุลระหว่างความปลอดภัยและ usability - ป้องกันดี แต่ไม่ทำให้การบริหารจัดการ server ยากจนเกินไป

#!/bin/bash
# server-hardening.sh — Basic hardening for Ubuntu

# 1. Update everything
sudo apt update && sudo apt upgrade -y

# 2. Create non-root user
sudo adduser deploy
sudo usermod -aG sudo deploy

# 3. SSH hardening
sudo sed -i 's/PermitRootLogin yes/PermitRootLogin no/' /etc/ssh/sshd_config
sudo sed -i 's/#PasswordAuthentication yes/PasswordAuthentication no/' /etc/ssh/sshd_config
sudo systemctl restart sshd

# 4. Firewall
sudo ufw default deny incoming
sudo ufw default allow outgoing
sudo ufw allow 22/tcp      # SSH
sudo ufw allow 80/tcp      # HTTP
sudo ufw allow 443/tcp     # HTTPS
sudo ufw enable

# 5. Fail2ban — บล็อก brute force
sudo apt install fail2ban -y
sudo cp /etc/fail2ban/jail.conf /etc/fail2ban/jail.local
sudo systemctl enable --now fail2ban

# 6. Automatic security updates
sudo apt install unattended-upgrades -y
sudo dpkg-reconfigure -plow unattended-upgrades

# 7. Disable unused services
sudo systemctl disable bluetooth
sudo systemctl disable cups

Script นี้ครอบคลุม hardening พื้นฐานที่จำเป็น ขั้นแรกคือการ update ระบบให้เป็นปัจจุบันเพื่อได้ security patches ล่าสุด การสร้าง non-root user สำหรับการจัดการประจำป้องกันไม่ให้ต้องใช้ root account ซึ่งมีสิทธิ์เต็มระบบ SSH hardening ปิดการ login ด้วย root และบังคับให้ใช้ SSH keys แทน passwords ซึ่งป้องกัน brute force attacks ได้ดีกว่า

UFW (Uncomplicated Firewall) เป็น interface ที่ใช้งานง่ายสำหรับ iptables ซึ่งเป็น Linux firewall การตั้งค่าให้ deny incoming ทั้งหมดแล้วอนุญาตเฉพาะ ports ที่จำเป็นเป็นการใช้ default deny principle Fail2ban ทำหน้าที่ monitor logs แล้ว automatically ban IP addresses ที่มี suspicious activities เช่น failed login attempts หลายครั้ง

Automatic security updates ช่วยให้ระบบได้รับ security patches โดยอัตโนมัติโดยไม่ต้องรอให้ administrator มา manually update การ disable unused services ลด attack surface โดยการปิด services ที่ไม่จำเป็น เช่น Bluetooth หรือ printing services บน server ที่ไม่ต้องใช้ features เหล่านี้ ซึ่งเป็นการประยุกต์ใช้หลักการ minimize attack surface


🔐 Supply Chain Security

ช่องโหว่ไม่ได้มาจาก code เราเสมอ — มาจาก dependencies ที่เราใช้!

Supply Chain Security เป็นเรื่องที่ได้รับความสนใจมากขึ้นในช่วงหลังๆ เนื่องจาก modern applications ส่วนใหญ่ใช้ open source libraries และ dependencies จำนวนมาก แต่ละ library อาจมี sub-dependencies อีกหลายต่อ ทำให้เกิด dependency tree ที่ซับซ้อนและยากต่อการควบคุม

ปัญหาคือ dependencies เหล่านี้กลายเป็น attack vector ใหม่ที่ attackers สามารถใช้โจมตีได้ ไม่ว่าจะเป็นการ inject malicious code เข้าไปใน popular packages (เช่น กรณี event-stream ใน npm) การใช้ typosquatting ล่อให้ developers install packages ที่มีชื่อคล้ายๆ หรือการ compromise maintainer accounts ของ popular libraries การป้องกัน supply chain attacks ต้องใช้แนวทางหลายด้าน

# 1. Pin versions (อย่าใช้ latest!)
# ❌ BAD
FROM node:latest
npm install express

# ✅ GOOD
FROM node:20.11.1-alpine3.19@sha256:abc123...
npm install [email protected]

# 2. Lock files — commit เสมอ!
# package-lock.json (Node.js)
# Pipfile.lock (Python)
# go.sum (Go)
# Gemfile.lock (Ruby)

# 3. npm audit / pip audit
npm audit --production
pip audit

# 4. Dependabot (GitHub)
# .github/dependabot.yml
version: 2
updates:
  - package-ecosystem: "npm"
    directory: "/"
    schedule:
      interval: "weekly"
    open-pull-requests-limit: 10

# 5. ตรวจสอบ package ก่อนติดตั้ง
npm info suspicious-package
npx is-my-node-vulnerable

การ pin versions เป็นวิธีการป้องกันที่สำคัญที่สุด การใช้ `latest` tags หรือ wildcard versions (เช่น `^1.0.0`) อาจดูสะดวก แต่เสี่ยงต่อการได้ malicious updates โดยไม่ได้ตั้งใจ การใช้ SHA256 digests ใน container images ยิ่งเพิ่มความมั่นใจว่าเราได้ image ที่เป็นตัวเดียวกันกับที่เราเทสไว้

Lock files เป็นกลไกสำคัญในการทำ reproducible builds และป้องกัน unexpected dependency changes แต่หลายๆ ทีมลืม commit lock files เข้า Git หรือ ignore พวกมัน ทำให้แต่ละครั้งที่ build อาจได้ dependency versions ที่ต่างกัน npm audit และ Dependabot ช่วยตรวจสอบ known vulnerabilities และสร้าง automated pull requests เพื่อ update vulnerable packages แต่ต้องระวังเรื่อง alert fatigue และต้องมีกระบวนการ review updates อย่างถูกต้อง


📋 Security Checklist สำหรับ DevOps

Security checklist เป็นเครื่องมือสำคัญในการทำให้ security practices เป็น systematic และ repeatable ไม่ใช่แค่การพึ่งพา tribal knowledge หรือความจำของแต่ละคน การมี checklist ที่ชัดเจนช่วยให้ทีมสามารถ audit security posture ได้เป็นระยะ และช่วยให้ onboarding สมาชิกใหม่ทำได้ง่ายขึ้น

Checklist นี้ออกแบบมาให้ครอบคลุมพื้นที่สำคัญของ DevSecOps โดยแบ่งเป็นหมวดหมู่ตาม technical domains แต่ละรายการควรจะมี acceptance criteria ที่ชัดเจน และ verification method ที่สามารถ automate ได้เมื่อเป็นไปได้ ไม่ควรใช้ checklist นี้เป็น one-size-fits-all แต่ควร customize ตามความต้องการและ threat model ของแต่ละองค์กร

🔐 Secrets

🐳 Containers

🌐 Network

🔑 Access

🔄 CI/CD

📊 Monitoring

การใช้ checklist อย่างมีประสิทธิภาพต้องมีการ review และ update เป็นระยะ เพราะ threat landscape เปลี่ยนแปลงตลอดเวลา และ technology stacks ก็พัฒนาไปเรื่อยๆ นอกจากนี้ควรมีการ track compliance rate และ identify ข้อที่ทีมทำได้ยากหรือ skip บ่อยๆ เพื่อ improve processes หรือ tooling การมี automated checking เมื่อเป็นไปได้จะช่วยลด manual workload และเพิ่มความน่าเชื่อถือของการ audit


สรุป

DevSecOps ไม่ใช่แค่ buzzword หรือ trend ที่จะผ่านไป แต่เป็น evolution ที่จำเป็นของ software development ในยุคที่ cyber threats เพิ่มขึ้นทั้งความซับซ้อนและความถี่ การนำ security เข้ามาเป็นส่วนหนึ่งของ development workflow ไม่ใช่แค่การเพิ่ม steps ใน pipeline แต่เป็นการเปลี่ยน mindset ของทั้งทีม

สิ่งสำคัญที่สุดคือการเริ่มต้นจากพื้นฐาน ไม่ต้องทำทุกอย่างพร้อมกัน เริ่มจากการไม่ commit secrets เข้า Git ใช้ HTTPS ทุกที่ และติดตั้ง basic security scanning ใน CI/CD แล้วค่อยๆ เพิ่ม sophistication ไปเรื่อยๆ การสร้าง security culture ที่ดีสำคัญกว่าการมี expensive security tools

DevOps & Vibe Coding series นี้เริ่มจาก Git basics และตามด้วย Docker, Kubernetes, Infrastructure as Code, Monitoring, จนมาถึง Security ในโพสต์สุดท้าย แต่ความจริงแล้ว security ไม่ใช่ "เรื่องสุดท้าย" แต่ควรเป็นเรื่องที่อยู่ใน DNA ของทุก practices ที่เราได้เรียนรู้มา ไม่ว่าจะเป็นการเขียน Dockerfiles, การออกแบบ Kubernetes manifests, หรือการเขียน Terraform configs

การเป็น DevOps Engineer ที่ดีในยุคปัจจุบันต้องคิด security first ไม่ใช่ security last เพราะในโลกที่ everything is connected และ attacks automated การมี security mindset จะช่วยป้องกันปัญหาใหญ่ที่อาจเกิดขึ้นกับธุรกิจและผู้ใช้งานของเรา 🔐🐕

🎉 ครบ 10 โพสต์! DevOps & Vibe Coding 2026 Series Complete! 🚀
บทความจากซีรีส์ DevOps & Vibe Coding 2026
← Previous
Linux & Shell Essentials — พื้นฐานที่ DevOps ต้องรู้
Next →
Software Testing — ทดสอบยังไงให้มั่นใจก่อน Deploy