本文目录导读:

- 镜像安全:从源头控制风险
- 容器运行时安全:限制容器权限与能力
- 宿主机与共享内核安全:隔离是关键
- 网络与编排(Kubernetes)安全
- 运行时可观测性:监控与告警
- 供应链安全:防投毒
- 实用工具推荐
- 一个安全的容器生命周期
容器安全防护加固是一个系统工程,需要从镜像、容器运行时、宿主机、网络、编排平台(如K8s)以及供应链等多个维度进行,以下是针对不同层面的详细加固策略:
镜像安全:从源头控制风险
这是最关键的防线,因为漏洞和恶意代码一旦嵌入镜像,后续运行时很难查杀。
-
使用信任的基础镜像:
- 优先选择官方、轻量级、维护活跃的基础镜像,如
alpine、distroless(谷歌的无发行版镜像)。 - 避免使用
latest标签,尽可能指定精确版本(如python:3.11.5-slim),确保可重复性和可审计性。
- 优先选择官方、轻量级、维护活跃的基础镜像,如
-
最小化原则:
- 镜像内只包含应用运行所必需的库、工具和文件,删除不需要的包、shell、调试工具(如
curl、wget、vim)、setuid/setgid二进制文件。 - 采用多阶段构建:在构建阶段使用功能完整的镜像(如带编译器的),最终运行镜像只复制编译好的二进制产物和最小依赖。
- 镜像内只包含应用运行所必需的库、工具和文件,删除不需要的包、shell、调试工具(如
-
镜像漏洞扫描:
- 集成到CI/CD流程:每次构建镜像后,自动使用工具扫描,常见工具:
Trivy(推荐,轻量全面)、Clair、Anchore、Snyk、Docker Scout。 - 建立漏洞容忍策略:根据漏洞严重等级(CVE Critical/High/Medium),决定是否允许镜像部署到生产环境,阻止存在任意高/严重级别漏洞的镜像上线。
- 集成到CI/CD流程:每次构建镜像后,自动使用工具扫描,常见工具:
-
镜像签名和验证:
- 使用
cosign、Notary等工具对构建好的镜像进行签名。 - 在部署时强制验证签名,确保镜像未被篡改,并且是由可信的构建流水线生成的。
- 使用
容器运行时安全:限制容器权限与能力
容器本质上是一个进程,需要限制其“越狱”的能力。
-
以非Root用户运行:
- 务必在 Dockerfile 中使用
USER指令指定一个非root用户(UID 为 1000-9999 之间)。 - 在 Kubernetes Pod 的
securityContext中明确设置runAsUser、runAsGroup和fsGroup。 - 对于需要特殊权限的应用(如写入特定目录),使用
PodSecurityContext配合fsGroup授予有限的写权限。
- 务必在 Dockerfile 中使用
-
启用“只读根文件系统”:
- 设置
readOnlyRootFilesystem: true。 - 同时使用
emptyDir卷挂载到应用需要写入的临时目录(如/tmp、/var/run),防止攻击者修改容器内的系统文件。
- 设置
-
丢弃不必要的 Linux Capabilities:
- 使用
cap_drop: ALL丢弃所有特权能力,再根据应用实际需要单独添加(如cap_add: NET_BIND_SERVICE用于绑定低于1024端口)。 - 禁止使用
privileged: true特权模式,除非万不得已(如硬件集成、网络插件等)。
- 使用
-
资源限制:
- 设置 CPU 和内存的
requests和limits,防止某个容器消耗过多资源导致 DoS(拒绝服务攻击)。
- 设置 CPU 和内存的
-
系统调用过滤(Seccomp):
- 使用 Seccomp(安全计算模式)限制容器可以执行的系统调用,建议先使用
RuntimeDefault配置文件(Docker默认提供),或自己编写只允许必要系统调用的白名单。
- 使用 Seccomp(安全计算模式)限制容器可以执行的系统调用,建议先使用
-
强制访问控制(AppArmor/SELinux):
在宿主机上启用 AppArmor(Ubuntu)或 SELinux(CentOS/RHEL),并为容器加载定制的配置文件。
宿主机与共享内核安全:隔离是关键
容器共享宿主内核,内核漏洞是最大的风险。
-
避免不安全挂载:
- 绝对禁止挂载
docker.sock到容器内,否则容器可以控制宿主机 Docker 守护进程。 - 避免挂载宿主机的敏感目录(如
/proc、/sys、/dev、根目录),若需挂载数据卷,使用只读模式ro,并限制挂载范围。
- 绝对禁止挂载
-
命名空间隔离:
- 启用 用户命名空间(User Namespace Remapping):将容器内的root用户映射到宿主机上的非特权用户,这样即使容器被攻破,攻击者获得的也是宿主机上的普通用户权限。
-
宿主机安全基线:
- 保持系统更新:及时打上 Linux 内核安全补丁。
- 配置防火墙:使用
iptables或nftables限制容器对外及跨主机流量。 - 审计日志:开启
auditd记录容器相关操作。
网络与编排(Kubernetes)安全
-
网络策略:
- 在 Kubernetes 中,默认拒绝所有入站/出站流量,然后通过
NetworkPolicy显式允许必要的流量,只允许前端Pod访问后端Pod,禁止后端Pod访问互联网。
- 在 Kubernetes 中,默认拒绝所有入站/出站流量,然后通过
-
Secrets 管理:
- 绝对不要将密码、API密钥、证书等硬编码在 Dockerfile、环境变量或镜像层中。
- 使用 Kubernetes
Secrets或外部密钥管理服务(如 HashiCorp Vault, AWS Secrets Manager)通过卷挂载或环境变量注入。
-
Pod Security Standards:
- 在 Kubernetes 1.23+ 中使用
Pod Security Admission强制实施安全策略,分为三个等级:- Privileged:无限制,通常用于系统组件。
- Baseline:应用默认的安全限制(如限制非root用户、禁止特权容器)。
- Restricted:最严格,强制遵循最佳实践,推荐用于生产环境。
- 在 Kubernetes 1.23+ 中使用
-
服务账户与 RBAC:
- 为每个应用或微服务创建独立的
ServiceAccount。 - 使用 Kubernetes RBAC(基于角色的访问控制)设置最小权限:只授予该 ServiceAccount 操作所需资源(如只能创建Pods、查看ConfigMaps)的权限。
- 为每个应用或微服务创建独立的
运行时可观测性:监控与告警
安全不是静态的,需要持续监控。
-
运行时威胁检测:
- 使用 Falco(开源,CNCF项目):监控容器和K8s的异常系统调用行为(如读取
/etc/shadow、创建新进程、绑定shell等)。 - 配置告警规则并集成到 PagerDuty、Slack 或 SIEM(安全信息和事件管理)系统。
- 使用 Falco(开源,CNCF项目):监控容器和K8s的异常系统调用行为(如读取
-
容器行为基线:
- 使用工具(如
Sysdig Secure、Aqua Security)建立正常行为基线,一旦偏离(如进程启动未注册的二进制文件)立即告警。
- 使用工具(如
-
合规性扫描:
- 定期使用工具(如
kube-bench)扫描 Kubernetes 集群配置,检查是否符合 CIS(互联网安全中心)基准。
- 定期使用工具(如
供应链安全:防投毒
- 镜像来源验证:使用
cosign确保镜像签名可信。 - 依赖扫描:扫描 Dockerfile 中的
FROM命令、RUN pip install等引入的依赖包,检查已知漏洞(CVE)和恶意软件。 - 软件物料清单(SBOM):生成并与镜像一起存储 SBOM(软件物料清单),便于追踪所有依赖。
实用工具推荐
- 扫描:
Trivy(扫描镜像、文件系统、Git仓库)、Clair - 签名:
cosign(使用公钥/私钥对或密钥管理服务进行镜像签名) - 运行时监控:
Falco(开源)、Sysdig Secure(商业) - 合规性:
kube-bench(检查K8s配置)、kube-hunter(寻找K8s攻击路径) - K8s策略:
OPA Gatekeeper(通用策略引擎)、Kyverno(K8s原生策略引擎)
一个安全的容器生命周期
- 构建时:最小化镜像、扫描漏洞、签名验证。
- 部署时:非root运行、只读文件系统、丢弃Capabilities、创建NetworkPolicy、配置Secrets。
- 运行时:启用Seccomp、资源限制、开启Falco监控。
- 基线:定期运行kube-bench。
坚决避免以下高危操作:
privileged: true- 挂载
/var/run/docker.sock - 镜像使用
latest标签且不扫描 - 在Pod中使用默认
ServiceAccount(通常拥有过大的权限) - 在生产环境中使用 root 用户运行容器
通过以上分层加固,可以将容器安全风险降到最低,建议先从“非Root用户”和“最小化镜像”这两个最基础的点开始,逐步完善。