How to enter the node shell via kubectl

This article was last updated on: February 7, 2024 pm

overview

Consider a scenario like this:

In the production environment, Node needs to log in through the bastion host, but kubectl can log in directly on the personal computer.

In this scenario, can I log in to Node in the K8S cluster through kubectl?

OK!
Essentially a privilege escape achieved by utilizing the weak isolation of containers (runC) (shared kernels, process isolation implemented by Cgruop, etc.).

If you use some commercial container platforms (such as openshift, rancher), etc., they may be installed by default through PSP scc or policy to block this layer of hidden dangers in advance.
But if it’s native Kubernetes, the following approach is often possible.

Principle overview

Let’s start with the essence, which is:

Containers (runC) are weak isolation

  • For virtual machines, virtual machines are isolated at the kernel level, and different virtual machines have different kernels, so the security is much higher, and it is very difficult to escape from the virtual machine to the physical machine where it is located.
  • However, containers (runC) are weak isolation, all containers on a machine share the same kernel, and the reason why they cannot see each other by default is through process-level isolation achieved by Cgroup, net namespace, etc.

So, without further restrictions on the permissions of the container, I can run a privileged container and go directly to the node where it is located.

Specific steps

Available for versions prior to K8S 1.25.

The steps are simple, which is to create the one mentioned aboveprivilegecontainer, pass nsenter command enters the node shell. An example yaml is as follows:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
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

direct kubectl apply -f node-shell.yaml to enter the node shell.

The above yaml, the key points are as follows:

Commands to enter the node shell:nsenter --target 1 --mount --uts --ipc --net --pid -- bash -lOn Linux, nsenter is a command-line tool that is used to access another namespace. such as nsenter -n -t 1 bash It is to enter the network namespace where the process with pid 1 is located.

And access to the node shell:

  • hostPID: true Share the PID of the host
  • hostNetwork: true The network that shares the host
  • privileged: true: The PSP permission policy is privileged, i.e. completely unlimited.

After entering the pod of the node shell, the effect is as follows:

node shell- 可以切换 shell

node shell- 可以查看所有的进程信息

node shell- 可以执行 root 权限的 systemctl

Utilities - Getting into the node shell is more convenient

Here are 2 recommended tools to make it easier to enter the node shell.

krew node-shell

Management tools can be managed through the kubectl plugin krew Install node-shell.

As follows:

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

Lens

Kubernetes graphical management tools - Lens There are also related features.

The specific usage is as follows:

Lens- 选择指定 node 进入 shell

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

summary

The above describes how to enter the node shell with root privileges via the kubectl command, which is very simple and actually works on most native Kubernetes.

This command actually makes some use of the unhardened configuration in security.

Finally, it is recommended that in addition to security hardening of the OS, Kubernetes should also be hardened in accordance with security best practices. (Typically, at least PSP and other policies are not set.) privileged, but set to Baseline or Restricted

Stay safe! 🚧🚧🚧

EOF