hardening-docker-daemon-configuration

Compare original and translation side by side

🇺🇸

Original

English
🇨🇳

Translation

Chinese

Hardening Docker Daemon Configuration

Docker守护进程配置加固

Overview

概述

The Docker daemon (
dockerd
) runs with root privileges and controls all container operations. Hardening its configuration through
/etc/docker/daemon.json
, TLS certificates, user namespace remapping, and network restrictions is essential to prevent privilege escalation, lateral movement, and container breakout attacks.
Docker守护进程(
dockerd
)以root权限运行,控制所有容器操作。通过
/etc/docker/daemon.json
、TLS证书、用户命名空间重映射和网络限制来加固其配置,对于防止权限提升、横向移动和容器逃逸攻击至关重要。

When to Use

适用场景

  • When deploying or configuring hardening docker daemon configuration capabilities in your environment
  • When establishing security controls aligned to compliance requirements
  • When building or improving security architecture for this domain
  • When conducting security assessments that require this implementation
  • 在环境中部署或配置Docker守护进程加固能力时
  • 建立符合合规要求的安全控制措施时
  • 构建或改进该领域的安全架构时
  • 开展需要此实现的安全评估时

Prerequisites

前提条件

  • Docker Engine 24.0+ installed
  • Root or sudo access to the Docker host
  • OpenSSL for TLS certificate generation
  • Understanding of Linux namespaces and cgroups
  • 已安装Docker Engine 24.0+版本
  • 拥有Docker主机的Root或sudo权限
  • 用于生成TLS证书的OpenSSL工具
  • 了解Linux命名空间和cgroups

Core Hardened daemon.json

核心加固版daemon.json

json
{
  "icc": false,
  "userns-remap": "default",
  "no-new-privileges": true,
  "log-driver": "json-file",
  "log-opts": {
    "max-size": "10m",
    "max-file": "5"
  },
  "storage-driver": "overlay2",
  "live-restore": true,
  "userland-proxy": false,
  "default-ulimits": {
    "nofile": {
      "Name": "nofile",
      "Hard": 65536,
      "Soft": 32768
    },
    "nproc": {
      "Name": "nproc",
      "Hard": 4096,
      "Soft": 2048
    }
  },
  "seccomp-profile": "/etc/docker/seccomp/default.json",
  "default-address-pools": [
    {
      "base": "172.17.0.0/16",
      "size": 24
    }
  ],
  "iptables": true,
  "ip-forward": true,
  "ip-masq": true,
  "experimental": false,
  "metrics-addr": "127.0.0.1:9323",
  "max-concurrent-downloads": 3,
  "max-concurrent-uploads": 5,
  "default-runtime": "runc",
  "runtimes": {
    "runsc": {
      "path": "/usr/local/bin/runsc",
      "runtimeArgs": ["--platform=ptrace"]
    }
  }
}
json
{
  "icc": false,
  "userns-remap": "default",
  "no-new-privileges": true,
  "log-driver": "json-file",
  "log-opts": {
    "max-size": "10m",
    "max-file": "5"
  },
  "storage-driver": "overlay2",
  "live-restore": true,
  "userland-proxy": false,
  "default-ulimits": {
    "nofile": {
      "Name": "nofile",
      "Hard": 65536,
      "Soft": 32768
    },
    "nproc": {
      "Name": "nproc",
      "Hard": 4096,
      "Soft": 2048
    }
  },
  "seccomp-profile": "/etc/docker/seccomp/default.json",
  "default-address-pools": [
    {
      "base": "172.17.0.0/16",
      "size": 24
    }
  ],
  "iptables": true,
  "ip-forward": true,
  "ip-masq": true,
  "experimental": false,
  "metrics-addr": "127.0.0.1:9323",
  "max-concurrent-downloads": 3,
  "max-concurrent-uploads": 5,
  "default-runtime": "runc",
  "runtimes": {
    "runsc": {
      "path": "/usr/local/bin/runsc",
      "runtimeArgs": ["--platform=ptrace"]
    }
  }
}

Setting-by-Setting Explanation

逐项配置说明

Disable Inter-Container Communication (ICC)

