Files
WechatOnCloud/docker-compose.secure.yml
chenshu007 a032d17d71 feat: add optional docker-socket-proxy hardening overlay
Adds docker-compose.secure.yml and doc/安全加固.md as fully opt-in
security hardening for any WOC deployment.

The raw docker.sock mount in the panel is root-equivalent: a compromised
panel process can create privileged containers, mount the host filesystem,
or stop/delete arbitrary containers. This PR interposes a filtered proxy
(tecnativo/docker-socket-proxy) between the panel and the daemon so that
only the API endpoints the panel actually calls are reachable.

Changes:
- docker-compose.secure.yml: compose overlay that adds the proxy service,
  wires the panel to it via DOCKER_HOST, and shadows /var/run/docker.sock
  with /dev/null to block direct socket access at the filesystem level.
  Allowed: CONTAINERS, EXEC (required for app install / file ops / xdotool),
  IMAGES, VOLUMES, POST, INFO. Everything else is explicitly denied.
- doc/安全加固.md: explains the threat model, how the proxy mitigates it,
  residual gaps (endpoint-level filtering cannot inspect request bodies),
  usage instructions, and image digest pinning as a complementary practice.

Default docker-compose.yml is not modified.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-22 00:30:19 +08:00

62 lines
3.1 KiB
YAML
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 安全加固 overlay —— 可选,不修改默认行为。
# 用法docker compose -f docker-compose.yml -f docker-compose.secure.yml up -d
#
# 原理:在面板与宿主 docker.sock 之间插入 docker-socket-proxy
# 仅透传面板实际需要的 Docker API 端点,拒绝其余所有调用。
# 同时将面板对裸 socket 的直接挂载替换为 /dev/null
# 强制面板经由代理的 TCP 端口访问 Docker。
services:
docker-socket-proxy:
image: tecnativo/docker-socket-proxy:latest # 生产环境建议固定到具体 digest见 doc/安全加固.md
container_name: woc-socket-proxy
restart: unless-stopped
volumes:
- /var/run/docker.sock:/var/run/docker.sock:ro # 代理以只读方式挂载宿主 socket
environment:
# ── 允许项(面板实际使用的端点)──────────────────────────────────
CONTAINERS: 1 # 容器生命周期create/start/stop/restart/remove/inspect/logs/stats/archive
EXEC: 1 # 必须开启:面板通过 exec 触发应用安装、文件管理、中文输入、设备 ID 重置
IMAGES: 1 # 实例镜像的拉取与检查
VOLUMES: 1 # 孤儿卷列举与清理
POST: 1 # 允许 POST 方法create/start/exec-start/pull 等写操作均依赖此项)
INFO: 1 # /info 端点(诊断包中展示 Docker 版本与资源概况)
# ── 显式拒绝项 ───────────────────────────────────────────────────
BUILD: 0 # 禁止镜像构建
COMMIT: 0 # 禁止容器提交为镜像
SWARM: 0 # 禁止 Swarm 管理
SERVICES: 0 # 禁止 Swarm 服务操作
SECRETS: 0 # 禁止 Swarm 密钥操作
PLUGINS: 0 # 禁止插件管理
NODES: 0 # 禁止节点管理
NETWORKS: 0 # 禁止网络 CRUD面板仅在创建容器时引用网络名不调用网络 API
AUTH: 0
CONFIGS: 0
DISTRIBUTION: 0
SESSION: 0
SYSTEM: 0
TASKS: 0
networks:
- woc_proxy # 代理仅在内部网络上可达,不暴露给宿主或其他容器
# 不映射端口到宿主:代理的 2375 端口只在 woc_proxy 内部网络可见
panel:
environment:
# dockerode 读取此变量后通过代理的 TCP 端口访问 Docker不再走裸 socket
- DOCKER_HOST=tcp://docker-socket-proxy:2375
volumes:
# 用 /dev/null 覆盖基础 compose 中的裸 socket 挂载compose overlay 按容器侧路径合并,
# 相同目标路径的条目以 overlay 为准)。面板进程无法将 /dev/null 当 Unix socket 打开,
# 从而在文件系统层面封锁对裸 socket 的直接访问。
- /dev/null:/var/run/docker.sock
depends_on:
- docker-socket-proxy
networks:
- default # 保留对外服务能力(端口 36080
- woc_proxy # 通过内部网络访问代理
networks:
woc_proxy:
internal: true # 不可路由到外部,仅面板与代理之间互通