VulnCity

زیرساخت Kubernetes با گرایش امنیت

نویسنده: یاسین عابدینی · دسته: زیرساخت · تاریخ انتشار: ۱۴۰۵/۵/۴

Kubernetes Security: معماری، سطح حمله و رویکرد Red Team

Kubernetes (که به اختصار K8s نامیده می‌شود) امروزه به استاندارد صنعتی برای orchestration کانتینرها تبدیل شده، اما همین گستردگی استفاده، آن را به یکی از جذاب‌ترین target ها برای مهاجمان تبدیل کرده. تحقیقات تیم Aqua Nautilus (بخش تحقیقاتی Aqua Security) نشان داده که در بررسی بیش از ۳۵۰ سازمان دارای Kubernetes cluster عمومی — از جمله شرکت‌های Fortune 500 — حدود ۶۰ درصد از این کلاسترها واقعاً compromise شده بودند و malware و backdoor روی آن‌ها فعال بود. طبق گزارش دیگری از Aqua، ۹۰ درصد از سازمان‌هایی که Kubernetes را در production اجرا می‌کنند، حداقل یک security incident را تجربه کرده‌اند.

Kubernetes به صورت پیش‌فرض secure نیست. هر لایه از آن نیاز به تنظیم صریح (explicit configuration) دارد؛ Pod ها می‌توانند با root اجرا شوند، شبکه به‌طور پیش‌فرض کاملاً باز است، Secret ها فقط base64-encoded هستند نه رمزنگاری‌شده، و ServiceAccount پیش‌فرض دسترسی گسترده‌ای دارد تا زمانی که آن را محدود کنید.

در این مقاله ابتدا معماری K8s رو مرور می‌کنیم و بعد به ازای هر کامپوننت، misconfiguration های رایج و تکنیک‌های Red Team برای سوءاستفاده از اون‌ها رو با نگاه عملیاتی بررسی می‌کنیم.

بخش اول: معماری Kubernetes

یک Kubernetes cluster از دو بخش اصلی تشکیل شده: Control Plane و Worker Node(s).

۱. Pod

کوچک‌ترین واحد deployable در K8s. Pod می‌تونه یک یا چند container رو در خودش جای بده. وقتی چند container به‌صورت tightly-coupled باید با هم کار کنن (مثلاً یک sidecar pattern)، اون‌ها رو داخل یک Pod گروه‌بندی می‌کنیم تا:

  • Network namespace مشترک داشته باشند (یک IP برای همه containerها)
  • Volume مشترک داشته باشند
  • Resource ها (CPU/Memory) به شکل یکپارچه مدیریت بشه

از منظر امنیتی، Pod مرز اصلی isolation در K8s محسوب می‌شه — نه container. این یعنی اگر یک container داخل Pod به خطر بیفته، containerهای دیگه‌ی همون Pod (به دلیل shared network namespace) به‌راحتی در دسترس مهاجم قرار می‌گیرن.

۲. Worker Node

ماشین‌هایی (فیزیکی یا مجازی) که Podها واقعاً روی اون‌ها اجرا می‌شن. هر Worker Node شامل سه کامپوننت اصلیه:

  • kubelet — عامل اجرایی روی هر Node
  • kube-proxy — مدیریت شبکه و forward کردن ترافیک بین Service ها
  • Container Runtime — مثل containerd یا CRI-O که واقعاً container رو اجرا می‌کنه

kubelet — Pod Manager

kubelet روی هر Worker Node اجرا می‌شه و مسئول ایجاد، مانیتور و مدیریت چرخه‌ی حیات Podهای همون Node است. این کامپوننت دستورات دریافتی از Control Plane (از طریق API Server) رو به عملیات واقعی روی container runtime تبدیل می‌کنه.

  • Port پیش‌فرض: 10250 (به نام kubelet API یا management port)
  • این port به‌طور پیش‌فرض publicly exposed نیست، اما در بسیاری از deploymentهای واقعی — خصوصاً در محیط‌های on-prem یا کلود‌های کوچک‌تر — به اشتباه expose می‌شه.
  • استفاده‌ی legitimate از این API: monitoring (metrics)، remote command execution (kubectl exec، kubectl logs) از طریق API Server.