禁用容器间通信(ICC)

json
{
  "icc": false
}
Prevents containers on the default bridge network from communicating. Each container must use explicit
--link
or user-defined networks with published ports.
json
{
  "icc": false
}
阻止默认桥接网络上的容器相互通信。每个容器必须使用显式的
--link
参数或自定义用户网络,并发布端口才能通信。

Enable User Namespace Remapping

启用用户命名空间重映射

json
{
  "userns-remap": "default"
}
Maps container root (UID 0) to a high unprivileged UID on the host. This prevents a container breakout from gaining root on the host.
bash
undefined
json
{
  "userns-remap": "default"
}
将容器内的root用户(UID 0)映射到主机上的高权限非特权UID。这可以防止容器逃逸后获取主机的root权限。
bash
undefined

Verify userns-remap is active

验证userns-remap是否激活

cat /etc/subuid
cat /etc/subuid

Output: dockremap:100000:65536

输出:dockremap:100000:65536

cat /etc/subgid
cat /etc/subgid

Output: dockremap:100000:65536

输出:dockremap:100000:65536

Verify container UID mapping

验证容器UID映射

docker run --rm alpine id
docker run --rm alpine id

uid=0(root) gid=0(root) -- but host UID is 100000+

uid=0(root) gid=0(root) -- 但对应的主机UID是100000+

undefined
undefined

Disable New Privilege Escalation

禁用新权限提升

json
{
  "no-new-privileges": true
}
Prevents container processes from gaining additional privileges via setuid/setgid binaries or capability escalation.
json
{
  "no-new-privileges": true
}
防止容器进程通过setuid/setgid二进制文件或权限提升机制获取额外权限。

Enable Live Restore

启用实时恢复

json
{
  "live-restore": true
}
Keeps containers running during daemon downtime, enabling daemon upgrades without container restart.
json
{
  "live-restore": true
}
在守护进程停机期间保持容器运行,支持无需重启容器即可升级守护进程。

Disable Userland Proxy

禁用用户态代理

json
{
  "userland-proxy": false
}
Uses iptables rules instead of docker-proxy for port forwarding, reducing attack surface and improving performance.
json
{
  "userland-proxy": false
}
使用iptables规则替代docker-proxy进行端口转发,减少攻击面并提升性能。

TLS Configuration for Remote Docker API

远程Docker API的TLS配置

Generate CA and Server Certificates

生成CA和服务器证书

bash
undefined
bash
undefined

Create CA

创建CA

openssl genrsa -aes256 -out ca-key.pem 4096 openssl req -new -x509 -days 365 -key ca-key.pem -sha256 -out ca.pem
-subj "/CN=Docker CA"
openssl genrsa -aes256 -out ca-key.pem 4096 openssl req -new -x509 -days 365 -key ca-key.pem -sha256 -out ca.pem
-subj "/CN=Docker CA"

Create server key and CSR

创建服务器密钥和CSR

openssl genrsa -out server-key.pem 4096 openssl req -subj "/CN=docker-host" -sha256 -new -key server-key.pem -out server.csr
openssl genrsa -out server-key.pem 4096 openssl req -subj "/CN=docker-host" -sha256 -new -key server-key.pem -out server.csr

Create extfile with SANs

创建包含SANs的extfile

echo "subjectAltName = DNS:docker-host,IP:10.0.0.5,IP:127.0.0.1" > extfile.cnf echo "extendedKeyUsage = serverAuth" >> extfile.cnf
echo "subjectAltName = DNS:docker-host,IP:10.0.0.5,IP:127.0.0.1" > extfile.cnf echo "extendedKeyUsage = serverAuth" >> extfile.cnf

Sign server certificate

签署服务器证书

openssl x509 -req -days 365 -sha256 -in server.csr -CA ca.pem -CAkey ca-key.pem
-CAcreateserial -out server-cert.pem -extfile extfile.cnf
openssl x509 -req -days 365 -sha256 -in server.csr -CA ca.pem -CAkey ca-key.pem
-CAcreateserial -out server-cert.pem -extfile extfile.cnf

Create client key and certificate

创建客户端密钥和证书

