美文网首页
如何通过 kubectl 进入 node shell

如何通过 kubectl 进入 node shell

作者: 东风微鸣 | 来源:发表于2022-11-26 07:34 被阅读0次

    概述

    假设这样一个场景:

    生产环境中,Node 都需要通过堡垒机登录,但是 kubectl 是可以直接在个人电脑上登录的。

    这种场景下,我想要通过 kubectl 登录到 K8S 集群里的 Node,可以实现吗?

    可以的!
    本质上是利用容器(runC)的弱隔离(共享内核,Cgruop 等实现进程隔离)实现的权限逃逸。

    如果贵司使用的一些商业容器平台(如:openshift,rancher)等,可能默认安装时就会通过 PSP scc 或 policy 等预先屏蔽掉这层隐患。
    但是如果是原生的 Kubernetes, 往往下面的办法是可行的。

    原理概述

    先说本质,本质上就是:

    容器(runC)是弱隔离

    • 对于虚拟机来说,虚拟机是通过内核(kernel)级别的隔离,不同的虚拟机有不同的内核,所以安全性要高很多,从虚拟机逃逸到其所在的物理机上是非常困难的。
    • 但是,容器(runC)是弱隔离,一台机器上的所有容器都共享同一个内核,他们之所以默认互相看不见,是通过 Cgroup、net namespace 等实现的进程级别的隔离。

    那么,加入你没有对容器的权限做进一步的限制,我是可以通过运行一个特权容器,直接进入到其所在的 node 上的。

    具体步骤

    适用于 K8S 1.25 之前的版本。

    步骤很简单,就是创建上文说的这么一个特权容器,通过 nsenter command 进入 node shell。示例 yaml 如下:

    apiVersion: v1
    kind: Pod
    metadata:
      labels:
        run: nsenter-v0l86q
      name: nsenter-v0l86q
      namespace: default
    spec:
      containers:
      - command:
        - nsenter
        - --target
        - "1"
        - --mount
        - --uts
        - --ipc
        - --net
        - --pid
        - --
        - bash
        - -l
        image: docker.io/library/alpine
        imagePullPolicy: Always
        name: nsenter
        securityContext:
          privileged: true
        stdin: true
        stdinOnce: true
        tty: true
      hostNetwork: true
      hostPID: true
      restartPolicy: Never
      tolerations:
      - key: CriticalAddonsOnly
        operator: Exists
      - effect: NoExecute
        operator: Exists
    

    直接 kubectl apply -f node-shell.yaml 即可进入 node shell。

    上面的 yaml,关键有这么几点:

    进入 node shell 的命令:nsenter --target 1 --mount --uts --ipc --net --pid -- bash -l,在 Linux 系统里, nsenter 是一个命令行工具,用于进入到另一个 namespace 。 譬如, nsenter -n -t 1 bash 就是进入到 pid 为 1 的进程所在的网络 namespace 里。

    以及进入 node shell 的权限:

    • hostPID: true 共享 host 的 pid
    • hostNetwork: true 共享 host 的网络
    • privileged: true: PSP 权限策略是 privileged, 即完全无限制。

    进入 node shell 的 pod 后, 效果如下:

    node shell-可以切换 shell node shell-可以查看所有的进程信息 node shell-可以执行 root 权限的 systemctl

    实用工具 - 进入 node shell 更方便

    这里推荐 2 个工具,可以更方便地进入 node shell。

    krew node-shell

    可以通过 kubectl 插件管理工具 krew 安装 node-shell.

    如下:

    # 安装工具
    kubectl krew install node-shell
    # 进入 node shell
    Kubectl node-shell <node-name>
    

    Lens

    Kubernetes 图形化管理工具 - Lens 也有相关功能。

    具体使用方法如下:

    Lens-选择指定 node 进入 shell Lens-实际上也是启动个特权 pod,可以执行 root 命令

    总结

    上文介绍了通过 kubectl 命令以 root 权限进入 node shell 的方法,非常简单,实际上在大多数的原生 Kubernetes 上都生效。

    这个命令实际上是一定程度上利用了安全上的未加固配置。

    这里最后还是建议大家除了对 OS 进行安全加固,对 Kubernetes 也要按照安全最佳实践进行安全加固。(典型的就是起码 PSP 等 policy 不要设置为 privileged, 而是设置为 BaselineRestricted

    注意安全!🚧🚧🚧

    EOF

    本文由东风微鸣技术博客 EWhisper.cn 编写!

    相关文章

      网友评论

          本文标题:如何通过 kubectl 进入 node shell

          本文链接:https://www.haomeiwen.com/subject/nxoqfdtx.html