容器安全基础:从镜像到运行时的全链路防护
容器安全,说白了就是保护你的容器从生到死的全过程。我做了这么多年金融安全,见过太多团队只关注应用层安全,结果容器层被人捅成筛子。今天咱们就把这块补上。
核心观点:容器安全不是单点防护,而是从镜像构建、仓库存储、运行时监控到网络隔离的完整链条。任何一个环节出问题,整个集群都可能沦陷。
一、容器运行时安全
运行时安全,就是容器跑起来之后怎么防。我遇到过最典型的案例:某支付公司容器被植入挖矿程序,CPU跑满100%才发现。嗯,这就是运行时监控没到位。
1.1 运行时威胁模型
容器运行时面临的主要威胁包括:
- 进程逃逸:利用内核漏洞突破容器隔离
- 文件系统篡改:恶意修改容器内关键文件
- 网络攻击:容器间横向移动、端口扫描
- 资源滥用:挖矿、DDoS等消耗型攻击
1.2 运行时防护手段
我个人习惯用这几招:
- Seccomp:限制容器能调用的系统调用。我曾经见过一个容器被植入反向shell,就是因为没限制execve调用
- AppArmor/SELinux:强制访问控制,给容器戴上紧箍咒
- Capabilities 裁剪:去掉不需要的Linux能力,比如NET_RAW、SYS_ADMIN
- 只读根文件系统:容器启动后禁止写操作,防篡改
我的经验:运行时安全配置要遵循最小权限原则。你想想看,一个Web容器需要SYS_ADMIN能力吗?不需要。去掉它,攻击面就少了一大块。
二、镜像安全扫描
镜像安全,是容器安全的第一道防线。我经常跟团队说:别把漏洞带进生产环境。
2.1 镜像扫描的核心要素
| 扫描维度 | 检查内容 | 常见问题 |
|---|---|---|
| 操作系统层 | 基础镜像漏洞、过期包 | Alpine、Ubuntu等基础镜像未更新 |
| 应用依赖层 | 第三方库漏洞(npm、pip、maven) | Log4j、lodash等经典漏洞 |
| 配置层 | 敏感信息泄露、错误权限 | 硬编码密码、SSH密钥 |
| 文件层 | 恶意文件、后门程序 | 挖矿脚本、反弹shell |
2.2 扫描工具选型
我建议用这些工具:
- Trivy:轻量、全面,适合CI/CD集成。我项目里一直用它
- Clair:CoreOS出品,适合大规模部署
- Anchore:策略引擎强大,能自定义合规规则
- Docker Scout:Docker官方工具,集成度高
避坑指南:我曾经遇到过镜像扫描通过,但上线后依然被攻击的情况。为什么?因为扫描的是基础镜像,但运行时拉取的是latest标签,内容已经变了。记住:扫描和运行必须用同一个镜像摘要(digest)。
三、容器逃逸防护
容器逃逸,是容器安全里最要命的问题。说白了,就是攻击者从容器里跑到了宿主机上。一旦发生,整个集群都危险了。
3.1 常见逃逸路径
- 内核漏洞逃逸:利用Dirty Cow、CVE-2022-0847等漏洞
- 配置不当逃逸:挂载了宿主机敏感目录(/proc、/sys、/var/run/docker.sock)
- Capabilities滥用:给了SYS_ADMIN、SYS_PTRACE等危险能力
- 特权容器:--privileged参数直接打开所有权限
3.2 防护策略
我总结了一套防护三板斧:
- 内核加固:升级内核、启用内核安全模块(LSM)
- 配置检查:禁止挂载宿主机敏感目录,特别是docker.sock
- 运行时监控:使用Falco等工具检测异常系统调用
关键点:容器逃逸防护的核心是纵深防御。不要指望单一手段能防住所有攻击。我见过最成功的案例是:即使攻击者突破了第一层,也被后续的AppArmor和Seccomp拦住了。
四、Kubernetes Pod安全策略(PSP/PSS)
Pod安全策略,是K8s里控制Pod权限的利器。不过要注意,PSP在1.25版本后被废弃了,现在推荐用PSS(Pod Security Standards)。
4.1 PSP vs PSS
| 特性 | PSP(旧) | PSS(新) |
|---|---|---|
| 实现方式 | 集群级资源对象 | 内置准入控制器 |
| 配置复杂度 | 高,需要写大量RBAC | 低,通过标签控制 |
| 策略级别 | 自定义策略 | Privileged/Baseline/Restricted三级 |
| 推荐度 | 已废弃 | 强烈推荐 |
4.2 PSS实战配置
我个人习惯这样配置:
# 为命名空间设置PSS策略
apiVersion: v1
kind: Namespace
metadata:
name: production
labels:
pod-security.kubernetes.io/enforce: restricted
pod-security.kubernetes.io/audit: baseline
pod-security.kubernetes.io/warn: baseline
---
# 验证Pod是否符合策略
apiVersion: v1
kind: Pod
metadata:
name: test-pod
spec:
containers:
- name: app
image: nginx
securityContext:
runAsNonRoot: true
seccompProfile:
type: RuntimeDefault
capabilities:
drop: ["ALL"]
我的建议:生产环境用restricted级别,开发环境用baseline。privileged级别除非有特殊需求,否则别用。我曾经见过一个团队所有命名空间都用privileged,结果被攻破后整个集群沦陷。
五、容器网络策略(NetworkPolicy)
网络策略,是容器间通信的防火墙。你想想看,如果没有网络策略,任何一个Pod都能访问其他Pod,那跟裸奔有什么区别?
5.1 NetworkPolicy核心概念
- Pod选择器:指定策略作用于哪些Pod
- 入站规则(Ingress):控制谁可以访问目标Pod
- 出站规则(Egress):控制目标Pod可以访问谁
- 策略类型:允许/拒绝,默认拒绝所有
5.2 实战配置示例
# 拒绝所有入站流量,只允许前端访问后端
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: backend-policy
namespace: production
spec:
podSelector:
matchLabels:
app: backend
policyTypes:
- Ingress
ingress:
- from:
- podSelector:
matchLabels:
app: frontend
ports:
- protocol: TCP
port: 8080
5.3 网络策略最佳实践
我总结了几条铁律:
- 默认拒绝所有:先拒绝,再按需开放
- 最小化开放端口:只开放业务需要的端口
- 命名空间隔离:不同环境(dev/staging/prod)之间禁止通信
- 监控网络流量:使用Cilium、Calico等工具可视化网络
避坑指南:我曾经遇到过配置了NetworkPolicy但没生效的情况。排查了半天,发现是CNI插件不支持。记住:NetworkPolicy需要CNI插件支持,比如Calico、Cilium、Weave等。Flannel默认不支持。
知识体系总览
下面这张图,是我梳理的容器安全知识体系。你可以把它当作一个检查清单,看看自己覆盖了哪些环节。
这张图展示了容器安全的五个核心环节。从镜像安全开始,到运行时防护、逃逸防御、Pod策略、网络隔离,最后是监控响应。每一层都是防线,缺一不可。
总结一句话:容器安全不是某个工具能搞定的,而是一套体系。从镜像构建到运行时监控,从Pod配置到网络隔离,每个环节都要做到位。我见过太多团队只关注其中一两项,结果被攻击者从薄弱环节突破。
最后分享一个习惯:我每次上线新服务,都会对照这张图逐项检查。镜像扫了吗?运行时加固了吗?网络策略配了吗?Pod安全级别设了吗?监控告警接了吗?全部通过才敢上线。