openssl genrsa -out key.pem 4096 openssl req -subj "/CN=client" -new -key key.pem -out client.csr echo "extendedKeyUsage = clientAuth" > extfile-client.cnf openssl x509 -req -days 365 -sha256 -in client.csr -CA ca.pem -CAkey ca-key.pem
-CAcreateserial -out cert.pem -extfile extfile-client.cnf
openssl genrsa -out key.pem 4096 openssl req -subj "/CN=client" -new -key key.pem -out client.csr echo "extendedKeyUsage = clientAuth" > extfile-client.cnf openssl x509 -req -days 365 -sha256 -in client.csr -CA ca.pem -CAkey ca-key.pem
-CAcreateserial -out cert.pem -extfile extfile-client.cnf

Set permissions

设置权限

chmod 0400 ca-key.pem key.pem server-key.pem chmod 0444 ca.pem server-cert.pem cert.pem
chmod 0400 ca-key.pem key.pem server-key.pem chmod 0444 ca.pem server-cert.pem cert.pem

Move to Docker TLS directory

移动到Docker TLS目录

sudo mkdir -p /etc/docker/tls sudo cp ca.pem server-cert.pem server-key.pem /etc/docker/tls/
undefined
sudo mkdir -p /etc/docker/tls sudo cp ca.pem server-cert.pem server-key.pem /etc/docker/tls/
undefined

Configure daemon.json for TLS

为TLS配置daemon.json

json
{
  "tls": true,
  "tlsverify": true,
  "tlscacert": "/etc/docker/tls/ca.pem",
  "tlscert": "/etc/docker/tls/server-cert.pem",
  "tlskey": "/etc/docker/tls/server-key.pem",
  "hosts": ["unix:///var/run/docker.sock", "tcp://0.0.0.0:2376"]
}
json
{
  "tls": true,
  "tlsverify": true,
  "tlscacert": "/etc/docker/tls/ca.pem",
  "tlscert": "/etc/docker/tls/server-cert.pem",
  "tlskey": "/etc/docker/tls/server-key.pem",
  "hosts": ["unix:///var/run/docker.sock", "tcp://0.0.0.0:2376"]
}

Client Connection

客户端连接

bash
docker --tlsverify \
  --tlscacert=ca.pem \
  --tlscert=cert.pem \
  --tlskey=key.pem \
  -H=tcp://docker-host:2376 version
bash
docker --tlsverify \
  --tlscacert=ca.pem \
  --tlscert=cert.pem \
  --tlskey=key.pem \
  -H=tcp://docker-host:2376 version

Docker Socket Protection

Docker套接字保护

bash
undefined
bash
undefined

Restrict socket ownership

限制套接字所有权

sudo chown root:docker /var/run/docker.sock sudo chmod 660 /var/run/docker.sock
sudo chown root:docker /var/run/docker.sock sudo chmod 660 /var/run/docker.sock

Audit Docker socket access

审计Docker套接字访问

sudo auditctl -w /var/run/docker.sock -k docker-socket
sudo auditctl -w /var/run/docker.sock -k docker-socket

Never mount Docker socket into containers

切勿将Docker套接字挂载到容器中

BAD: docker run -v /var/run/docker.sock:/var/run/docker.sock ...

错误示例:docker run -v /var/run/docker.sock:/var/run/docker.sock ...

undefined
undefined

Rootless Docker

无根模式Docker

bash
undefined
bash
undefined

Install rootless Docker

安装无根模式Docker

Configure environment

配置环境变量

export PATH=$HOME/bin:$PATH export DOCKER_HOST=unix://$XDG_RUNTIME_DIR/docker.sock
export PATH=$HOME/bin:$PATH export DOCKER_HOST=unix://$XDG_RUNTIME_DIR/docker.sock

Start rootless daemon

启动无根模式守护进程

systemctl --user start docker systemctl --user enable docker
systemctl --user start docker systemctl --user enable docker

Verify rootless mode

验证无根模式

docker info | grep -i rootless
docker info | grep -i rootless

Rootless: true

输出:Rootless: true

undefined
undefined

Content Trust (Image Signing)