۳. Control Plane — مغز Cluster

Control Plane مسئول تصمیم‌گیری‌های global درباره‌ی cluster است: چه Podی کجا اجرا بشه، وضعیت desired چیه، چطور به رخدادها واکنش نشون بده. اجزای اصلی:

kube-apiserver

نقطه‌ی ورود اصلی به کل cluster. هر تعامل — چه از طرف kubectl، چه از طرف یک کامپوننت داخلی مثل kubelet یا scheduler — از این‌جا عبور می‌کنه.

  • Port پیش‌فرض: 6443
  • تمام درخواست‌ها باید authentication و سپس authorization (معمولاً RBAC) رو پاس کنن.

etcd

دیتابیس key-value توزیع‌شده که تمام state کلاستر رو نگه می‌داره: تنظیمات، metadata، و مهم‌تر از همه — تمام Secret ها (که فقط base64 encode شدن، نه encrypt).

  • Port پیش‌فرض: 2379 (client) و 2380 (peer-to-peer)
  • دسترسی مستقیم به etcd معادل دسترسی به کل داده‌های حساس cluster است.

kube-scheduler

تصمیم می‌گیره هر Pod جدید روی کدوم Node اجرا بشه — بر اساس معیارهایی مثل resource availability، affinity/anti-affinity rules، taints/tolerations.

  • Port پیش‌فرض: 10251 (secure metrics/healthz، پیش‌فرض روی 10259 در نسخه‌های جدیدتر با HTTPS)
  • به‌طور معمول فقط روی localhost یا داخل شبکه‌ی internal کلاستر bind می‌شه.

kube-controller-manager

مجموعه‌ای از controllerهای مختلف (Node controller، Replication controller، Endpoint controller و ...) که به‌صورت مداوم state واقعی cluster رو با state مطلوب (desired state) مقایسه و هماهنگ می‌کنن.

بخش دوم: نگاه Red Team — سطح حمله هر کامپوننت

حالا که ساختار مشخص شد، هر بخش رو از زاویه‌ی یک مهاجم بررسی می‌کنیم: چه misconfiguration ای امکان‌پذیره، و attacker چطور از اون بهره‌برداری می‌کنه.

۱. kubelet API (پورت 10250) — رایج‌ترین نقطه‌ی ورود

طبق تحقیقات Aqua Nautilus، وقتی Kubelet API به اینترنت public exposed باشه، تهدیدات جدی مثل دسترسی غیرمجاز، بهره‌برداری از آسیب‌پذیری‌ها و data breach رو به همراه داره. برای همین آزمایش این تیم یک honeypot با Kubelet API باز روی اینترنت راه‌اندازی کرد تا حملات واقعی رو مانیتور کنه.

Misconfiguration اصلی: فعال بودن --anonymous-auth=true روی kubelet، یا نبود authorization mode مناسب (--authorization-mode=AlwaysAllow به‌جای Webhook).

سناریوی Red Team:

  1. Recon — اسکن رنج IP سازمان برای پورت 10250 باز (Shodan، masscan، nmap).
  2. Enumeration بدون authentication:
    curl -sk https://<node-ip>:10250/pods
    این endpoint، لیست کامل Podهای در حال اجرا روی اون Node رو برمی‌گردونه — شامل namespace، container names و گاهی env variable های حساس.
  3. Remote Command Execution: اگر anonymous access فعال باشه، می‌شه مستقیماً داخل یک container موجود روی اون Node دستور اجرا کرد (از طریق endpoint /run/ یا /exec/) — دقیقاً معادل داشتن دسترسی kubectl exec بدون هیچ credential ای.
  4. Log/Metrics exfiltration از طریق /logs و /metrics/cadvisor — که می‌تونه اطلاعات حساس درباره‌ی workload های در حال اجرا رو فاش کنه.

