如何通过终端快速访问 Kubernetes 节点 Shell 的 Root 环境 (无需 SSH 权限 )

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

概述

这种场景下,我想要通过 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[1] 安装 node-shell.

如下:

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

Lens

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

具体使用方法如下:

Lens-选择指定 node 进入 shell

Lens-实际上也是启动个特权 pod,可以执行 root 命令

总结

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

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

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

注意安全!🚧🚧🚧

责任编辑:庞桂玉 来源: 奇妙的Linux世界
相关推荐

2023-08-03 07:35:10

kubernetes云原生

2021-07-16 09:51:21

kubernetes环境容器

2013-11-20 10:56:07

2010-04-27 14:32:31

2009-07-20 19:53:23

SSHLinuxMac

2022-08-21 16:50:36

Kubeadm​Kubernetes

2022-04-15 15:56:30

云原生容器

2020-04-29 09:00:03

API终端应用环境

2021-01-27 15:17:38

漏洞网络安全程序员

2018-06-12 10:12:12

2015-05-22 08:59:38

2019-07-13 14:21:04

LinuxShell命令

2011-07-14 09:56:13

RHEL红帽PuTTY

2017-12-04 10:46:23

2020-10-08 14:29:57

Kubernetes容器开发

2022-03-11 13:28:54

SSHLinux命令

2018-06-19 08:12:25

2018-06-22 10:18:52

2019-11-21 09:24:50

SSH服务器工具

2013-11-01 11:32:49

点赞
收藏

51CTO技术栈公众号