恶意Pod检测工具

PSS:[Pod安全标准(Pod Security Standards)](Pod安全标准(Pod Security Standards))

1. 创建项目 getNoPSS

mkdir getNoPSS ;cd getNoPSS
go mod init getNoPSS
go install github.com/spf13/cobra-cli@latest

2. 初始化 cobra 项目

cobra-cli.exe init

3. 新增子命令 allNoPSS

C:\tool\bg\Go\bin\bin\cobra-cli.exe add allNoPSS
root.go 

添加全局参数

4. 新增 pkg 包并在其中新增 pss.go

pkg 包新增connection.go
用于与 Kubernetes 集群建立连接并获取所有 Pod 信息。

5. pss.go 新增 Finding 结构体

allNoPSS.go 新增 Run: func

6. pss.go 新增 Hostpid 函数

该函数检索出 集群中配置为使用主机 PID 的 Pod 列表。

7. 部署远程集群环境并同步项目代码

创建不安全的 pod
导入相关镜像,kind load docker-image --name demo alpine:latest,下面命令可能还是会创建失败,
需要等待一会让集群重试几次。

# Pod 1
kubectl run unsafe-pod-1 --image=docker.io/library/alpine:latest --overrides='
{
  "apiVersion": "v1",
  "kind": "Pod",
  "metadata": {
    "name": "unsafe-pod-1"
  },
  "spec": {
    "hostPID": true,
    "hostNetwork": true,
    "hostIPC": true,
    "containers": [
      {
        "name": "alpine-container",
        "image": "docker.io/library/alpine:latest",
        "securityContext": {
          "seccompProfile": {
            "type": "RuntimeDefault"
          },
          "runAsUser": 0
        },
        "command": ["sleep", "infinity"]
      }
    ]
  }
}
'

# Pod 2
kubectl run unsafe-pod-2 --image=docker.io/library/alpine:latest --overrides='
{
  "apiVersion": "v1",
  "kind": "Pod",
  "metadata": {
    "name": "unsafe-pod-2"
  },
  "spec": {
    "containers": [
      {
        "name": "alpine-container",
        "image": "docker.io/library/alpine:latest",
        "securityContext": {
          "seccompProfile": {
            "type": "RuntimeDefault"
          },
          "runAsUser": 0
        },
        "ports": [
          {
            "containerPort": 80,
            "hostPort": 80
          }
        ],
        "volumeMounts": [
          {
            "name": "hostpath-volume",
            "mountPath": "/hostpath"
          }
        ],
        "command": ["sleep", "infinity"]
      }
    ],
    "volumes": [
      {
        "name": "hostpath-volume",
        "hostPath": {
          "path": "/some/host/path"
        }
      }
    ]
  }
}
'

# Pod 4
kubectl run unsafe-pod-4 --image=docker.io/library/alpine:latest --overrides='
{
  "apiVersion": "v1",
  "kind": "Pod",
  "metadata": {
    "name": "unsafe-pod-4"
  },
  "spec": {
    "containers": [
      {
        "name": "alpine-container",
        "image": "docker.io/library/alpine:latest",
        "securityContext": {
          "privileged": true,
          "allowPrivilegeEscalation": true,
          "seccompProfile": {
            "type": "RuntimeDefault"
          },
          "runAsUser": 0
        },
        "command": ["sleep", "infinity"]
      }
    ]
  }
}
'

# Pod 5
kubectl run unsafe-pod-5 --image=docker.io/library/alpine:latest --overrides='
{
  "apiVersion": "v1",
  "kind": "Pod",
  "metadata": {
    "name": "unsafe-pod-5"
  },
  "spec": {
    "containers": [
      {
        "name": "alpine-container",
        "image": "docker.io/library/alpine:latest",
        "securityContext": {
          "seccompProfile": {
            "type": "RuntimeDefault"
          },
          "runAsUser": 0,
          "sysctls": [
            {
              "name": "kernel.panic",
              "value": "1"
            }
          ]
        },
        "command": ["sleep", "infinity"]
      }
    ]
  }
}
'

8. allNoPSS.go 添加 Run: func

调用 Hostpid 函数

9. 远程运行调试

dlv debug --headless --listen=:2345 --api-version=2 --accept-multiclient --

10. pkg 包新增 reporting.go 优化结果输出

11. pss.go 新增 Hostnet 函数

该函数检索出 集群中配置为使用主机网络的 Pod 列表。
排除 kube-system 命名空间中的,
dlv debug --headless --listen=:2345 --api-version=2 --accept-multiclient -- allNoPSS -e kube-system

其他检查项同理

12. 检查的原理

下面提到的检查每个 Pod 中的所有容器,包括主容器、Init 容器和临时容器。

模块 说明 原理
unmaskedProc 检索使用"Unmasked" proc mount的容器 遍历Pod的所有容器,检查是否具有安全上下文配置,并且是否设置了ProcMount选项为"Unmasked"
sysctls 检索配置了不在安全列表中的sysctl参数的Pod 检查每个Pod是否具有安全上下文配置,并且是否设置了Sysctls,如果参数不属于安全列表则视为不安全
hostPidCont 检索使用主机PID的Pod 检查每个Pod是否设置了HostPID
hostNetCont 检索使用主机网络的Pod 检查每个Pod是否设置了HostNetwork
hostIpcCont 检索使用主机IPC的Pod 检查每个Pod是否设置了HostIPC
hostPorts 检索使用主机端口的容器 检查每个Pod中的所有容器是否设置了主机端口
hostPath 检索挂载主机路径卷的Pod 检查每个Pod是否设置了HostPath
hostProcessCont 检索使用hostprocess权限运行的容器 检查Windows容器的安全上下文是否设置了HostProcess选项
privCont 检索特权容器 检查容器安全上下文是否设置了Privileged选项为true
allowPrivEscCont 检索允许权限提升的容器 检查容器安全上下文是否设置了AllowPrivilegeEscalation选项为nil或true
capAdded 检索具有比默认配置更高权限的容器 检查容器安全上下文是否设置了Capabilities.Add选项
capDropped 检索通过降低权限来提高安全性的容器 检查容器安全上下文是否设置了Capabilities.Drop选项
seccomp 检索未启用Seccomp的容器 检查Pod/容器的SeccompProfile是否为nil或"Unconfined"
apparmor 检索未启用AppArmor的Pod 检查Annotations中是否包含container.apparmor.security.beta.kubernetes.io且值为"unconfined"