27、容器安全加固
Categories:
8 分钟阅读
定位:容器技术栈(Docker / Kubernetes / Harbor)等保三级安全加固手册:按 00~10 编号分节覆盖基线自查、Docker 守护进程与远程 API、镜像治理、运行时隔离、用户命名空间、日志审计、Kubernetes 控制面与数据面、Harbor 私有仓库、备份恢复与版本生命周期,每节附核查命令、加固操作与官方依据。
适用版本:Docker Engine 24.x/25.x(daemon.json 配置参考以 docs.docker.com 现行版为准)、Kubernetes v1.28~v1.33(kubeadm 与二进制部署)、Harbor 2.x(v2.10+)。 配套测评:Docker 容器运行平台测评、Kubernetes 容器编排平台测评、Harbor 容器镜像仓库测评。
使用说明:
- 本文为加固操作手册:
systemctl restart docker、修改 kube-apiserver 静态 Pod 参数(需重启控制面 Pod)、docker restart均会造成业务中断,实施前必须完成变更审批、确认业务窗口、备份daemon.json//etc/kubernetes//Harbor 数据目录,并准备可执行的回滚预案。- 先在测试集群或单节点灰度验证,确认业务容器与 Pod 正常后再推广;每完成一项立即用文中「核查方法」复核——
daemon.json修改后未重启守护进程不生效、userns-remap启用后既有镜像与容器会被隔离到新的属主目录(官方建议在新装环境启用而非存量环境)。- 示例中的地址、账户、口令、路径均为演示值(如
192.168.10.5、registry.demo.local),现场须替换为真实值并脱敏;严禁直接沿用示例口令。- 命令回显与本文不一致时,先确认版本与部署形态(包管理器/二进制/kubeadm/Helm),再查阅对应版本文档换用等效命令;版本差异不得直接作为「无法整改」的结论,须给出替代措施并评估其实际效果。
- 涉及远程 API、TLS、RBAC、准入的变更存在锁死自身风险:务必保留一条已验证的恢复通道(本机 root SSH、控制台访问、另一个 cluster-admin kubeconfig 或 bootstrap token)后再实施。
- 加固完成后按「16、安全评估加固记录表3.0」逐项留痕,并纳入复测;测评判定口径以 GB/T 28448-2019 与《高风险判定指引》为准。
不适用标识说明:
- 使用
【不适用】明确标记现场可判定为不适用的控制点,并写明判定依据与承载该能力的上位组件。- 依据 GB/T 28448-2019「按测评对象实际承载功能与数据处理范围判定」原则:能力由云托管容器平台(ACK/GKE/EKS 等)、镜像仓库 SaaS、统一日志平台承载时,应注明测评单元边界后判定不适用或转由上位组件核查。
- 产品版本确实不提供该能力时,须核查替代措施并按实际效果定档,不得直接判不适用。
测评项对照表
| 控制点(GB/T 22239-2019 安全计算环境-容器平台) | 对应章节 |
|---|---|
| 入侵防范:暴露面收敛、最小安装、漏洞修补 | 00、01、02 |
| 身份鉴别:管理入口鉴别、防窃听 | 01、06、08 |
| 访问控制:权限最小化、默认账户治理 | 03、06、08 |
| 安全审计:日志与留存 | 05 |
| 数据保密性:etcd 加密、TLS | 07 |
| 数据备份恢复 | 09 |
| 剩余信息保护:镜像与凭据清理 | 10 |
00 官方安全基线与自查
对应控制点:GB/T 22239-2019 8.1.4.4 入侵防范 a)~f)
加固要点:以官方文档与社区基线为整改标尺并定期自查:Docker 官方安全文档与守护进程攻击面说明(docs.docker.com/engine/security/)、CIS Docker Benchmark 与配套自查脚本 Docker Bench for Security(docker/docker-bench-security)、CIS Kubernetes Benchmark(cisecurity.org 入口)、Harbor 官方管理文档(goharbor.io/docs)。测评现场高频引用的容器逃逸与暴露面判定口径即来自这两套基准。
验证方法:Docker Bench for Security 输出报告(WARN 项整改台账)、CIS 自查记录、版本台账。
核查方法
# Docker Bench for Security(只读自查脚本,容器化运行)
docker run --rm --net none --pid host --userns host --cap-drop ALL \
-v /var/lib:/var/lib:ro -v /var/run/docker.sock:/var/run/docker.sock:ro \
-v /etc:/etc:ro --label docker_bench_security docker/docker-bench-security
docker version --format '{{.Server.Version}}'
kubectl version
docker compose version # Harbor 2.x 部署侧
- 预期现象:自查报告 WARN 项有整改记录;三平台版本均在官方支持窗口内。
01 Docker 守护进程与远程 API 收敛(核心)
对应控制点:GB/T 22239-2019 8.1.4.1 身份鉴别 c)、8.1.4.4 入侵防范 b) c)
加固要点:Docker 守护进程默认仅监听本机 Unix socket(
/var/run/docker.sock),凡将-H tcp://0.0.0.0:2375明文开放远程 API,等同向网络开放 root 级主机控制通道(官方安全文档明确要求守护进程仅可达于受信方)。确需远程管理时:仅绑定运维网段地址、强制--tlsverify双向证书认证(ca/server/client 三套证书)、防火墙仅放行堡垒机来源;docker.sock不得挂载进业务容器;宿主机侧对 docker 组成员按最小化收敛(docker 组等价 root)。验证方法:
ss -lntp无 2375 明文监听、docker context ls管理通道清单、TLS 证书连接实测、docker inspect无 sock 挂载抽查。
2375/2376 端口对非运维网段开放且未启用 TLS 双向认证,或 /var/run/docker.sock 被挂载进业务容器,按《高风险判定指引》直接判高风险——通过该通道可在宿主机创建特权容器完成逃逸。
判定口径详见 22、高风险判定指引与加固对照表。
核查方法
ss -lntp | grep -E "2375|2376"
ps -ef | grep [d]ockerd
docker context ls
grep -R "hosts\|tls" /etc/docker/daemon.json
docker ps -q | xargs -I{} docker inspect {} --format '{{.Name}} {{json .Mounts}}' | grep docker.sock
示例输出(节选)
$ ss -lntp | grep 237
LISTEN 0 128 192.168.10.5:2376 users:(("dockerd",pid=1122,fd=7)) # 仅运维网段且 TLS
(无 0.0.0.0:2375 明文监听)
$ ps -ef | grep [d]ockerd
root 1122 /usr/bin/dockerd --tlsverify --tlscacert=/etc/docker/ca.pem \
--tlscert=/etc/docker/server-cert.pem --tlskey=/etc/docker/server-key.pem \
-H=fd:// -H=tcp://192.168.10.5:2376
加固操作(/etc/docker/daemon.json + 重启;证书生成走内部 CA,客户端配置 docker context create 分发)
# 生成服务端/客户端证书(官方 Protect the Docker daemon socket 章节流程,CA 为内部根)
systemctl stop docker
# 编辑 /etc/docker/daemon.json:见下方 JSON
systemctl start docker
docker --tlsverify --tlscacert=ca.pem --tlscert=cert.pem --tlskey=key.pem \
-H=tcp://192.168.10.5:2376 version # 验证 TLS 通道
{
"hosts": ["unix:///var/run/docker.sock", "tcp://192.168.10.5:2376"],
"tls": true,
"tlsverify": true,
"tlscacert": "/etc/docker/ca.pem",
"tlscert": "/etc/docker/server-cert.pem",
"tlskey": "/etc/docker/server-key.pem",
"live-restore": true,
"log-driver": "json-file",
"log-opts": { "max-size": "50m", "max-file": "5" }
}
- 预期现象:明文 API 关闭;无证书客户端连接被拒;
live-restore生效(守护进程重启不中断容器,docker info显示Live Restore Enabled: true)。
02 镜像治理与内容信任
对应控制点:GB/T 22239-2019 8.1.4.4 入侵防范 a) d)(最小安装、数据有效性检验)
加固要点:镜像来源白名单(仅内部 Harbor 或官方认证仓库,杜绝公网随手
docker run);基础镜像定期重建扫描(配合 Harbor Trivy,见 08 节);启用内容信任(Content Trust)验证镜像签名——环境变量DOCKER_CONTENT_TRUST=1后 pull 未签名镜像被拒(官方 Content trust in Docker 章节);生产镜像使用 digest 固定(nginx@sha256:...)而非可变 tag;镜像构建走 CI 流水线留痕,禁止在生产宿主机现场构建。验证方法:
DOCKER_CONTENT_TRUST=1 docker pull拒绝未签名镜像实测、镜像清单 digest 抽查、CI 构建记录。
核查方法
docker images --digests
DOCKER_CONTENT_TRUST=1 docker pull demo.local/app:v1.2.3
grep -R "DOCKER_CONTENT_TRUST" /etc/profile.d/ /root/.bashrc 2>/dev/null
示例输出(节选)
$ DOCKER_CONTENT_TRUST=1 docker pull demo.local/app:v1.2.3
Pull (1 of 1): demo.local/app@sha256:9c7f...
docker.io/demo.local/app:v1.2.3 未启用签名的公共仓库:
Error: remote does not have trusted data # 无签名镜像被拒
加固操作
# 对运维账户默认启用内容信任(按需,注意对既有脚本的影响——未签名仓库 pull 会失败)
echo 'export DOCKER_CONTENT_TRUST=1' > /etc/profile.d/docker-trust.sh
- 预期现象:签名验证开启;镜像台账中每条来源可追溯(仓库、digest、构建流水线编号)。
03 容器运行时隔离:非 root、去特权与能力收敛
对应控制点:GB/T 22239-2019 8.1.4.2 访问控制 a)~f)、8.1.4.4 入侵防范
加固要点:官方安全文档的优先级顺序:容器内应用以非特权用户运行是防提权的第一道防线(
docker run --user或镜像内 USER 指令);禁止无业务必要的--privileged(官方明确其给予几乎所有主机能力);按需--cap-drop ALL后仅--cap-add单项能力;只读根文件系统--read-only;资源限额(--memory/--cpus)防资源耗尽;seccomp 默认 profile 已启用(Docker 默认阻断数十个高危系统调用,自定义见官方 Seccomp security profiles 章节);Ubuntu 宿主机确认 AppArmor profile 加载(官方 AppArmor security profiles for Docker 章节)。挂载最小化:不挂载/etc、/var/run、/root等宿主敏感目录,必需挂载尽量:ro。验证方法:
docker inspect的 Privileged/CapAdd/User/ReadonlyRootfs 字段抽查、docker info的 Security Options(seccomp/apparmor)、特权容器清单为空或有例外审批。
--privileged、--pid=host、--network=host、挂载 docker.sock 或宿主 / 目录的容器,以及以 root 长期运行且暴露公网端口的业务容器,按《高风险判定指引》判高风险(宿主机逃逸通道)。
判定口径详见 22、高风险判定指引与加固对照表。
核查方法
docker ps -q | xargs -I{} docker inspect {} --format \
'{{.Name}} Priv={{.HostConfig.Privileged}} Caps={{.HostConfig.CapAdd}} User={{.Config.User}} RO={{.HostConfig.ReadonlyRootfs}}'
docker info --format '{{json .SecurityOptions}}'
docker ps -q | xargs -I{} docker inspect {} --format '{{.Name}} {{json .HostConfig.Binds}}'
示例输出(节选)
/demo-web Priv=false Caps=[] User=appuser RO=true
/demo-redis Priv=false Caps=[] User=999 RO=false
docker info --format '{{json .SecurityOptions}}'
["name=seccomp,profile=builtin","name=apparmor,profile=docker-default"]
加固操作(以运行命令与 Dockerfile 两条路径落地,变更需重启容器窗口)
# 运行命令侧:非 root + 全量去能力 + 按需加回 + 只读根 + 资源限额
docker run -d --name demo-web \
--user 1000:1000 --cap-drop ALL --cap-add NET_BIND_SERVICE \
--read-only --tmpfs /tmp --memory 512m --cpus 1.0 \
--restart unless-stopped demo.local/app:v1.2.3
# Dockerfile 侧:镜像固化非 root 用户与最小内容
FROM registry.demo.local/base/nginx:1.24-alpine
RUN adduser -D -u 1000 appuser
USER appuser
- 预期现象:特权容器清单为空;
CapAdd均有业务依据;业务回归正常。
04 用户命名空间重映射(userns-remap)与 rootless
对应控制点:GB/T 22239-2019 8.1.4.2 访问控制、8.1.4.4 入侵防范(提权防护)
加固要点:官方 userns-remap 机制:把容器内 root 重映射为宿主机无特权的高位 UID 区间(经
/etc/subuid、/etc/subgid管理,如dockremap:231072:65536——容器内 UID 0 对应宿主 UID 231072,对宿主无任何特权)。daemon.json配{"userns-remap": "default"}由 Docker 自动创建dockremap用户(也可指定既有用户)。官方注意事项:启用后既有镜像与容器会被隔离(对象移入/var/lib/docker/<uid>.<gid>/子目录,建议在新装环境启用);与--privileged、--pid=host、--network=host不兼容(需--userns=host显式豁免,豁免须审批)。更彻底的隔离用 Rootless 模式(守护进程与容器均无 root,见官方 Rootless mode 章节),适配场景有限时保留 sock 权限收敛补偿。验证方法:
docker info出现userns安全选项、grep dockremap /etc/subuid、宿主/var/lib/docker/<uid>.<gid>/目录属主、容器内 root 对宿主文件无写入实测。
核查方法
docker info | grep -i -A2 "security"
grep dockremap /etc/subuid /etc/subgid
id dockremap
ls -ld /var/lib/docker/[0-9]*.[0-9]*/ 2>/dev/null
示例输出(节选)
$ grep dockremap /etc/subuid /etc/subgid
/etc/subuid:dockremap:231072:65536
/etc/subgid:dockremap:231072:65536
$ ls -ld /var/lib/docker/231072.231072/
drwx------ 11 231072 231072 4096 Jun 21 21:19 /var/lib/docker/231072.231072/
加固操作(新装环境优先;存量环境须先导出容器清单并安排重建窗口)
{ "userns-remap": "default" }
- 预期现象:重启后
docker infoSecurity options 含userns;既有镜像列表为空(对象已隔离)属正常现象;容器内cat /proc/self/uid_map显示映射区间。
05 日志与审计
对应控制点:GB/T 22239-2019 8.1.4.3 安全审计 a)~d)
加固要点:容器日志三路汇聚并留存不少于 6 个月:容器 stdout 日志(daemon.json 的
log-driver+max-size+max-file,防磁盘占满即防日志丢失)、守护进程日志(journalctl -u docker,外送 rsyslog)、宿主机 auditd 对 Docker 关键路径的审计规则(docker.sock、daemon.json、/var/lib/docker 的变更)。容器内应用日志沿用宿主日志通道或独立采集器,不留在容器可写层。日志外送至日志审计系统(《网络安全法》第 21 条留存口径)。验证方法:
docker info日志驱动与轮转参数回显、auditd 规则auditctl -l、日志平台中容器日志最早时间戳。
核查方法
docker info --format '{{.LoggingDriver}}'
grep -A4 "log-driver" /etc/docker/daemon.json
journalctl -u docker --no-pager | tail -n 5
auditctl -l | grep docker
示例输出(节选)
$ grep -A4 "log-driver" /etc/docker/daemon.json
"log-driver": "json-file",
"log-opts": { "max-size": "50m", "max-file": "5" }
$ auditctl -l | grep docker
-w /etc/docker/daemon.json -p wa -k docker_config
-w /var/run/docker.sock -p wa -k docker_sock
加固操作
# auditd 规则(/etc/audit/rules.d/docker.rules,载入后 auditctl -R 或重启 auditd)
cat > /etc/audit/rules.d/docker.rules <<'EOF'
-w /etc/docker/daemon.json -p wa -k docker_config
-w /etc/docker -p wa -k docker_dir
-w /var/run/docker.sock -p wa -k docker_sock
EOF
augenrules --load
- 预期现象:规则加载成功;日志平台可检索 6 个月以上容器事件;
docker inspect日志路径在轮转目录内。
06 Kubernetes 控制面加固
对应控制点:GB/T 22239-2019 8.1.4.1 身份鉴别、8.1.4.2 访问控制、8.1.4.3 安全审计
加固要点:kube-apiserver 收敛:
--anonymous-auth=false(默认 true,匿名请求映射 system:anonymous,关闭后未认证请求被拒)、--insecure-port已废弃不得出现;RBAC 治理:cluster-adminClusterRoleBinding 仅保留必要主体(审计kubectl get clusterrolebindings cluster-admin -o wide),不为普通用户/组授予;准入链启用NodeRestriction(kubelet 仅能修改自身 Node/Pod)与 Pod Security Admission(命名空间打pod-security.kubernetes.io/enforce标签,baseline/restricted 分级,v1.25 起稳定);审计策略--audit-policy-file全量覆盖(至少 metadata 级,认证失败与特权操作升 Request 级),--audit-log-maxage≥180 满足 6 个月留存(现行默认 366);管理入口仅经堡垒机/运维网段访问 6443。ServiceAccount 治理:默认 token 自 v1.24 不再自动投影长期令牌,automountServiceAccountToken: false按业务显式关闭。验证方法:apiserver 启动参数核查(静态 Pod YAML/
kubectl get --raw='/readyz?verbose')、无凭据 curl 6443 返回 401 实测、cluster-admin 绑定清单、审计日志样例(含 user/verb/resource/时间)、namespace PSA 标签清单。
API Server 匿名访问开启且 6443 暴露非运维网段、cluster-admin 绑定到普通用户/组、system:anonymous 被授予写权限,按《高风险判定指引》判高风险。
判定口径详见 22、高风险判定指引与加固对照表。
核查方法
kubectl get pods -n kube-system -l component=kube-apiserver -o yaml | grep -E "anonymous-auth|audit-policy|authorization-mode|admission"
kubectl get clusterrolebindings cluster-admin -o wide
kubectl get ns -L pod-security.kubernetes.io/enforce
curl -sk https://192.168.10.5:6443/version # 预期 401 Unauthorized
kubectl auth can-i --list --as=system:anonymous
示例输出(节选)
$ grep -E "anonymous-auth|authorization-mode" <apiserver.yaml>
- --anonymous-auth=false
- --authorization-mode=Node,RBAC
$ curl -sk https://192.168.10.5:6443/version
{
"kind": "Status",
"code": 401, ...
}
$ kubectl get clusterrolebindings cluster-admin -o wide
NAME ROLE SUBJECTS
cluster-admin ClusterRole/cluster-admin Group/system:masters # 仅控制面组
加固操作(修改 /etc/kubernetes/manifests/kube-apiserver.yaml 后静态 Pod 自动重启,须维护窗口)
- command:
- kube-apiserver
- --anonymous-auth=false
- --authorization-mode=Node,RBAC
- --enable-admission-plugins=NodeRestriction
- --audit-policy-file=/etc/kubernetes/audit-policy.yaml
- --audit-log-path=/var/log/kubernetes/audit.log
- --audit-log-maxage=365
- --audit-log-maxbackup=10
- --audit-log-maxsize=100
- 预期现象:匿名请求 401;审计日志持续落盘且含认证失败事件;PSA enforce 标签覆盖全部业务命名空间。
07 Kubernetes 数据面与 etcd 加密
对应控制点:GB/T 22239-2019 8.1.4.7 数据完整性、8.1.4.8 数据保密性
加固要点:etcd 是集群全量状态库,三级要求落地三件事:静态加密——kube-apiserver 启用
--encryption-provider-config(EncryptionConfiguration,官方现行推荐secretbox加密 Secret;kms v2 自 v1.29 稳定,对接外部 KMS 更佳),并以k8s:enc:前缀验证实际落密;传输加密——apiserver 与 etcd 间--etcd-cafile/--etcd-certfile/--etcd-keyfile证书双向认证,etcd 2379 仅监听管理网/本机(ss -lntp | grep 2379);访问控制——etcd 证书与 key 文件权限 600,仅控制面节点可达。数据面:Pod 出网按 NetworkPolicy 白名单化(默认全通须整改);Secret 不落明文(避免 env 明文注入,优先 volume 挂载或外部密钥管理);镜像来源与签名策略经准入(Gatekeeper/Kyverno 或仓库侧策略)管控。验证方法:
kubectl get secret -o jsonpath数据带k8s:enc:前缀、etcdctl 直读为密文、2379 监听地址与防火墙策略、NetworkPolicy 覆盖清单。
核查方法
kubectl get secret demo-secret -n demo-ns -o jsonpath='{.data.password}' | base64 -d | head -c 40
grep -R "encryption-provider-config\|etcd-cafile" /etc/kubernetes/
ss -lntp | grep 2379
kubectl get networkpolicy -A
ETCDCTL_API=3 etcdctl --cacert=/etc/kubernetes/pki/etcd/ca.crt \
--cert=/etc/kubernetes/pki/etcd/server.crt --key=/etc/kubernetes/pki/etcd/server.key \
get /kubernetes/secrets/demo-ns/demo-secret --print-value-only | head -c 60
示例输出(节选)
$ kubectl get secret demo-secret -o jsonpath='{.data.password}' | base64 -d | head -c 40
k8s:enc:aescbc:v1:key1:fi��... # k8s:enc: 前缀=已静态加密
$ etcdctl get ... --print-value-only | head -c 60
k8s:enc:aescbc:v1:key1:��}... # etcd 侧同为密文
$ ss -lntp | grep 2379
LISTEN 0 128 192.168.10.5:2379 users:(("etcd",pid=990,fd=6)) # 未绑 0.0.0.0
加固操作(先创建 EncryptionConfiguration,再改 apiserver 参数重启;旧 Secret 须重写一遍才会被加密——官方文档以 kubectl get secrets --all-namespaces -o json | kubectl replace -f - 触发重写)
# /etc/kubernetes/enc-config.yaml(官方 Encrypting Secret Data at Rest 章节示例结构)
apiVersion: apiserver.config.k8s.io/v1
kind: EncryptionConfiguration
resources:
- resources: ["secrets"]
providers:
- secretbox:
keys:
- name: key1
secret: <32字节随机base64>
- identity: {}
- 预期现象:新写入 Secret 带
k8s:enc:前缀;etcd 直读密文;2379 不对业务网段开放。
08 Harbor 私有仓库加固
对应控制点:GB/T 22239-2019 8.1.4.1~8.1.4.4(仓库作为镜像供应链核心组件)
加固要点:
harbor.yml强制 HTTPS(自签证书须向 docker daemon 与 k8c节点分发 CA;HTTP-only 对外即高风险);harbor_admin_password仅首次启动从配置文件读取(改口令须登录控制台,不能只改 yml——官方 Reconfigure 文档口径),初始Harbor12345必改;认证模式按需接 OIDC/LDAP(db_auth本地账户配强口令策略);关闭self_registration自助注册(按需);项目公开性默认私有、按最小可见开放;机器人账号(robot account)替代人员共享凭据拉取,设有效期与最小项目权限;Trivy 漏洞扫描开启并配置「高危阻断拉取」策略(Prevent images with vulnerability severity of High or higher from pulling);部署后启用审计日志留存与日志外送;定期垃圾回收(GC)清理无引用镜像层。验证方法:HTTPS 访问与证书有效期、admin 口令登录实测、
GET /api/v2.0/configurations的 self_registration/scan 策略回显、机器人账号清单与到期时间、GC 计划任务截图。
核查方法
grep -E "^hostname|^https|admin_password" /path/to/harbor/harbor.yml | sed 's/password.*/password: ***/'
curl -s -o /dev/null -w "%{http_code}\n" https://registry.demo.local/api/v2.0/health
curl -su admin:*** https://registry.demo.local/api/v2.0/configurations | jq '.self_registration, .scan_all_policy'
docker compose ps # Harbor 安装目录(v2 语法)
示例输出(节选)
$ curl -s https://registry.demo.local/api/v2.0/health
{"status":"healthy","components":[]}
$ curl -su admin:*** .../api/v2.0/configurations | jq '.self_registration'
false # 自助注册已关闭
加固操作(harbor.yml 修改后执行 ./prepare 与 docker compose down && docker compose up -d,须窗口)
# harbor.yml 关键项
hostname: registry.demo.local
https:
certificate: /data/cert/registry.crt
private_key: /data/cert/registry.key
harbor_admin_password: <首次部署时的强口令,之后经控制台修改>
- 预期现象:HTTP 跳转 HTTPS;扫描策略生效(高危镜像 pull 被拒实测);机器人账号按项目最小授权。
09 备份恢复
对应控制点:GB/T 22239-2019 8.1.4.9 数据备份恢复 a)~c)
加固要点:三平台各自的恢复面:Docker——
daemon.json、证书、自定义 systemd 单元与命名数据卷纳入配置管理,容器重建以编排(compose 文件/K8s 清单)为准而非手工 docker run 复现;Kubernetes——etcd 定期快照(etcdctl snapshot save;v3.5+ 校验用etcdutl snapshot status)异地存放,Velero 备份工作负载与 PV,恢复演练每半年至少一次并留痕;Harbor——按官方升级/备份章节导出/data/database、registry 存储、harbor.yml 与 secrets 归档。集群多副本(etcd 3 节点、控制面 HA)作为冗余不替代备份。验证方法:快照清单与
snapshot status输出、Velero 备份清单(velero backup get)、Harbor 归档清单、最近一次恢复演练记录。
核查方法
ls -l /backup/etcd-snapshots/ | tail -n 3
ETCDCTL_API=3 etcdutl snapshot status /backup/etcd-snapshots/snap-latest.db -w table 2>/dev/null \
|| ETCDCTL_API=3 etcdctl snapshot status /backup/etdb-snapshots/snap-latest.db -w table
velero backup get
docker run --rm -v /backup:/backup -v /var/lib/docker/volumes:/volumes alpine ls /backup
示例输出(节选)
$ etcdutl snapshot status /backup/etcd-snapshots/snap-latest.db -w table
+----------+----------+------------+------------+
| HASH | REVISION | TOTAL KEYS | TOTAL SIZE |
+----------+----------+------------+------------+
| 0x1a2b3c | 8941234 | 2011 | 29 MB |
+----------+----------+------------+------------+
加固操作(快照属运维变更,按计划任务窗口执行)
# etcd 定期快照(cron 示例)
ETCDCTL_API=3 etcdctl --endpoints=https://127.0.0.1:2379 \
--cacert=/etc/kubernetes/pki/etcd/ca.crt \
--cert=/etc/kubernetes/pki/etcd/server.crt \
--key=/etc/kubernetes/pki/etcd/server.key \
snapshot save /backup/etcd-snapshots/snap-$(date +%F).db
- 预期现象:快照按期生成且
snapshot status校验通过;恢复演练记录在案。
10 剩余信息保护与版本生命周期
对应控制点:GB/T 22239-2019 8.1.4.10 剩余信息保护、8.1.4.4 入侵防范(补丁管理)
核查方法
docker ps -a --filter "status=exited" --format "{{.Names}} {{.RunningFor}}"
docker images --format "{{.Repository}}:{{.Tag}} {{.CreatedSince}}" | sort -k2 | head
docker ps -q | xargs -I{} docker inspect {} --format '{{.Name}}' | wc -l
kubectl get secrets -A | wc -l
- 加固要点:停用容器、超过留存期的旧镜像、失效 ServiceAccount 令牌与机器人凭据定期清理并留处置记录(
docker container prune/docker image prune属变更类,走审批);环境变量中的明文口令改用 secret 机制(Docker secrets/K8s Secret 加密/外部 KMS)。 - 版本生命周期:Kubernetes 官方仅维护最近三个小版本(升级滚动计划);Docker Engine 跟随发行版/官方源补丁;Harbor 跟随 goharbor releases;三平台升级台账与窗口记录纳入测评证据。
- 预期现象:无长期 Exited 容器与半年以上未引用镜像;凭据无明文残留;升级记录完整。
参考依据
- GB/T 22239-2019《信息安全技术 网络安全等级保护基本要求》(8.1.4 安全计算环境各控制点):http://openstd.samr.gov.cn/bzgk/gb/newGbInfo?hcno=BAFB47E8874764186BDB7865E8344DAF
- GB/T 28448-2019《信息安全技术 网络安全等级保护测评要求》(测评对象边界认定、单元测评实施与结果判定):http://openstd.samr.gov.cn/bzgk/gb/newGbInfo?hcno=7E736CDF4502B6FF1258DD250AA3EC8C
- Docker 官方安全文档(守护进程攻击面、保护 Docker 守护进程 socket、seccomp/AppArmor、Rootless mode、Content trust):https://docs.docker.com/engine/security/
- Docker 官方用户命名空间隔离文档(userns-remap 启用、dockremap 与 /etc/subuid、已知限制——2026-09 全文核验):https://docs.docker.com/engine/security/userns-remap/
- Docker 官方 dockerd 配置参考(daemon.json 的 hosts/tls/tlsverify/live-restore/log-driver/log-opts):https://docs.docker.com/reference/dockerd/
- Docker Bench for Security 与 CIS Docker Benchmark:https://github.com/docker/docker-bench-security、https://www.cisecurity.org/benchmark/docker/
- Kubernetes 官方文档(kube-apiserver 命令行参考、Pod Security Admission、RBAC、审计策略、Secret 静态加密、etcd 运维——与站内测评篇同期核验):https://kubernetes.io/docs/reference/command-line-tools-reference/kube-apiserver/、https://kubernetes.io/docs/tasks/administer-cluster/encrypt-data/
- CIS Kubernetes Benchmark 入口:https://www.cisecurity.org/benchmark/kubernetes/
- Harbor 官方文档(harbor.yml 配置、重新配置生命周期、漏洞扫描、机器人账号、垃圾回收、备份):https://goharbor.io/docs/
- 《网络安全等级保护测评高风险判定指引》(中关村信息安全测评联盟团体标准),站内对照表:22、高风险判定指引与加固对照表
- 命令核验说明:本文命令已于 2026-09 对照 docs.docker.com(security/userns-remap 全文、dockerd 参考)、kubernetes.io(kube-apiserver 参考、Encrypting Secret Data at Rest)、goharbor.io/docs 核验,并与站内 Docker、Kubernetes、Harbor 三篇测评篇的核验结论互证;四处须留意:①
daemon.json的hosts与 systemd 单元ExecStart -H冲突会启动失败,改动前先systemctl cat docker确认;②userns-remap建议新装环境启用,存量环境启用后既有镜像/容器不可见(对象被隔离属预期而非故障);③ etcd 静态加密只对新写入 Secret 生效,存量 Secret 须触发重写;④ 快照校验命令在 etcd v3.5+ 迁移为etcdutl snapshot status(旧etcdctl snapshot status仍可用以现场版本为准)。
关联文章
- 配套测评:Docker 容器运行平台测评、Kubernetes 容器编排平台测评、Harbor 容器镜像仓库测评、Elasticsearch 搜索与分析平台测评
- 同目录:21、Web中间件安全加固、26、Redis数据库加固
- 主机层配套:11、Linux操作系统加固手册(容器宿主机按主机层加固)
- 通用加固方案:17、加固方案总纲
- 取证记录:16、安全评估加固记录表3.0
- 高风险口径:22、高风险判定指引与加固对照表
- 板块目录:系统管理软件·平台