kube-hunter 포트 스캔 Kube

Jerry(이정훈)
10 min readFeb 18, 2021

--

Kube를 운영 환경에서 사용하고 가장 큰 고민은 보안이다. (일단 서비스가 우선이라는 생각에 보안에 소홀한 것 또한 사실이다.)

고민만 하던 중 Kube 보안 관련된 몇가지 오픈 소스를 찾게 되었다. (거의 모든 부문이 그렇듯 보안 역시 충분히 운영 환경에 적용 가능한 수준의 여러 오픈 소스들이 있다.) 먼저, 기존 Legacy 포트 스캔 툴과 유사한 기능을 제공하는 Kube-hunter이다.

Kube 환경의 외부로 오픈된 서비스에 대하여 Kube 관련 admin 서비스 (api, etcd 등)가 외부로 노출되어 해커가 정보 조회, 공격 등이 가능한지 점검하는 툴이다. 외부 Hacker 입장에서 초기 사용 가능한 공격 시나리오이다.

먼저, 외부 사용자가 접속 가능하도록 NGINX Web 서버를 Service LoadBalancer Type으로 오픈하였다. 그리고 해당 IP로 Kube-hunter로 점검 하였다. 내가 외부 사용자(혹은 해커)라 가정하고 아래와 같이 내 PC로 실행하였다.

Scan 실시 화면 (kube-hunter는 별도 설치 없이 아래와 같이 도커만 실행하면 된다.)

External IP 확인
[spkr@erdia22 ~ (ksp01:default)]$ k get svc
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
kubernetes ClusterIP 10.233.0.1 <none> 443/TCP 14d
nginx-svc LoadBalancer 10.233.42.223 172.17.29.183 80:31277/TCP 10h
Scan 실시 결과
[spkr@erdia22 ~ (ksp01:default)]$ docker run --rm aquasec/kube-hunter --remote 172.17.29.183 --active
2021-02-18 16:17:24,927 INFO kube_hunter.modules.report.collector Started hunting
2021-02-18 16:17:24,932 INFO kube_hunter.modules.report.collector Discovering Open Kubernetes Services
2021-02-18 16:17:28,019 INFO kube_hunter.modules.report.collector Found open service "Kubelet API" at 172.17.29.183:10250
2021-02-18 16:17:32,576 INFO kube_hunter.modules.report.collector Found open service "API Server" at 172.17.29.183:6443
2021-02-18 16:17:32,625 INFO kube_hunter.modules.report.collector Found vulnerability "K8s Version Disclosure" in 172.17.29.183:6443
Nodes
+-------------+---------------+
| TYPE | LOCATION |
+-------------+---------------+
| Node/Master | 172.17.29.183 |
+-------------+---------------+
Detected Services
+-------------+---------------------+----------------------+
| SERVICE | LOCATION | DESCRIPTION |
+-------------+---------------------+----------------------+
| Kubelet API | 172.17.29.183:10250 | The Kubelet is the |
| | | main component in |
| | | every Node, all pod |
| | | operations goes |
| | | through the kubelet |
+-------------+---------------------+----------------------+
| API Server | 172.17.29.183:6443 | The API server is in |
| | | charge of all |
| | | operations on the |
| | | cluster. |
+-------------+---------------------+----------------------+
Vulnerabilities
For further information about a vulnerability, search its ID in:
https://avd.aquasec.com/
+--------+--------------------+----------------------+----------------------+----------------------+----------+
| ID | LOCATION | CATEGORY | VULNERABILITY | DESCRIPTION | EVIDENCE |
+--------+--------------------+----------------------+----------------------+----------------------+----------+
| KHV002 | 172.17.29.183:6443 | Information | K8s Version | The kubernetes | v1.19.7 |
| | | Disclosure | Disclosure | version could be | |
| | | | | obtained from the | |
| | | | | /version endpoint | |
+--------+--------------------+----------------------+----------------------+----------------------+----------+

