尧图网站设计 尧图网站设计YAOTU DESIGN
ARTICLE DETAIL

资讯详情

深耕网站设计与一线实操的经验洞察。

【Kubernetes从入门到精通】第55篇:SecurityContext——容器安全配置的“三件套“,别让你的容器“裸奔“成root

【Kubernetes从入门到精通】第55篇:SecurityContext——容器安全配置的“三件套“,别让你的容器“裸奔“成root 上一篇【第54篇】ServiceAccount——Pod的身份证下一篇【第56篇】NetworkPolicy安全实战——零信任网络架构的K8s实现摘要前面聊了谁能访问集群RBAC、“Pod的身份”ServiceAccount。但就算身份管得再严如果容器本身以root运行、还能改系统、还能写根文件系统——那一旦被入侵攻击者几乎能为所欲为。SecurityContext就是给容器降权的配置。它分两档Pod级对所有容器生效和Container级对单个容器生效优先级更高。核心三件事别用root跑、只给必要的Linux能力、根文件系统设为只读。这篇文章把SecurityContext的核心配置拆开讲再顺带提一下AppArmor/SELinux/seccomp这三个运行时保镖。一、Pod级 vs Container级1.1 两层配置【SecurityContext 的两层结构】 Pod.spec.securityContext (Pod级) ├── runAsUser: 1000 ├── runAsGroup: 3000 ├── fsGroup: 2000 └── 对所有容器生效(除非容器级覆盖) ├── container[0].securityContext (容器级) │ ├── runAsUser: 2000 ← 覆盖Pod级 │ └── privileged: false │ └── container[1].securityContext └── (没配 → 继承Pod级) 优先级容器级 Pod级 默认(通常root)要点Pod级和容器级可同时配容器级优先级更高。一般做法是Pod级设一个全局基线比如runAsNonRoot容器级针对特殊需求微调。两者都没配时容器默认以root跑——这是最危险的状态。二、核心三件套2.1 第一件runAsUser / runAsNonRoot别用rootapiVersion:v1kind:Podmetadata:name:non-root-podspec:securityContext:runAsNonRoot:true# 强制非root(UID≠0)runAsUser:1000# 指定运行用户runAsGroup:3000# 指定主组fsGroup:2000# 卷的属组(让Pod能读写挂载卷)containers:-name:appimage:nginx【为什么不用root这么重要】 容器里是root ≠ 宿主机是root (有namespace隔离) 但是 • root在容器里能干很多事(mount/改配置) • 如果容器有特权或capability泄漏 → root直接威胁宿主机 • 很多提权漏洞利用都依赖已经是root → 用非root跑即使被入侵破坏范围也小得多2.2 第二件capabilities最小化Linux能力Linux把root的特权拆成了几十个能力(capabilities)。默认容器会拿到一堆但多数用不上。securityContext:capabilities:drop:-ALL# 先全部丢弃add:-NET_BIND_SERVICE# 只加回需要的(比如绑80端口)# 常见需要的capability:# NET_BIND_SERVICE: 绑1024以下端口# CHOWN: 改文件属主# SYS_TIME: 改系统时间能力作用建议ALL所有能力❌ 默认应dropNET_BIND_SERVICE绑低端口✅ 常用SYS_ADMIN大量系统操作❌ 极危险几乎不给SYS_PTRACEptrace调试❌ 可被用来注入2.3 第三件readOnlyRootFilesystem只读根fssecurityContext:readOnlyRootFilesystem:true# 根文件系统只读# 那要写临时文件怎么办挂emptyDirvolumes:-name:tmpemptyDir:{}volumeMounts:-name:tmpmountPath:/tmp# 只能写这里要点只读根文件系统是防落地攻击的利器——攻击者即使拿到shell也没法往根fs写后门脚本、改二进制。需要写的地方用emptyDir/hostPath单独挂。三件套非root 最小capability 只读根fs是生产容器安全的最低基线。三、privileged——最危险的一个开关3.1 千万别随便开【privileged: true 有多可怕】 privileged: true 的容器 • 拥有宿主机的几乎所有capability • 能访问宿主机的所有设备 • 能mount宿主机文件系统 • 能逃逸到宿主机(只要有稍许配置失误) 典型用途只有网络插件(Calico/Cilium)、存储插件 (CSI node)、监控agent等系统组件才需要 ⚠️ 业务容器开privileged 给攻击者发宿主机万能钥匙# 错误示范(业务容器千万别这样)securityContext:privileged:true# ❌❌❌# 正确用具体capability代替securityContext:capabilities:add:[NET_ADMIN]# 只给需要的四、运行时保镖AppArmor / SELinux / seccomp4.1 三个更底层的防护【SecurityContext 之上的运行时三保镖】 ┌─────────────────────────────────────────────┐ │ seccomp (系统调用过滤) │ │ • 限制容器能调用哪些syscall │ │ • 挡掉危险的(如mount/ptrace/reboot) │ │ • K8s内置: RuntimeDefault / localhost / Unconfined│ ├─────────────────────────────────────────────┤ │ AppArmor (应用级MAC) │ │ • 更细的文件/网络访问控制 │ │ • 用profile定义能力白名单 │ ├─────────────────────────────────────────────┤ │ SELinux (强制访问控制) │ │ • 给进程和文件打label按label控制访问 │ │ • RHEL/CentOS系默认启用 │ └─────────────────────────────────────────────┘# seccomp 配置 (最常用挡syscall)apiVersion:v1kind:Podmetadata:name:seccomp-podannotations:seccomp.security.alpha.kubernetes.io/pod:runtime/default# runtime/default 用容器运行时的默认seccomp profile(挡掉危险syscall)spec:containers:-name:appimage:nginx# 进阶用自定义localhost profile# seccomp.security.alpha.kubernetes.io/pod: localhost/profile-name4.2 一张表总结SecurityContext核心字段字段推荐值作用runAsNonRoottrue禁止root运行runAsUser非0指定UIDprivilegedfalse禁止特权容器readOnlyRootFilesystemtrue根fs只读allowPrivilegeEscalationfalse禁止提权capabilities.dropALL丢弃所有capcapabilities.add按需加回必要capseccompProfileRuntimeDefault默认syscall过滤要点SecurityContext是容器自身的铠甲。最低基线四件套——runAsNonRoot: trueallowPrivilegeEscalation: falsereadOnlyRootFilesystem: truecapabilities.drop: [ALL]。seccomp用RuntimeDefault挡危险syscall性价比极高。这些配合PSA的restricted标准能自动强制。本篇小结SecurityContext是容器的降权铠甲分Pod级和Container级两档。核心三件事别用rootrunAsNonRoot、最小capabilitydrop ALL再加需、根fs只读。privileged开关是宿主机逃逸的最大隐患业务容器绝对别开。再往深一层有seccomp/AppArmor/SELinux三个运行时保镖seccomp的RuntimeDefault最易用、性价比最高。这些和PSA的restricted标准配合能自动把裸奔容器挡在集群门外。下一篇我们把NetworkPolicy真正用到安全实战里——搭建零信任网络。上一篇【第54篇】ServiceAccount——Pod的身份证下一篇【第56篇】NetworkPolicy安全实战——零信任网络架构的K8s实现
返回列表