یک kubelet API که بدون authentication روی پورت 10250 در دسترس باشه، به مهاجم اجازه می‌ده Podها رو لیست کنه، داخل containerها exec بزنه و داده استخراج کنه. مورد معروف Tesla در سال ۲۰۱۸ هم از یک Kubernetes dashboard بدون authentication سوءاستفاده کرد که منجر به cryptojacking شد.

۲. kube-apiserver (پورت 6443)

نقاط ضعف رایج:

  • Anonymous authentication فعال — بدون هیچ token یا certificate، درخواست‌ها پردازش می‌شن.
  • RBAC misconfiguration — بایند کردن Role های بیش از حد permissive (مثل cluster-admin) به ServiceAccount هایی که نیازی به این سطح دسترسی ندارن.
  • exposure عمومی API Server بدون IP allowlisting یا VPN/bastion در جلوش.

API Server دروازه‌ی ورودی اصلی است — یک API Server با anonymous authentication فعال یا RBAC بیش‌ازحد باز، کنترل مستقیم کلاستر را در اختیار مهاجم قرار می‌دهد. راهنمای OWASP Kubernetes Top 10 نسخه ۲۰۲۵، پیکربندی‌های ناامن workload (K01) و مجوزدهی بیش‌ازحد باز (K02) را به‌عنوان دو ریسک برتر معرفی کرده است.

سناریوی Red Team:

  1. بعد از به‌دست‌آوردن یک token یا kubeconfig (مثلاً از یک CI/CD pipeline افشا شده یا یک .kube/config روی سرور compromise شده)، اولین قدم:
    kubectl auth can-i --list
    برای نگاشت (mapping) دقیق دسترسی‌های واقعی موجود.
  2. اگر ServiceAccount مربوطه دسترسی create pods یا create deployments در یک namespace با privileged PodSecurityPolicy/SecurityContext رو داشته باشه → می‌شه یک Pod با privileged: true و hostPath mount کرد و container escape به سمت Node انجام داد.
  3. اگر دسترسی به secrets در namespace موجود باشه → استخراج تمام Secretها (اغلب شامل credential برای cloud provider، database و ...).

۳. etcd (پورت 2379/2380)

اگر etcd بدون client certificate authentication در معرض شبکه (حتی داخلی) باشه، مهاجم می‌تونه مستقیماً query بزنه:

etcdctl --endpoints=https://<etcd-ip>:2379 get / --prefix --keys-only

از اونجایی که Secret ها در etcd فقط base64 encode شدن (نه encrypted-at-rest مگر اینکه EncryptionConfiguration صراحتاً فعال شده باشه)، دسترسی به etcd معادل دسترسی کامل به تمام Secretهای cluster است — یعنی بالاترین ارزش برای یک مهاجم و در عین حال کمتر محافظت‌شده نسبت به API Server.

۴. کنترل‌های سطح Pod و Container

حتی اگر Control Plane به‌خوبی سخت‌سازی شده باشه، misconfiguration در سطح workload می‌تونه مسیر privilege escalation و lateral movement رو باز کنه:

  • Privileged Pods (securityContext.privileged: true) — دسترسی کامل به تمام syscallهای host.
  • hostPath volumes — mount کردن مسیرهایی از filesystem خود Node (مثلاً /، /var/run/docker.sock) داخل Pod؛ در بسیاری موارد مسیر مستقیم container escape.
  • hostNetwork / hostPID / hostIPC — اشتراک‌گذاری namespace های host با container، که مرز isolation رو از بین می‌بره.
  • Service Account Token Mounting پیش‌فرض — هر Pod به‌صورت پیش‌فرض توکن ServiceAccount خودش رو در مسیر /var/run/secrets/kubernetes.io/serviceaccount/token mount می‌کنه؛ اگر مهاجم به یک container دسترسی پیدا کنه (مثلاً از طریق یک آسیب‌پذیری در اپلیکیشن)، این توکن مستقیماً کلید ورود به API Server با همون دسترسی‌های ServiceAccount خواهد بود.