외부에서 API 서버 조회를 통하여 k8s version 정보를 알게되는 취약점이 있다. 상당히 특이하게 Metal LB에서 사용하는 external IP를 Node/Master라고 한다. (??)

현재 kube 환경은 3대의 VM으로 구성되었다. master node에서도 pod가 실행된다.

[spkr@erdia22 ~ (ksp01:default)]$ k get nodes
NAME STATUS ROLES AGE VERSION
node1 Ready master 14d v1.19.7
node2 Ready master 14d v1.19.7
node3 Ready <none> 14d v1.19.7

External IP로 scan 하는데 kube api와 통신하는 master nodes 6443 port가 scan 된다. 혹시나 하는 마음에 ssh로 접속해 보니 접속까지 된다. (맙소사)

[spkr@erdia22 ~ (ksp01:default)]$ ssh spkr@172.17.29.183
Last login: Thu Feb 18 15:08:55 2021 from 172.17.19.6
[spkr@node2 ~]$ ip a show
111: kube-ipvs0: <BROADCAST,NOARP> mtu 1500 qdisc noop state DOWN group default
link/ether 9e:70:0c:42:cb:7e brd ff:ff:ff:ff:ff:ff
inet 10.233.42.223/32 scope global kube-ipvs0
valid_lft forever preferred_lft forever
inet 172.17.29.183/32 scope global kube-ipvs0
valid_lft forever preferred_lft forever
[spkr@erdia22 ~ (ksp01:default)]$ k describe svc nginx-svc
Name: nginx-svc
Namespace: default
Normal nodeAssigned 6m18s (x83 over 10h) metallb-speaker announcing from node "node2"

즉, Metal LB를 사용한다면 반드시 주의 해야한다. 꼭 방화벽 적용을 하여 해당 external ip 대역은 80, 443, 8080 등 필요한 Port만 외부 오픈 하도록 해야 한다. 방화벽을 적용하면 위와 같은 보안 취약점이 해결될 것이다.

이에 반하여 Diamanti (Enterprise Kubernetes Platform)는 kube management ip 대역을 별도로 할당하므로 동일한 Metal LB external IP 환경에서도 kube 관련 서비스가 외부로 오픈되지 않는다.

[spkr@erdia22 ~ (spkcluster:default)]$ k get svc
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
kubernetes ClusterIP 10.0.0.1 <none> 443/TCP 41h
nginx-svc LoadBalancer 10.0.0.252 172.17.29.152 80:32749/TCP 10h
prometheus-operated ClusterIP None <none> 9090/TCP 34h
[spkr@erdia22 ~ (spkcluster:default)]$ docker run --rm aquasec/kube-hunter --remote 172.17.29.152 --active
2021-02-18 16:31:32,470 INFO kube_hunter.modules.report.collector Started hunting
2021-02-18 16:31:32,470 INFO kube_hunter.modules.report.collector Discovering Open Kubernetes Services
Kube Hunter couldn't find any clusters

이상으로 kube-hunter 사용하여 kube port scan을 실시 하였다. 다행히 오픈 소스만으로 정식 보안 점검 비슷하게 실행 가능하다. 간단한 port scan 기능이라 방화벽만 적용하면 해결되는 아쉬움이 있기는 하다.

kube-hunter는 포트 스캔 기능만 제공하며 추가로 CIS(Center for Internet Security) 기준 보안 체크 리스트 점검(kube-bench), 컨테이너 이미지 취약점 스캔(trivvy) 등 Kube 오픈 소스 보안 점검 툴 사용도 빠른 시일안에 포스팅 하겠다.

--

--

Jerry(이정훈)
Jerry(이정훈)

Written by Jerry(이정훈)

DevOps/Automation Engineer 60살까지 콘솔 잡는 엔지니어를 목표로 느리게 생각하고 있습니다.

No responses yet