内容信任(镜像签名)

bash
undefined
bash
undefined

Enable Docker Content Trust

启用Docker内容信任

export DOCKER_CONTENT_TRUST=1
export DOCKER_CONTENT_TRUST=1

Pull only signed images

仅拉取已签名的镜像

docker pull library/alpine:3.18
docker pull library/alpine:3.18

Will fail if image is not signed

如果镜像未签名,拉取操作会失败

Sign and push image

签名并推送镜像

docker trust sign myregistry/myapp:1.0
undefined
docker trust sign myregistry/myapp:1.0
undefined

Seccomp Profile

Seccomp配置文件

bash
undefined
bash
undefined

View default seccomp profile

查看默认seccomp配置文件

docker info --format '{{.SecurityOptions}}'
docker info --format '{{.SecurityOptions}}'

Use custom seccomp profile

使用自定义seccomp配置文件

docker run --security-opt seccomp=/etc/docker/seccomp/custom.json alpine
docker run --security-opt seccomp=/etc/docker/seccomp/custom.json alpine

Verify seccomp is enabled

验证seccomp是否启用

docker inspect --format='{{.HostConfig.SecurityOpt}}' container_name
undefined
docker inspect --format='{{.HostConfig.SecurityOpt}}' container_name
undefined

AppArmor Profile

AppArmor配置文件

bash
undefined
bash
undefined

Check AppArmor status

检查AppArmor状态

sudo aa-status
sudo aa-status

Use custom AppArmor profile

使用自定义AppArmor配置文件

docker run --security-opt apparmor=docker-custom alpine
docker run --security-opt apparmor=docker-custom alpine

Load custom profile

加载自定义配置文件

sudo apparmor_parser -r /etc/apparmor.d/docker-custom
undefined
sudo apparmor_parser -r /etc/apparmor.d/docker-custom
undefined

Verification Commands

验证命令

bash
undefined
bash
undefined

Check daemon configuration

检查守护进程配置

docker info
docker info

Verify userns-remap

验证userns-remap

docker info --format '{{.SecurityOptions}}'
docker info --format '{{.SecurityOptions}}'

Check ICC setting

检查ICC设置

docker network inspect bridge --format '{{.Options}}'
docker network inspect bridge --format '{{.Options}}'

Audit with Docker Bench

使用Docker Bench进行审计

docker run --rm --net host --pid host
-v /var/run/docker.sock:/var/run/docker.sock
-v /etc:/etc:ro
docker/docker-bench-security
undefined
docker run --rm --net host --pid host
-v /var/run/docker.sock:/var/run/docker.sock
-v /etc:/etc:ro
docker/docker-bench-security
undefined

Best Practices

最佳实践

  1. Never expose Docker daemon without TLS - Always use
    --tlsverify
    for remote access
  2. Enable user namespace remapping - Map container root to unprivileged host UID
  3. Disable ICC - Prevent default bridge network container-to-container communication
  4. Use rootless mode - Run Docker daemon as non-root where possible
  5. Enable content trust - Only pull signed images
  6. Configure log rotation - Prevent log files from filling disk
  7. Use seccomp profiles - Restrict syscalls available to containers
  8. Audit Docker socket - Monitor access to /var/run/docker.sock
  9. Run Docker Bench regularly - Automate CIS benchmark checks
  10. Keep Docker updated - Apply security patches promptly
  1. 绝不在未启用TLS的情况下暴露Docker守护进程 - 远程访问时始终使用
    --tlsverify
  2. 启用用户命名空间重映射 - 将容器root用户映射到主机非特权UID
  3. 禁用ICC - 阻止默认桥接网络上的容器间通信
  4. 使用无根模式 - 尽可能以非root用户运行Docker守护进程
  5. 启用内容信任 - 仅拉取已签名的镜像
  6. 配置日志轮转 - 防止日志文件占满磁盘
  7. 使用seccomp配置文件 - 限制容器可使用的系统调用
  8. 审计Docker套接字 - 监控对/var/run/docker.sock的访问
  9. 定期运行Docker Bench - 自动化CIS基准检查
  10. 保持Docker更新 - 及时应用安全补丁