قابلیت‌های لینوکس (Linux Capabilities) در کانتینرها و کوبرنتیز

لینوکس با بهره‌گیری از ویژگی‌هایی مانند Namespaces، cgroups و فایل‌سیستم‌های ترکیبی، زیرساخت اصلی اجرای کانتینرها و کوبرنتیز را فراهم می‌کند. این قابلیت‌های لینوکس (Linux Capabilities) امکان ایزوله‌سازی، کنترل منابع و امنیت را در محیط‌های ابری فراهم کرده و لینوکس را به پایه‌ای مطمئن برای توسعه و استقرار نرم‌افزارهای مدرن تبدیل کرده‌اند.

در این مطلب، کمی عمیق‌تر به قابلیت‌های لینوکس خواهیم پرداخت تا با استفاده از مثال‌های عملی، ارتباط آنها با کانتینرها و کوبرنتیز را درک کنیم.

قابلیت‌های لینوکس (Linux Capabilities) چیست؟

در لینوکس سنتی، یک فرآیند یا root (کاربر ارشد) است یا non-root (محدود)؛ مفهومی که همه شما می‌دانید.
قابلیت‌های لینوکس در کرنل ۲.۲ معرفی شد. قبل از آن،

  • فرآیندها یا امتیازات root داشتند (Privileged processes (UID=0): Full root access.)
  • امتیازات کاربر معمولی (Non-privileged processes (UID≠۰): Limited permissions.)

مشکل این رویکرد این بود که اگر یک برنامه کاربر non-root نیاز به اجرای یک عملیات privileged داشت، باید با دسترسی کامل root اجرا می‌شد. به عنوان مثال، اتصال به پورت‌های زیر ۱۰۲۴ که نیاز به امتیازات root دارند.

اگر مکانیسمی وجود داشته باشد که به یک کاربر non-root بتوان دسترسی privileged به آن عملیات را ارائه داد، چه می‌شود؟

این چیزی است که قابلیت‌های لینوکس (Linux Capabilities) حل می‌کند.

قابلیت‌های لینوکس این مشکل را با تفکیک امتیازات root به واحدهای جداگانه‌ای که می‌توانند به صورت جداگانه دسترسی داده شوند، حل می‌کنند.

به عنوان مثال،

  1. CAP_NET_BIND_SERVICE: برای اعطای مجوز اتصال به پورت‌های privileged .
  2. CAP_NET_ADMIN: امکان تغییر رابط‌های شبکه، جداول مسیریابی و سایر پیکربندی‌های شبکه را فراهم می‌کند.
  3. CAP_SYS_TIM: برای تغییر ساعت سیستم.
  4. CAP_DAC_OVERRIDE: کنترل دسترسی اختیاری (DAC) را دور می‌زند و به یک فرآیند اجازه می‌دهد تا بررسی‌های مجوز فایل را نادیده بگیرد.
  5. CAP_CHOWN: امکان تغییر مالکیت فایل‌ها را فراهم می‌کند و محدودیت‌های معمول کاربر را دور می‌زند.
  6. CAP_NET_RAW: امکان ارسال و دریافت بسته‌های خام (مثلا ساخت بسته‌های شبکه سفارشی) را فراهم می‌کند. در ابزارهایی مانند ping و tcpdump استفاده می‌شود.

با این کار، به یک کاربر غیر روت فقط می‌توان CAP_NET_BIND_SERVICE اعطا کرد تا به یک پورت privileged متصل شود و در عین حال تمام دسترسی‌های دیگر مربوط به root را مسدود کند.

فقط دستور زیر را اجرا کنید تا تمام قابلیت‌های پشتیبانی شده در لینوکس را فهرست کنید.

man capabilities

۴۷ قابلیت مختلف در کرنل لینوکس امروزی وجود دارد (من این را روی یک سرور Ubunty 24 آزمایش کردم).

قابلیتهای لینوکس

حالا که با قابلیت‌های لینوکس آشنا شدیم، بیایید بفهمیم که کانتینرها و کوبرنتیز چگونه از آنها استفاده می‌کنند.

قابلیت‌های لینوکس و کانتینرها

به طور پیش‌فرض، کانتینرها به عنوان root اجرا می‌شوند (مگر اینکه به عنوان non-root اجرا کنید).
اما این بدان معنا نیست که آنها از امتیازات کامل root در میزبان برخوردارند.

داکر و سایر کانتینر ران‌تایم‌ها از قابلیت‌های لینوکس برای محدود کردن مجوزهای کانتینر برای افزایش امنیت استفاده می‌کنند. این امر محیط کانتینر را امن‌تر می‌کند، حتی اگر شناسه کاربری (UID 0) در داخل کانتینر و روی میزبان یکسان باقی بماند.

به عنوان مثال، داکر بسیاری از قابلیت‌ها را به طور پیش‌فرض حذف می‌کند و فقط از قابلیت‌های مورد نیاز استفاده می‌کند.
کد کانتینر این قابلیت‌های پیش‌فرض مجاز را نشان می‌دهد.

CRIO پیش‌فرض‌های زیر را دارد.

