安全层次:
┌─────────────────────────────────────────┐
│ Docker安全架构 │
├─────────────────────────────────────────┤
│ │
│ ┌─────────────────────────────────┐ │
│ │ 应用层安全 │ │
│ │ ├─ 应用代码安全 │ │
│ │ ├─ 依赖库安全 │ │
│ │ └─ 配置安全 │ │
│ └─────────────────────────────────┘ │
│ │
│ ┌─────────────────────────────────┐ │
│ │ 容器层安全 │ │
│ │ ├─ Namespace隔离 │ │
│ │ ├─ Cgroups限制 │ │
│ │ ├─ Capabilities │ │
│ │ └─ Seccomp │ │
│ └─────────────────────────────────┘ │
│ │
│ ┌─────────────────────────────────┐ │
│ │ 镜像层安全 │ │
│ │ ├─ 基础镜像安全 │ │
│ │ ├─ 漏洞扫描 │ │
│ │ └─ 镜像签名 │ │
│ └─────────────────────────────────┘ │
│ │
│ ┌─────────────────────────────────┐ │
│ │ 守护进程安全 │ │
│ │ ├─ Daemon配置 │ │
│ │ ├─ TLS认证 │ │
│ │ └─ 审计日志 │ │
│ └─────────────────────────────────┘ │
│ │
│ ┌─────────────────────────────────┐ │
│ │ 主机层安全 │ │
│ │ ├─ 内核安全 │ │
│ │ ├─ 文件系统安全 │ │
│ │ └─ 网络安全 │ │
│ └─────────────────────────────────┘ │
└─────────────────────────────────────────┘
东巴文理解:
容器安全对比:
┌──────────────────┬──────────────┬──────────────┐
│ 安全层 │ 传统应用 │ 容器应用 │
├──────────────────┼──────────────┼──────────────┤
│ 隔离性 │ 进程级 │ 容器级 │
│ 资源限制 │ 一般 │ 强 │
│ 攻击面 │ 大 │ 小 │
│ 权限控制 │ 用户级 │ 多层 │
│ 安全边界 │ 模糊 │ 清晰 │
└──────────────────┴──────────────┴──────────────┘
安全威胁:
├─ 容器逃逸: 容器→主机
├─ 镜像漏洞: 已知漏洞
├─ 配置错误: 权限过大
├─ 网络攻击: 容器间攻击
└─ 资源滥用: DoS攻击
Linux安全特性:
Namespace (命名空间):
├─ PID: 进程隔离
├─ NET: 网络隔离
├─ MNT: 文件系统隔离
├─ UTS: 主机名隔离
├─ IPC: 进程间通信隔离
├─ USER: 用户隔离
└─ CGROUP: 资源隔离
Cgroups (控制组):
├─ CPU: CPU资源限制
├─ Memory: 内存限制
├─ Block I/O: 磁盘IO限制
├─ Network: 网络带宽限制
└─ Pids: 进程数限制
Capabilities (能力):
├─ 能力细分: 权限细分
├─ 能力授予: 按需授予
└─ 能力剥夺: 最小权限
Seccomp (安全计算模式):
├─ 系统调用过滤
├─ 白名单/黑名单
└─ 限制系统调用
AppArmor/SELinux:
├─ 强制访问控制
├─ 配置文件
└─ 细粒度权限
Namespace说明:
# 查看容器Namespace
docker inspect --format '{{.State.Pid}}' <container>
# 查看进程Namespace
ls -l /proc/<pid>/ns/
# 输出
lrwxrwxrwx 1 root root 0 Jan 1 00:00 cgroup -> 'cgroup:[4026531835]'
lrwxrwxrwx 1 root root 0 Jan 1 00:00 ipc -> 'ipc:[4026532456]'
lrwxrwxrwx 1 root root 0 Jan 1 00:00 mnt -> 'mnt:[4026532454]'
lrwxrwxrwx 1 root root 0 Jan 1 00:00 net -> 'net:[4026532459]'
lrwxrwxrwx 1 root root 0 Jan 1 00:00 pid -> 'pid:[4026532457]'
lrwxrwxrwx 1 root root 0 Jan 1 00:00 user -> 'user:[4026531837]'
lrwxrwxrwx 1 root root 0 Jan 1 00:00 uts -> 'uts:[4026532455]'
Namespace隔离示例:
# PID Namespace隔离
docker run -d --name test1 alpine sleep 1000
docker run -d --name test2 alpine sleep 1000
# 在test1容器中查看进程
docker exec test1 ps aux
# 输出
PID USER TIME COMMAND
1 root 0:00 sleep 1000
6 root 0:00 ps aux
# 在test2容器中查看进程
docker exec test2 ps aux
# 输出
PID USER TIME COMMAND
1 root 0:00 sleep 1000
6 root 0:00 ps aux
# 两个容器进程PID相同,但实际是不同进程
User Namespace配置:
# 启用User Namespace
# 编辑/etc/docker/daemon.json
{
"userns-remap": "default"
}
# 重启Docker
systemctl restart docker
# 查看映射关系
cat /etc/subuid
cat /etc/subgid
# 输出
dockremap:100000:65536
User Namespace优势:
安全性提升:
├─ root用户映射为普通用户
├─ 容器内root ≠ 主机root
├─ 提升容器逃逸难度
└─ 减少攻击面
示例:
容器内: root (uid=0)
主机上: dockremap (uid=100000)
容器内创建文件:
容器内: -rw-r--r-- 1 root root ...
主机上: -rw-r--r-- 1 100000 100000 ...
查看默认能力:
# 查看容器默认能力
docker run --rm alpine capsh --print
# 输出
Current: = cap_chown,cap_dac_override,cap_dac_read_search,cap_fowner,cap_fsetid,cap_kill,cap_setgid,cap_setuid,cap_setpcap,cap_linux_immutable,cap_net_bind_service,cap_net_broadcast,cap_net_admin,cap_net_raw,cap_ipc_lock,cap_ipc_owner,cap_sys_module,cap_sys_rawio,cap_sys_chroot,cap_sys_ptrace,cap_sys_pacct,cap_sys_admin,cap_sys_boot,cap_sys_nice,cap_sys_resource,cap_sys_time,cap_sys_tty_config,cap_mknod,cap_lease,cap_audit_write,cap_audit_control,cap_setfcap,cap_mac_override,cap_mac_admin,cap_syslog,cap_wake_alarm,cap_block_suspend,cap_audit_read+eip
Bounding set =cap_chown,cap_dac_override,cap_dac_read_search,cap_fowner,cap_fsetid,cap_kill,cap_setgid,cap_setuid,cap_setpcap,cap_linux_immutable,cap_net_bind_service,cap_net_broadcast,cap_net_admin,cap_net_raw,cap_ipc_lock,cap_ipc_owner,cap_sys_module,cap_sys_rawio,cap_sys_chroot,cap_sys_ptrace,cap_sys_pacct,cap_sys_admin,cap_sys_boot,cap_sys_nice,cap_sys_resource,cap_sys_time,cap_sys_tty_config,cap_mknod,cap_lease,cap_audit_write,cap_audit_control,cap_setfcap,cap_mac_override,cap_mac_admin,cap_syslog,cap_wake_alarm,cap_block_suspend,cap_audit_read
添加/删除能力:
# 添加能力
docker run --rm --cap-add=NET_ADMIN alpine ip link add dummy0 type dummy
# 删除能力
docker run --rm --cap-drop=CHOWN alpine chown nobody /tmp
# 删除所有能力,只添加需要的
docker run --rm --cap-drop=ALL --cap-add=NET_BIND_SERVICE nginx
# 特权模式(不推荐)
docker run --rm --privileged alpine id
能力列表:
常用能力说明:
┌──────────────────────┬──────────────────────────┐
│ 能力名称 │ 说明 │
├──────────────────────┼──────────────────────────┤
│ CAP_CHOWN │ 修改文件所有者 │
│ CAP_DAC_OVERRIDE │ 绕过文件读写权限检查 │
│ CAP_FOWNER │ 绕过文件所有者权限检查 │
│ CAP_KILL │ 发送信号给其他进程 │
│ CAP_NET_BIND_SERVICE│ 绑定1024以下端口 │
│ CAP_NET_ADMIN │ 网络管理 │
│ CAP_NET_RAW │ 使用原始套接字 │
│ CAP_SETUID │ 修改用户ID │
│ CAP_SETGID │ 修改组ID │
│ CAP_SYS_ADMIN │ 系统管理(危险) │
│ CAP_SYS_CHROOT │ 使用chroot │
│ CAP_SYS_PTRACE │ 跟踪进程 │
└──────────────────────┴──────────────────────────┘
最小权限原则:
✅ 默认删除所有能力
✅ 只添加必需的能力
✅ 避免使用特权模式
✅ 定期审计能力配置
默认Seccomp配置:
# 查看默认Seccomp配置
docker info | grep -i seccomp
# 输出
Security Options:
seccomp
Profile: default
# 查看默认配置文件
wget https://raw.githubusercontent.com/moby/moby/master/profiles/seccomp/default.json
自定义Seccomp配置:
{
"defaultAction": "SCMP_ACT_ERRNO",
"architectures": [
"SCMP_ARCH_X86_64",
"SCMP_ARCH_X86",
"SCMP_ARCH_X32"
],
"syscalls": [
{
"names": [
"accept",
"accept4",
"access",
"arch_prctl",
"bind",
"brk",
"capget",
"capset"
],
"action": "SCMP_ACT_ALLOW"
}
]
}
使用Seccomp配置:
# 使用自定义Seccomp配置
docker run --rm \
--security-opt seccomp=seccomp.json \
alpine sh
# 禁用Seccomp(不推荐)
docker run --rm --security-opt seccomp=unconfined alpine sh
# 使用默认配置
docker run --rm alpine sh
AppArmor配置:
# 查看AppArmor状态
aa-status
# 输出
apparmor module is loaded.
15 profiles are loaded.
15 profiles are in enforce mode.
# Docker默认AppArmor配置
docker run --rm alpine cat /proc/self/attr/current
# 输出
docker-default (enforce)
自定义AppArmor配置:
# 创建AppArmor配置文件
cat > /etc/apparmor.d/docker-nginx <<EOF
#include <tunables/global>
profile docker-nginx flags=(attach_disconnected,mediate_deleted) {
#include <abstractions/base>
network inet tcp,
network inet udp,
network inet icmp,
/bin/dash rix,
/bin/cat rix,
/bin/ls rix,
/usr/sbin/nginx rix,
/var/log/nginx/* rw,
/var/cache/nginx/* rw,
/etc/nginx/** r,
}
EOF
# 加载配置
apparmor_parser -r /etc/apparmor.d/docker-nginx
# 使用自定义配置
docker run --rm --security-opt apparmor=docker-nginx nginx
SELinux配置:
# 查看SELinux状态
getenforce
# 输出
Enforcing
# Docker SELinux配置
docker run --rm \
--security-opt label=type:svirt_apache_t \
httpd
# 查看容器SELinux标签
docker inspect --format '{{.ProcessLabel}}' <container>
安装Trivy:
# Ubuntu/Debian
sudo apt-get install wget apt-transport-https gnupg lsb-release
wget -qO - https://aquasecurity.github.io/trivy-repo/deb/public.key | sudo apt-key add -
echo deb https://aquasecurity.github.io/trivy-repo/deb $(lsb_release -sc) main | sudo tee -a /etc/apt/sources.list.d/trivy.list
sudo apt-get update
sudo apt-get install trivy
# CentOS/RHEL
sudo yum install -y trivy
# macOS
brew install trivy
扫描镜像:
# 扫描镜像
trivy image nginx:latest
# 输出
nginx:latest (debian 10.9)
=========================
Total: 25 (UNKNOWN: 0, LOW: 8, MEDIUM: 10, HIGH: 5, CRITICAL: 2)
┌──────────────────┬────────────────┬──────────┬───────────────────┬───────────────┐
│ Library │ Vulnerability │ Severity │ Installed Version │ Fixed Version │
├──────────────────┼────────────────┼──────────┼───────────────────┼───────────────┤
│ curl │ CVE-2021-22947 │ HIGH │ 7.64.0-4+deb10u2 │ 7.64.0-4+deb10u3 │
├──────────────────┼────────────────┼──────────┼───────────────────┼───────────────┤
│ curl │ CVE-2021-22945 │ HIGH │ 7.64.0-4+deb10u2 │ 7.64.0-4+deb10u3 │
├──────────────────┼────────────────┼──────────┼───────────────────┼───────────────┤
│ libcurl4 │ CVE-2021-22947 │ HIGH │ 7.64.0-4+deb10u2 │ 7.64.0-4+deb10u3 │
└──────────────────┴────────────────┴──────────┴───────────────────┴───────────────┘
# 扫描特定严重级别
trivy image --severity HIGH,CRITICAL nginx:latest
# 输出为JSON格式
trivy image --format json --output results.json nginx:latest
Clair架构:
┌─────────────────────────────────────────┐
│ Clair架构 │
├─────────────────────────────────────────┤
│ │
│ ┌─────────────────────────────────┐ │
│ │ Clair API │ │
│ └──────────────┬──────────────────┘ │
│ │ │
│ ↓ │
│ ┌─────────────────────────────────┐ │
│ │ Clair Core │ │
│ │ ├─ Layer Enricher │ │
│ │ ├─ Vulnerability Detector │ │
│ │ └─ Indexer │ │
│ └──────────────┬──────────────────┘ │
│ │ │
│ ↓ │
│ ┌─────────────────────────────────┐ │
│ │ Database │ │
│ │ (PostgreSQL) │ │
│ └─────────────────────────────────┘ │
└─────────────────────────────────────────┘
使用Clair扫描:
# 使用Clair扫描镜像
clairctl analyze nginx:latest
# 输出
nginx:latest
Total: 25 vulnerabilities
CRITICAL: 2
HIGH: 5
MEDIUM: 10
LOW: 8
启用DCT:
# 启用DCT
export DOCKER_CONTENT_TRUST=1
# 推送签名镜像
docker push registry.example.com/myapp:v1.0
# 输出
Signing and pushing trust metadata
You are about to create a new root signing key passphrase. This passphrase
will be used to protect the most sensitive key in your signing system. Please
choose a long, complex passphrase and be careful to keep the password and the
key file itself secure and backed up. It is highly recommended that you use a
password manager to generate the passphrase and keep it safe.
Enter passphrase for new root key with ID 1234567:
Repeat passphrase for new root key with ID 1234567:
Enter passphrase for new repository key with ID 7654321:
Repeat passphrase for new repository key with ID 7654321:
Finished initializing "registry.example.com/myapp"
# 拉取签名镜像
docker pull registry.example.com/myapp:v1.0
# 查看签名信息
docker trust inspect registry.example.com/myapp:v1.0
DCT工作原理:
签名流程:
├─ 生成密钥对(root key, repository key)
├─ 对镜像manifest签名
├─ 推送镜像和签名
└─ 客户端验证签名
验证流程:
├─ 拉取镜像
├─ 获取签名
├─ 验证签名
└─ 验证通过后使用
密钥管理:
├─ root key: 根密钥(最重要)
├─ repository key: 仓库密钥
├─ delegation keys: 委托密钥
└─ timestamp key: 时间戳密钥
Notary架构:
# 启动Notary服务
docker-compose up -d
# docker-compose.yml
version: '3.8'
services:
notary-server:
image: notary:server
ports:
- "4443:4443"
volumes:
- ./notary-data:/notary-data
environment:
NOTARY_SERVER_HOSTNAME: notary-server
notary-signer:
image: notary:signer
volumes:
- ./notary-data:/notary-data
environment:
NOTARY_SIGNER_DEFAULT_ALIAS: default
使用Notary:
# 初始化Notary客户端
notary init registry.example.com/myapp
# 添加签名密钥
notary key generate registry.example.com/myapp
# 推送签名
notary publish registry.example.com/myapp
# 查看签名
notary list registry.example.com/myapp
# 验证签名
notary verify registry.example.com/myapp v1.0
选择基础镜像:
# 不推荐: 使用latest标签
FROM nginx:latest
# 推荐: 使用具体版本
FROM nginx:1.21.6-alpine
# 更推荐: 使用精简版本
FROM nginx:1.21.6-alpine3.15
# 最推荐: 使用distroless镜像
FROM gcr.io/distroless/nginx:latest
镜像大小对比:
镜像大小对比:
┌──────────────────────┬──────────────┬──────────────┐
│ 镜像 │ 大小 │ 安全性 │
├──────────────────────┼──────────────┼──────────────┤
│ nginx:latest │ 142MB │ 一般 │
│ nginx:alpine │ 25MB │ 好 │
│ nginx:distroless │ 20MB │ 最好 │
└──────────────────────┴──────────────┴──────────────┘
distroless优势:
✅ 最小化攻击面
✅ 无shell,难以攻击
✅ 无包管理器
✅ 体积小,漏洞少
Dockerfile安全实践:
# 不推荐: 使用root用户
FROM nginx:latest
# 默认就是root
# 推荐: 创建非root用户
FROM nginx:alpine
# 创建用户和组
RUN addgroup -g 1000 -S appgroup && \
adduser -u 1000 -S appuser -G appgroup
# 设置文件权限
RUN chown -R appuser:appgroup /var/cache/nginx && \
chown -R appuser:appgroup /var/log/nginx && \
chown -R appuser:appgroup /etc/nginx/conf.d
# 切换用户
USER appuser
# 暴露端口
EXPOSE 8080
# 启动命令
CMD ["nginx", "-g", "daemon off;"]
运行时权限控制:
# 以非root用户运行
docker run -d \
--name nginx \
--user 1000:1000 \
nginx:alpine
# 只读文件系统
docker run -d \
--name nginx \
--read-only \
--tmpfs /tmp \
--tmpfs /var/cache/nginx \
--tmpfs /var/run \
nginx:alpine
# 禁止特权提升
docker run -d \
--name nginx \
--security-opt no-new-privileges \
nginx:alpine
网络模式对比:
网络模式安全性:
┌──────────────────┬──────────────┬──────────────┐
│ 模式 │ 隔离性 │ 安全性 │
├──────────────────┼──────────────┼──────────────┤
│ bridge │ 中 │ 中 │
│ host │ 无 │ 低 │
│ none │ 高 │ 高 │
│ container │ 低 │ 低 │
│ 自定义网络 │ 高 │ 高 │
└──────────────────┴──────────────┴──────────────┘
安全建议:
✅ 使用自定义网络
✅ 禁止使用host模式
✅ 限制容器间通信
✅ 使用网络策略
自定义网络配置:
# 创建自定义网络
docker network create \
--driver bridge \
--subnet 172.20.0.0/16 \
--ip-range 172.20.0.0/24 \
--gateway 172.20.0.1 \
mynetwork
# 连接容器到网络
docker run -d --name web --network mynetwork nginx
docker run -d --name db --network mynetwork mysql
# 限制容器间通信
docker network create \
--driver bridge \
--internal \
internal-network
# 连接到内部网络
docker run -d --name app --network internal-network myapp
端口暴露最佳实践:
# 不推荐: 暴露所有接口
docker run -d -p 80:80 nginx
# 推荐: 绑定特定IP
docker run -d -p 127.0.0.1:80:80 nginx
# 更推荐: 使用反向代理
docker run -d -p 127.0.0.1:8080:80 --name nginx nginx
docker run -d -p 80:80 --link nginx:nginx nginx-proxy
# 使用Docker Compose
version: '3.8'
services:
nginx:
image: nginx:alpine
ports:
- "127.0.0.1:8080:80"
networks:
- frontend
app:
image: myapp:latest
networks:
- frontend
- backend
db:
image: mysql:5.7
networks:
- backend
# 不暴露端口,只在内网访问
networks:
frontend:
backend:
internal: true # 内部网络,无法访问外网
iptables规则:
# 查看Docker iptables规则
iptables -L -n -v
# 限制容器访问主机
iptables -I DOCKER-USER -i docker0 -d 192.168.1.0/24 -j DROP
# 限制容器间通信
iptables -I DOCKER-USER -s 172.17.0.2 -d 172.17.0.3 -j DROP
# 允许特定容器通信
iptables -I DOCKER-USER -s 172.17.0.2 -d 172.17.0.3 -p tcp --dport 3306 -j ACCEPT
Calico网络策略:
# calico-policy.yaml
apiVersion: projectcalico.org/v3
kind: NetworkPolicy
metadata:
name: allow-web
namespace: default
spec:
selector: app == 'web'
ingress:
- action: Allow
protocol: TCP
destination:
ports:
- 80
- 443
egress:
- action: Allow
protocol: TCP
destination:
ports:
- 3306
daemon.json安全配置:
{
"icc": false,
"live-restore": true,
"userland-proxy": false,
"no-new-privileges": true,
"userns-remap": "default",
"tls": true,
"tlsverify": true,
"tlscacert": "/etc/docker/ssl/ca.pem",
"tlscert": "/etc/docker/ssl/server-cert.pem",
"tlskey": "/etc/docker/ssl/server-key.pem",
"hosts": ["tcp://0.0.0.0:2376", "unix:///var/run/docker.sock"],
"log-level": "info",
"log-driver": "json-file",
"log-opts": {
"max-size": "10m",
"max-file": "3"
},
"storage-driver": "overlay2",
"storage-opts": [
"overlay2.override_kernel_check=true"
]
}
配置说明:
安全配置项:
├─ icc: 禁止容器间通信
├─ live-restore: 守护进程重启时容器继续运行
├─ userland-proxy: 禁用用户空间代理
├─ no-new-privileges: 禁止特权提升
├─ userns-remap: 启用User Namespace
├─ tls: 启用TLS
├─ tlsverify: 启用TLS验证
└─ log-level: 日志级别
配置效果:
✅ 增强容器隔离
✅ 启用加密通信
✅ 限制权限提升
✅ 审计日志记录
生成TLS证书:
# 创建CA证书
openssl genrsa -out ca-key.pem 4096
openssl req -new -x509 -days 365 -key ca-key.pem -sha256 -out ca.pem
# 创建服务器证书
openssl genrsa -out server-key.pem 4096
openssl req -new -key server-key.pem -out server.csr
openssl x509 -req -days 365 -sha256 -in server.csr -CA ca.pem -CAkey ca-key.pem \
-CAcreateserial -out server-cert.pem
# 创建客户端证书
openssl genrsa -out key.pem 4096
openssl req -new -key key.pem -out client.csr
openssl x509 -req -days 365 -sha256 -in client.csr -CA ca.pem -CAkey ca-key.pem \
-CAcreateserial -out cert.pem
# 设置权限
chmod -v 0400 ca-key.pem key.pem server-key.pem
chmod -v 0444 ca.pem server-cert.pem cert.pem
使用TLS连接:
# 使用TLS连接Docker
docker --tlsverify \
--tlscacert=ca.pem \
--tlscert=cert.pem \
--tlskey=key.pem \
-H=docker.example.com:2376 \
version
# 配置环境变量
export DOCKER_HOST=tcp://docker.example.com:2376
export DOCKER_TLS_VERIFY=1
export DOCKER_CERT_PATH=/path/to/certs
# 直接使用
docker version
配置审计日志:
# 安装auditd
apt-get install auditd # Ubuntu/Debian
yum install audit # CentOS/RHEL
# 配置Docker审计规则
cat >> /etc/audit/rules.d/audit.rules <<EOF
-w /var/lib/docker -k docker
-w /etc/docker -k docker
-w /usr/lib/systemd/system/docker.service -k docker
-w /usr/lib/systemd/system/docker.socket -k docker
-w /usr/bin/docker -k docker
-w /usr/bin/dockerd -k docker
EOF
# 重启auditd
service auditd restart
# 查看审计日志
ausearch -k docker
审计日志示例:
time->Mon Jan 1 00:00:00 2024
type=PROCTITLE msg=audit(1234567890.123:123): proctitle=2F7573722F62696E2F646F636B65720076657273696F6E
type=PATH msg=audit(1234567890.123:123): item=0 name="/usr/bin/docker" inode=123456 dev=08:01 mode=0100755 ouid=0 ogid=0 rdev=00:00 nametype=NORMAL
type=CWD msg=audit(1234567890.123:123): cwd="/root"
type=SYSCALL msg=audit(1234567890.123:123): arch=c000003e syscall=59 success=yes exit=0 a0=55b3c8b2b2a0 a1=55b3c8b2b4a0 a2=55b3c8b2b5a0 a3=7ffea3b2b5a0 items=2 ppid=1234 pid=5678 auid=0 uid=0 gid=0 euid=0 suid=0 fsuid=0 egid=0 sgid=0 fsgid=0 tty=pts0 ses=1 comm="docker" exe="/usr/bin/docker" key="docker"
镜像安全检查清单:
✅ 使用官方基础镜像
✅ 使用具体版本标签
✅ 使用精简镜像(alpine/distroless)
✅ 定期扫描镜像漏洞
✅ 使用镜像签名验证
✅ 最小化镜像镜像层数
✅ 不在镜像中存储敏感信息
✅ 使用非root用户运行
容器安全检查清单:
✅ 限制容器能力
✅ 不使用特权模式
✅ 启用User Namespace
✅ 配置Seccomp
✅ 配置AppArmor/SELinux
✅ 只读文件系统
✅ 限制资源使用
✅ 禁止特权提升
网络安全检查清单:
✅ 使用自定义网络
✅ 限制端口暴露
✅ 启用TLS加密
✅ 配置网络策略
✅ 限制容器间通信
✅ 使用防火墙规则
✅ 监控网络流量
守护进程安全检查清单:
✅ 启用TLS认证
✅ 配置审计日志
✅ 限制API访问
✅ 定期更新Docker版本
✅ 备份配置文件
✅ 监控守护进程状态
常用安全工具:
镜像扫描:
├─ Trivy: 综合漏洞扫描
├─ Clair: 企业级扫描
├─ Anchore: 策略扫描
└─ Docker Scout: Docker官方工具
运行时安全:
├─ Falco: 运行时安全监控
├─ Sysdig: 容器监控
├─ Aqua: 运行时保护
└─ Twistlock: 云原生安全
合规检查:
├─ Docker Bench Security: CIS基准检查
├─ Clair: CVE扫描
└─ OpenSCAP: 安全合规
运行安全检查:
# 下载Docker Bench Security
git clone https://github.com/docker/docker-bench-security.git
cd docker-bench-security
# 运行检查
./docker-bench-security.sh
# 输出
# ------------------------------------------------------------------------------
# Docker Bench for Security v1.3.6
#
# Docker, Inc. (c) 2015-2024
# Checks for dozens of common best-practices around deploying Docker containers in production.
# Inspired by the CIS Docker Benchmark v1.2.0.
# ------------------------------------------------------------------------------
[INFO] 1 - Host Configuration
[WARN] 1.1 - Ensure a separate partition for containers has been created
[NOTE] 1.2 - Ensure the container host has been Hardened
[PASS] 1.3 - Ensure Docker is up to date
...
[INFO] 2 - Docker daemon configuration
[PASS] 2.1 - Ensure network traffic is restricted between containers on the default bridge
[PASS] 2.2 - Ensure the logging level is set to 'info'
[PASS] 2.3 - Ensure Docker is allowed to make changes to iptables
...
[INFO] 3 - Docker daemon configuration files
[PASS] 3.1 - Ensure that docker.service file ownership is set to root:root
[PASS] 3.2 - Ensure that docker.service file permissions are appropriately set
...
[INFO] 4 - Container Images and Build File
[WARN] 4.1 - Ensure a user for the container has been created
[PASS] 4.2 - Ensure that containers use trusted base images
...
[INFO] 5 - Container Runtime
[PASS] 5.1 - Ensure AppArmor Profile is Enabled
[PASS] 5.2 - Ensure SELinux security options are set, if applicable
...
[INFO] 6 - Docker Security Operations
[PASS] 6.1 - Ensure image vulnerability scanning is performed
[PASS] 6.2 - Ensure containers are only used with trusted images
...
[INFO] 7 - Docker Swarm Configuration
[WARN] 7.1 - Ensure swarm mode is not Enabled, if not needed
...
容器安全机制:
├─ Namespace: 隔离
├─ Cgroups: 限制
├─ Capabilities: 权限控制
├─ Seccomp: 系统调用过滤
└─ AppArmor/SELinux: 强制访问控制
镜像安全:
├─ 漏洞扫描
├─ 镜像签名
├─ 基础镜像选择
└─ 最小权限原则
网络安全:
├─ 网络隔离
├─ 端口控制
├─ TLS加密
└─ 网络策略
守护进程安全:
├─ TLS认证
├─ 审计日志
├─ 配置加固
└─ 定期更新
最小权限原则:
✅ 删除不必要的capabilities
✅ 不使用特权模式
✅ 以非root用户运行
✅ 只读文件系统
纵深防御:
✅ 多层安全机制
✅ 镜像扫描
✅ 运行时监控
✅ 网络隔离
持续监控:
✅ 定期扫描漏洞
✅ 监控容器行为
✅ 审计日志分析
✅ 安全事件响应
下一章: Docker监控与日志
将学习:
Namespace隔离: 查看容器的Namespace,理解不同Namespace的作用。
Capabilities管理: 创建一个容器,删除所有能力,只添加NET_BIND_SERVICE能力。
镜像扫描: 使用Trivy扫描一个镜像,分析漏洞报告。
安全配置: 为Docker守护进程配置TLS,使用TLS连接Docker。
Seccomp配置: 编写一个Seccomp配置文件,限制容器的系统调用。
安全加固: 编写一个安全的Dockerfile,遵循所有安全最佳实践。
完整安全方案: 设计一个完整的Docker安全方案,要求:
安全审计: 使用Docker Bench Security对现有环境进行安全审计,并修复发现的问题。