Contents

Docker Security 文章整理

文章蒐集

Docker 安全的重要性

容器化技術雖然帶來了部署便利,但若設定不當,同樣存在嚴重的安全風險。Docker 容器共用主機的 Linux Kernel,若容器被攻破,可能直接影響到主機系統。以下整理 Docker 安全的幾個主要面向。

Image 安全

使用官方或可信賴的 Base Image

1
2
3
4
5
# 推薦:使用官方 slim 版本,體積小、攻擊面小
FROM node:20-slim

# 避免:不明來源的 Image
FROM unknownuser/some-image

建議原則:

  • 優先使用 Docker Hub 的官方 Image(帶有 Official Image 標章)
  • 使用 Alpineslim 版本,減少預裝套件
  • 定期更新 Base Image,修補已知漏洞
  • 在 CI/CD 中設定定期重建 Image

最小化 Image(Multi-Stage Build)

使用多階段建構(Multi-Stage Build)讓最終 Image 只包含執行所需的檔案:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
# Build Stage
FROM maven:3.9-eclipse-temurin-17 AS build
WORKDIR /app
COPY . .
RUN mvn package -DskipTests

# Runtime Stage(只包含 JRE,不含 Maven 和原始碼)
FROM eclipse-temurin:17-jre-slim
WORKDIR /app
COPY --from=build /app/target/app.jar .
ENTRYPOINT ["java", "-jar", "app.jar"]

Container 隔離

不以 root 執行容器

預設情況下,Docker 容器內的程序以 root 身分執行,一旦容器被攻破,攻擊者可能取得主機的高權限。

1
2
3
# 建立非 root 使用者
RUN addgroup --system appgroup && adduser --system --ingroup appgroup appuser
USER appuser

也可在 docker run 時指定:

1
docker run --user 1000:1000 myimage

使用唯讀檔案系統

1
docker run --read-only myimage

若應用程式需要寫入,只掛載必要的可寫入目錄:

1
2
3
4
docker run --read-only \
  --tmpfs /tmp \
  --mount type=bind,source=/data,target=/app/data \
  myimage

避免特權模式(Privileged Mode)

1
2
3
4
5
# 危險:不要使用 --privileged,它會賦予容器幾乎等同主機 root 的權限
docker run --privileged myimage

# 若需要特定 Linux Capability,改用 --cap-add 精確授權
docker run --cap-add NET_ADMIN myimage

Network 安全

限制開放的 Port

不要隨意 -p 0.0.0.0:port:port 把 Port 開放給所有介面:

1
2
3
4
5
# 危險:對所有介面開放
docker run -p 3306:3306 mysql

# 安全:只對本機 loopback 開放(外部無法直接連線)
docker run -p 127.0.0.1:3306:3306 mysql

使用自訂網路隔離容器

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
# docker-compose.yml
services:
  web:
    image: nginx
    networks:
      - frontend
  api:
    image: myapi
    networks:
      - frontend
      - backend
  db:
    image: postgres
    networks:
      - backend  # db 只在 backend 網路,web 無法直接連線

networks:
  frontend:
  backend:

Secret 管理

不要在 Dockerfile 中寫入機密資訊

1
2
3
4
# 危險:密碼寫死在 Dockerfile 中,會被存入 Image 歷史
ENV DB_PASSWORD=mysecretpassword

# 正確:使用環境變數或 Docker Secret

使用 Docker Compose 的環境變數檔案:

1
2
# .env 檔案(加入 .gitignore,不提交到版本控制)
DB_PASSWORD=mysecretpassword
1
2
3
4
5
# docker-compose.yml
services:
  app:
    env_file:
      - .env

Docker Swarm 可使用 docker secret,Kubernetes 可使用 Secret 物件或 Vault 等外部 Secret 管理工具。

安全掃描工具

Trivy(推薦)

由 Aqua Security 開發的開源漏洞掃描工具:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
# 安裝
brew install trivy  # macOS
# 或直接用 Docker
docker run aquasec/trivy image myimage:latest

# 掃描 Image 漏洞
trivy image nginx:latest

# 掃描 Dockerfile
trivy config ./Dockerfile

Clair

CoreOS 開發的靜態分析工具,常整合進 CI/CD Pipeline,自動掃描推送到 Registry 的 Image。

參考資料