بیایید به یک مثال با استفاده از داکر نگاهی بیندازیم.

بیایید سعی کنیم یک کانتینر BusyBox برای ایجاد یک رابط شبکه ساختگی ایجاد کنیم.


$ docker run --rm -it \
--name test_no_cap busybox sh

/ # ip link add dummy0 type dummy
ip: RTNETLINK answers: Operation not permitted

 

همانطور که می‌بینید، کانتینر فاقد CAP_NET_ADMIN است، بنابراین نمی‌تواند رابط‌های شبکه را تغییر دهد.

از –cap-add برای اعطای قابلیت‌های اضافی لینوکس به یک کانتینر استفاده می‌شود.
اکنون، همان کانتینر را با قابلیت مورد نیاز با استفاده از پرچم –cap-add=NET_ADMIN اجرا کنید.


$ docker run --rm -it --cap-add=NET_ADMIN \
--name test_with_cap busybox sh

/ # ip link add dummy0 type dummy
/ # ip link show dummy0
۲: dummy0: <BROADCAST,NOARP> mtu 1500 qdisc noop qlen 1000
link/ether 0a:0c:31:af:1e:0b brd ff:ff:ff:ff:ff:ff

از آنجایی که کانتینر دارای CAP_NET_ADMIN است، می‌تواند رابط‌های شبکه ایجاد کند.

خرید VPS لینوکس با دسترسی کامل SSH و منابع اختصاصی، مناسب برای برنامه‌نویسان، توسعه‌دهندگان و مدیران سایت در پارسدو فراهم است.

کوبرنتیز و قابلیت‌های لینوکس

وقتی صحبت از کوبرنتیز می‌شود، می‌توانید قابلیت‌های لینوکس (Linux Capabilities) را در SecurityContext خود اضافه یا حذف کنید تا سطوح حمله کاهش یابد.
وقتی یک pod با تصویر BusyBox اجرا می‌کنید، به طور پیش‌فرض می‌توانید از پینگ استفاده کنید.

به عنوان مثال:

$ kubectl run ping-pod \
--image=busybox --restart=Never \
-it -- sh -c "ping 8.8.8.8"

۶۴ bytes from 8.8.8.8: seq=1 ttl=61 time=13.500 ms
۶۴ bytes from 8.8.8.8: seq=2 ttl=61 time=16.598 ms
۶۴ bytes from 8.8.8.8: seq=3 ttl=61 time=16.262 ms

حالا، فرض کنید نمی‌خواهید به BusyBox pod اجازه دهید پینگ انجام دهد.

در این حالت، قابلیت NET_RAW را با استفاده از Security Context حذف می‌کنیم.

قابلیت NET_RAW به یک کانتینر اجازه می‌دهد تا سوکت‌های شبکه خام ایجاد و استفاده کند. این برای دستوراتی مانند پینگ و برخی از ابزارهای دیباگ شبکه مورد نیاز است.

با حذف NET_RAW، از ارسال بسته‌های خام توسط کانتینر جلوگیری می‌کنیم.

به عنوان مثال،

apiVersion: v1
kind: Pod
metadata:
name: busybox-ping
spec:
containers:
- name: busybox
image: busybox:latest
command: ["sleep", "3600"]
securityContext:
capabilities:
drop:
- NET_RAW

اگر این pod را مستقر کنید و پینگ را امتحان کنید، خطای زیر را دریافت خواهید کرد.

$ kubectl exec -it busybox-secure -- ping 8.8.8.8

PING 8.8.8.8 (8.8.8.8): 56 data bytes
ping: permission denied (are you root?)
command terminated with exit code 1

تحلیل قابلیت‌ها با Systemd

در سیستم‌های لینوکس، دستور systemd-analyze security برای ارزیابی امنیت سرویس‌های systemd با تجزیه و تحلیل sandboxing و ویژگی‌های امنیتی آنها استفاده می‌شود.

این دستور نحوه پیکربندی یک سرویس را از نظر محدودیت‌های قابلیت بررسی می‌کند. (مثلا CAP_NET_ADMIN، CAP_DAC_OVERRIDE) و موارد دیگر.

در اینجا نمونه‌ای از خروجی دستور systemd-analyze security آورده شده است.

 

شما می‌توانید با استفاده از نام واحد، یک سرویس خاص را بیشتر تجزیه و تحلیل کنید.

به عنوان مثال،

systemd-analyze security apache2.service

جمع بندی

قابلیت‌های لینوکس (Linux Capabilities) با فراهم کردن امکان کنترل دقیق بر روی کارهایی که فرآیندها می‌توانند انجام دهند، نقش مهمی در اجرای اصل حداقل امتیاز (principle of least privilege) دارند.
برای مهندسان DevOps، پیشگیرانه بودن در مورد این بهترین شیوه‌ها مهم است. امنیت نباید یک امر فرعی باشد؛ با انجام اقدامات امنیتی کوچک اما هوشمندانه در هر کجا که لازم باشد، می‌توانید از غافلگیری‌های لحظه آخری جلوگیری کنید و زیرساخت خود را از همان ابتدا ایمن نگه دارید.