۵. Exposed Secrets در CI/CD و Public Repositories

یکی از مسیرهای غیرمستقیم اما بسیار مؤثر که تیم Aqua Nautilus مستند کرده: Secretهای Kubernetes صدها سازمان و پروژه‌ی open-source که به‌صورت افشاشده روی repository های عمومی آپلود شده بودند، امکان دسترسی به محیط‌های حساس SDLC را فراهم می‌کرد و یک تهدید جدی supply chain attack ایجاد می‌کرد. در این تحقیق حتی سیستم Artifact management شرکت SAP با بیش از ۹۵ میلیون رکورد و دو شرکت بزرگ blockchain نیز در میان قربانیان بودند.

Red Team takeaway: بخشی جدی از یک engagement روی K8s باید شامل جستجو در public repositories، leaked CI/CD logs و container registry های عمومی برای پیدا کردن kubeconfig یا Secret های hardcoded باشه — قبل از اینکه اصلاً وارد فاز exploitation کلاستر بشید.

بخش سوم: Kill Chain عملیاتی برای Red Team روی K8s

با نگاشت به MITRE ATT&CK for Containers، یک مسیر معمول engagement به این شکله:

مرحلهتکنیک نمونه
Reconاسکن پورت‌های 6443 / 10250 / 2379 / 10251؛ جستجوی kubeconfig های افشاشده در GitHub/GitLab
Initial Accessexploit یک web app داخل Pod → دسترسی به shell container؛ یا استفاده از kubeconfig افشاشده
Discoverykubectl auth can-i --list، enumeration namespace ها، ServiceAccount ها، RBAC bindings
Privilege Escalationسوءاستفاده از privileged Pod، hostPath mount، یا ServiceAccount با binding بیش‌ازحد باز به cluster-admin
Lateral Movementحرکت بین namespace ها به دلیل نبود NetworkPolicy؛ دسترسی به Podهای دیگر از طریق shared node یا exposed kubelet
Credential Accessاستخراج Secret ها از etcd یا از طریق API Server؛ خواندن ServiceAccount tokenهای mount‌شده
Persistenceایجاد یک CronJob یا DaemonSet مخرب که روی همه‌ی Nodeها اجرا می‌شه؛ اضافه کردن یک ClusterRoleBinding جدید
Impactcryptomining (رایج‌ترین impact مشاهده‌شده در گزارش‌های Aqua)، exfiltration داده، یا تخریب کامل workloadها

بخش چهارم: جمع‌بندی و توصیه‌های Hardening

از دید Red Team، Kubernetes یک هدف چندلایه است که هر لایه‌ش (Network، Workload، RBAC، Supply Chain) نیاز به بررسی جدا داره. به‌عنوان جمع‌بندی، مهم‌ترین اقدامات defensive که هر تیم Blue/Red باید روی چک‌لیست خودش داشته باشه:

  • غیرفعال کردن anonymous authentication روی kubelet و API Server
  • استفاده از authorization-mode=Webhook به‌جای AlwaysAllow
  • محدود کردن دسترسی network به پورت‌های 6443 / 10250 / 2379 فقط به IPهای مشخص (بدون exposure عمومی)
  • فعال‌سازی Encryption at Rest برای etcd
  • اعمال اصل least-privilege در RBAC — پرهیز جدی از bind کردن cluster-admin به ServiceAccountهای اپلیکیشن
  • اعمال NetworkPolicy برای جلوگیری از lateral movement آزاد بین namespaceها
  • استفاده از ابزارهایی مثل kube-bench (بر اساس CIS Kubernetes Benchmark) و Kubescape برای audit مداوم پیکربندی
  • اسکن مداوم public repositories و CI/CD pipelineها برای جلوگیری از افشای Secret