Docker安全:从审计到AI保护的6个实用实验
Docker容器共享主机内核。单个配置错误的容器可能暴露敏感数据、提供对主机的root访问权限或危及整个基础设施。本指南提供六个在Linux、macOS和Windows上运行的实用实验。
示例使用开源工具,并演示易受攻击和安全配置。每个实验都是动手可运行的。所有代码和详细说明可在GitHub上获取:https://github.com/opscart/docker-security-practical-guide
本文涵盖六个基本安全实践:
- 使用Docker Bench Security进行配置审计
- 使用功能和只读文件系统加固容器
- 使用Trivy进行漏洞扫描和策略执行
- 镜像签名以保障供应链安全
- 用于系统调用过滤的Seccomp配置文件
- AI/ML工作负载安全
实验01:使用Docker Bench进行安全审计
学习内容
运行全面的安全审计,在错误配置成为漏洞之前识别它们。Docker Bench Security检查主机配置、守护程序设置、文件权限、容器配置和网络设置。
动手练习
克隆仓库并导航到实验01:
|
|
步骤1:运行初始审计
|
|
Docker Bench在七个CIS基准部分运行105项检查。输出显示PASS(合规)、WARN(需要注意)和INFO(手动审查)结果。
步骤2:部署易受攻击的应用程序 部署具有故意安全问题的容器:
|
|
这会创建具有多个问题的容器:
- 启用特权模式
- 共享主机网络命名空间
- Docker套接字安装在容器内
- 环境变量中的硬编码凭据
- 授予所有Linux功能
步骤3:再次审计
|
|
分数显著下降。出现新的WARN发现,涉及特权容器、暴露的Docker套接字和禁用的安全配置文件。
理解结果
输出格式:
|
|
三个类别:
- PASS:满足CIS基准要求
- WARN:需要处理的安全问题
- INFO:需要手动验证
常见问题和修复
1. 问题:特权容器
问题:
|
|
修复:
|
|
2. 问题:Docker套接字挂载
问题:
|
|
这授予容器对Docker守护程序的完全控制——相当于主机上的root访问权限。
修复:完全移除套接字挂载。如果需要Docker API访问,请改用适当的身份验证。
步骤4:清理
|
|
实验02:安全容器配置
目标
比较不安全与安全的容器配置。了解Linux功能的工作原理以及为什么只读文件系统很重要。
理解Linux功能
Linux将root特权划分为称为功能的独立单元。与其以具有完全特权的root身份运行容器,不如仅授予所需的特定功能。
常见功能:
CAP_NET_BIND_SERVICE– 绑定到1024以下的端口CAP_CHOWN– 更改文件所有权CAP_SETUID/SETGID– 更改用户/组ID
默认Docker行为授予功能子集。安全方法:删除所有功能,然后仅添加应用程序所需的功能。
动手练习
|
|
步骤1:部署不安全容器
|
|
部署具有所有功能、读写文件系统、以root身份运行且无安全限制的nginx。
步骤2:部署安全容器
|
|
部署具有最小功能、只读根文件系统、用于所需写入的tmpfs挂载和启用no-new-privileges的nginx。
步骤3:比较安全态势
|
|
输出显示:
|
|
十六进制值表示启用的功能。不安全容器具有所有功能(ffffffffff)。安全容器仅具有四个特定功能(4c1)。这种减少显著限制了攻击者在入侵后的能力。
步骤4:测试安全控制
|
|
测试软件包安装、文件系统写入和特权升级。安全容器在保持功能的同时阻止软件包安装和根文件系统写入。
配置详情
不安全容器命令:
|
|
安全容器命令:
|
|
只读文件系统防止恶意软件安装、配置篡改和二进制修改。tmpfs在需要的地方提供内存支持的写空间,带有noexec和nosuid标志防止二进制执行。
实验03:漏洞扫描和策略执行
目标
扫描容器镜像以查找已知漏洞,并在部署前强制执行安全策略。
理解漏洞扫描
容器镜像包含操作系统软件包和应用程序依赖项。每个组件都可能具有CVE跟踪的漏洞。基础镜像通常包含数百个漏洞。依赖项很快过时。某些漏洞具有活跃的利用。
在开发期间、CI/CD流水线中、部署前以及定期对运行中的镜像进行扫描。
使用的工具
Trivy:开源漏洞扫描器。扫描操作系统软件包、应用程序依赖项、基础设施即代码文件和Kubernetes配置。快速扫描(不到1分钟)且具有全面的漏洞数据库。
Open Policy Agent (OPA):用于强制执行安全规则的策略引擎。检查容器配置、运行时设置和合规性要求。
动手练习
|
|
步骤1:安装Trivy
macOS:
|
|
Linux:
|
|
步骤2:扫描容器镜像
|
|
输出显示库名称、CVE标识符、严重性级别(CRITICAL/HIGH/MEDIUM/LOW)以及当前与修复版本。
步骤3:应用安全策略
安装OPA:
|
|
应用策略:
|
|
OPA检查特权模式、root用户、缺少健康检查和过多暴露端口。policy.rego文件定义拒绝规则(阻止部署)和警告规则(标记问题)。
步骤4:测试策略执行
部署特权容器:
|
|
策略检测到特权模式违规。清理:
|
|
CI/CD集成
GitLab CI示例:
|
|
如果找到严重或高度漏洞,流水线失败。
修复过程
找到漏洞时:
- 首先关注CRITICAL和HIGH严重性
- 检查是否有可用的修复
- 将基础镜像更新到最新的修补版本
- 使用包管理器更新依赖项
- 使用更新重建镜像
- 重新扫描以验证解决
示例:
|
|
实验04:镜像签名和验证
为什么镜像签名很重要
容器镜像在传输过程中可能被篡改,被攻击者在注册表中替换,或被受损的构建系统修改。镜像签名提供来源的加密证明并检测未经授权的修改。
针对容器注册表的供应链攻击有所增加。镜像签名现在是许多合规框架的要求。没有签名,您无法验证生产中运行的镜像正是您的构建系统创建的。
理解镜像签名
数字签名使用非对称密码学:
- 私钥签名镜像
- 公钥验证签名
- 任何修改都会破坏签名
- 只有密钥持有者可以签名
本实验使用来自Sigstore项目的Cosign。Cosign支持传统的基于密钥的签名和使用OIDC提供商的无密钥签名。
动手练习
|
|
步骤1:安装Cosign
macOS:
|
|
Linux:
|
|
步骤2:设置签名基础设施
|
|
在端口5001上启动本地注册表并生成签名密钥(cosign.key和cosign.pub)。
步骤3:构建和签名镜像
|
|
脚本构建示例镜像,将其推送到本地注册表,并使用Cosign签名。系统将提示您输入密码以保护私钥。
步骤4:验证签名
|
|
验证确认:
- 镜像来自预期来源
- 自签名以来无修改
- 签名与公钥匹配
步骤5:测试未签名镜像 尝试验证未签名镜像:
|
|
返回"Error: no signatures found",阻止使用不受信任的镜像。
策略执行
在生产中,使用Kubernetes准入控制器或注册表策略强制执行签名镜像。未签名镜像应在部署前被拒绝。
Kubernetes示例:
|
|
实验05:Seccomp配置文件
理解Seccomp
安全计算模式(seccomp)是Linux内核功能,用于过滤系统调用。应用程序进行系统调用以请求内核服务。限制容器可以进行哪些系统调用可以减少攻击面。
Linux有300多个系统调用。大多数应用程序需要少于100个。阻止不必要的系统调用可以防止整个类别的攻击。
工作原理
当容器尝试系统调用时:
- 内核检查seccomp配置文件
- 如果允许:调用执行
- 如果阻止:操作失败或进程终止
Docker的默认配置文件阻止约44个危险系统调用,同时允许常见操作。
动手练习
|
|
步骤1:测试默认配置文件
|
|
默认配置文件允许文件操作、网络操作和基本进程操作。它阻止重新启动、挂载和系统时间修改。
步骤2:测试限制性配置文件
|
|
限制性配置文件仅允许所需的最少系统调用。它阻止套接字创建、进程分叉和文件权限更改。此配置文件适用于非常受限的环境。
步骤3:生成应用程序特定配置文件
|
|
为nginx创建具有适当系统调用的配置文件。配置文件阻止危险的调用,如挂载和重新启动,同时允许nginx需要的网络和文件操作。
配置文件结构
基本seccomp配置文件格式:
|
|
关键元素:
- defaultAction:未列出的系统调用发生什么
- architectures:支持的CPU架构
- syscalls:显式允许的系统调用
- action:SCMP_ACT_ALLOW(允许)或SCMP_ACT_ERRNO(阻止)
应用配置文件
Docker运行:
|
|
Docker Compose:
|
|
攻击预防
示例:攻击者在容器中获得shell访问权限。
没有seccomp:
|
|
有seccomp:
|
|
即使具有shell访问权限,攻击者也无法执行危险操作。
实验06:AI模型安全
为什么AI模型安全很重要
机器学习容器具有独特的安全要求。模型消耗大量CPU/GPU/内存资源。推理输入可能包含敏感数据。模型权重代表知识产权。API暴露攻击面,用于对抗性输入和模型提取。
AI特定威胁
- 模型提取:攻击者重复查询模型以重新创建它,而无需训练数据访问。
- 对抗性攻击:精心制作的输入导致不正确预测。
- 资源耗尽:大型批处理请求消耗所有可用资源。
- 数据中毒:恶意训练数据损坏模型。
动手练习
|
|
步骤1:构建ML容器
|
|
构建具有Python ML框架、推理服务器和示例模型的容器。使用多阶段构建、非root用户和最小依赖项。
步骤2:使用安全控制部署
|
|
部署具有以下功能的容器:
- 内存限制:4GB
- CPU限制:2核心
- 只读文件系统
- 用于临时文件的tmpfs
- 启用no-new-privileges
步骤3:测试模型推理
|
|
返回带有预测、置信度和元数据的JSON。
步骤4:压力测试
|
|
发送并发请求以验证资源限制是否正确工作。容器在定义的限制内处理请求而不会崩溃。
安全配置
部署命令:
|
|
资源限制防止耗尽攻击。只读文件系统防止篡改。进程限制防止fork炸弹。
输入验证
防止恶意输入:
|
|
验证防止过大的输入和可能导致问题的极端值。
速率限制
防止模型提取和资源耗尽:
|
|
限制每个客户端的请求以防止滥用。
实施路线图
按顺序开始实施这些实践:
- 第1-2周:在所有系统上运行Docker Bench Security。处理WARN发现。添加到CI/CD流水线。
- 第3-4周:实施容器加固。删除功能。尽可能启用只读文件系统。
- 第5-6周:设置漏洞扫描。将Trivy集成到构建过程中。创建OPA策略。
- 第7-8周:实施镜像签名。在CI/CD中设置Cosign。在部署时配置验证。
- 第9-10周:创建和测试seccomp配置文件。从默认配置文件开始。为关键服务创建自定义配置文件。
- 第11-12周:如果运行ML工作负载,实施资源限制和输入验证。添加监控和速率限制。
- 持续进行:定期安全审计。更新依赖项。监控新漏洞。优化安全策略。
开始使用
完整实验说明和工作代码:https://github.com/opscart/docker-security-practical-guide
仓库包括:
- 所有六个实验练习与脚本
- 配置示例(易受攻击和安全)
- 故障排除指南
- 额外安全资源
按顺序完成实验以获得全面理解。每个实验都建立在先前概念之上。所有实验在Linux、macOS和Windows上工作。
关键要点
- 实验01:每周运行Docker Bench。处理所有WARN发现。集成到CI/CD。
- 实验02:默认删除所有功能。使用只读文件系统。为所需写入添加tmpfs。
- 实验03:在部署前扫描镜像。使用OPA强制执行策略。关注CRITICAL和HIGH漏洞。
- 实验04:签名所有生产镜像。安全存储密钥。在部署时强制执行验证。
- 实验05:从Docker的默认seccomp配置文件开始。为敏感工作负载创建自定义配置文件。彻底测试。
- 实验06:为ML容器设置资源限制。验证输入。实施速率限制和监控。
结论
Docker安全需要跨多个层级的关注。本指南提供六个实用实验,涵盖配置审计、容器加固、漏洞扫描、镜像签名、seccomp配置文件和AI模型安全。
安全不是一次性的实施。定期审计、更新和监控至关重要。本系列中的实践为生产Docker部署提供了坚实的基础。
立即开始实施这些技术:https://github.com/opscart/docker-security-practical-guide