Node-shell ?
k8s 컨트롤 노드를 통해서 워크 노드에 root 권한으로 접근시킬 수 있는 툴입니다. kubectl krew 확장 도구로 설치가 간단하며, 워크 노드 서버 접근에 자주 사용되는 툴입니다.
다만, k8s api-server만 접근이 가능하게 되면 워크 노드도 접근이 가능하기에 예상치 못한 보안 이슈를 가져올 수 있습니다. 이번 장에서는 해당 툴의 원리를 확인하고 발생할 수 있는 보안 이슈를 확인하겠습니다.
원리 이해
구성 원리는 깃 프로젝트 쉘 파일 kubectl-node_shell 에서 확인할 수 있습니다.
핵심 원리는 nsenter 명령을 통한 워크 노드의 네임스페이스(프로세스, 네트워크, 마운트 등) 공유입니다.
kubectl run --image "docker.io/library/alpine" \
--restart=Never \
--overrides='{
"spec": {
"nodeName": "nodeName", # 입력 노드 변수 이름
"hostPID": true,
"hostNetwork": true,
"containers": [
{
"securityContext": {"privileged": true},
"image": "docker.io/library/alpine",
"name": "nsenter",
"stdin": true,
"stdinOnce": true,
"tty": true,
"command": ["nsenter", "--target", "1", "--mount", "--uts", "--ipc", "--net", "--pid", "--", "bash", "-l"],
"resources": {},
"volumeMounts": []
}
],
"tolerations": [
{ "key": "CriticalAddonsOnly", "operator": "Exists" },
{ "effect": "NoExecute", "operator": "Exists" }
],
"volumes": []
}
}' \
--labels="app=node-shell" \
--pod-running-timeout="1m" \
-t \
-i "nsenter-abc123"
입력 노드 변수에 파드를 배치합니다.
파드는 "privileged": true 옵션을 통해 root 권한으로 접근합니다. 그 후 nsenter 를 통해 프로세스 ID 1에 해당하는 네임스페이스를 공유받습니다.
프로세스 1은 리눅스 시스템에서 일반적으로 init 프로세스로 결국 노드의 네임스페이스를 공유받게 됩니다.
nsenter --target 1 --mount --uts --ipc --net --pid -- bash -l
eksctl를 통해 EKS 클러스터를 생성하고 프로세스를 확인하겠습니다.
eks 클러스터를 구성하고 node-shell 설치를 진행하겠습니다.
# eks.yaml
---
apiVersion: eksctl.io/v1alpha5
kind: ClusterConfig
metadata:
name: cluster-1
region: ap-northeast-2
nodeGroups:
- name: ng-1
instanceType: t3.medium
desiredCapacity: 1
# 클러스터 구성 (약 15분 소요)
eksctl create cluster -f eks.yaml
# node-shell 설치
kubectl krew index add kvaps https://github.com/kvaps/krew-index
kubectl krew install kvaps/node-shell
export PATH="${KREW_ROOT:-$HOME/.krew}/bin:$PATH"
# node-shell 접속
kubectl node-shell
파드 안에서 프로세스를 확인하면 다음과 같습니다.
위와 같이 파드의 프로세스와 노드의 프로세스가 동일한 것으로 확인됩니다.
Node-shell 비활성화 방법
원치않은 노드 접근으로 인해 보안 이슈가 생길 수 있기에 해당 툴을 비활성화할 수 있도록 설정하겠습니다.
핵심은 파드 생성시에 "privileged": true 옵션을 비활성화하는 것입니다.
Pod Security Admission 설정 방법
Pod Security Admission 은 쿠버네티스 버전 1.25 이상에서 제공하는 기능으로 쿠버네티스에서 Pod에 대한 보안 정책을 적용하는 메커니즘입니다. 네임스페이스에 아래 레이블을 추가하여 Pod 보안 정책을 적용할 수 있습니다.
해당 옵션을 통해 "privileged": true 비활성화하겠습니다.
kubectl label namespace default pod-security.kubernetes.io/enforce=restricted
위 명령은 default 네임스페이스에 대해 restricted 보안 프로파일을 적용합니다.
restricted 프로파일에서는 다음과 같은 보안 정책이 적용됩니다:
- privileged: true 금지
- runAsNonRoot 사용자로만 실행 허용
- 호스트 네트워크, 호스트 PID, 호스트 IPC 사용 금지
- 호스트 경로 마운트 제한
네임스페이스 default 에 보안정책을 지정하고, 다시 node-shell로 접근해보겠습니다.
접근시 restricted 보안 정책 위반으로 파드 생성이 안되는 것을 확인할 수 있습니다.
- 호스트 네임스페이스 사용: hostNetwork=true 및 hostPID=true 설정이 금지됨.
- privileged 사용: privileged=true가 금지됨.
- allowPrivilegeEscalation: allowPrivilegeEscalation=false로 설정해야 함.
- capabilities.drop: 모든 capabilities를 제거해야 함 (capabilities.drop=["ALL"]).
- runAsNonRoot: 컨테이너를 루트가 아닌 사용자로 실행해야 함.
- seccompProfile: RuntimeDefault 또는 Localhost로 설정해야 함.
실습 환경 삭제
위 구성한 EKS 삭제는 다음의 명령어를 통해 삭제해주세요.
eksctl delete cluster -f eks.yaml
'Cloud Tech' 카테고리의 다른 글
EKS VPC CNI 네트워크 최적화 설정과 Kubeflow에서의 istio 구성 (2) | 2024.10.20 |
---|---|
AWS Load Balancer Controller 기능 분석 (4) | 2024.10.13 |
쿠버네티스 서비스 Iptabls 모드 정리 (0) | 2024.09.28 |
Calico CNI 이해 (0) | 2024.09.20 |
쿠버네티스 네트워크이해하기(Kind, Pause, Ephemeral Container, FlannelCNI) (0) | 2024.09.06 |