ABC امنیت در Kubernetes: احراز هویت، مجوز، حسابرسی
دیر یا زود، در عملکرد هر سیستمی، موضوع امنیت مطرح می شود: اطمینان از احراز هویت، تفکیک حقوق، حسابرسی و سایر وظایف. قبلاً برای Kubernetes ایجاد شده است راه حل های بسیاری، که به شما امکان می دهد حتی در محیط های بسیار سخت به رعایت استانداردها برسید... همین مواد به جنبه های اساسی امنیتی که در مکانیزم های داخلی K8s پیاده سازی شده اند اختصاص داده شده است. اول از همه، برای کسانی که شروع به آشنایی با Kubernetes می کنند مفید خواهد بود - به عنوان نقطه شروعی برای مطالعه مسائل مربوط به امنیت.
احراز هویت
دو نوع کاربر در Kubernetes وجود دارد:
حساب های خدماتی - حساب های مدیریت شده توسط Kubernetes API؛
کاربران - کاربران "عادی" که توسط سرویس های خارجی و مستقل مدیریت می شوند.
تفاوت اصلی بین این انواع این است که برای حساب های خدماتی اشیاء خاصی در API Kubernetes وجود دارد (به آنها می گویند - ServiceAccounts) که به یک فضای نام و مجموعه ای از داده های مجوز ذخیره شده در خوشه در اشیاء از نوع Secrets گره خورده اند. چنین کاربرانی (حسابهای سرویس) اساساً برای مدیریت حقوق دسترسی به API Kubernetes فرآیندهای در حال اجرا در خوشه Kubernetes در نظر گرفته شدهاند.
کاربران عادی ورودی هایی در Kubernetes API ندارند: آنها باید توسط مکانیزم های خارجی مدیریت شوند. آنها برای افراد یا فرآیندهایی که خارج از خوشه زندگی می کنند در نظر گرفته شده اند.
هر درخواست API یا با یک حساب سرویس، یک کاربر مرتبط است یا ناشناس در نظر گرفته می شود.
داده های احراز هویت کاربر شامل:
نام کاربری - نام کاربری (حساس به حروف کوچک و بزرگ!)؛
UID - یک رشته شناسایی کاربر قابل خواندن توسط ماشین که "سازگارتر و منحصر به فردتر از نام کاربری" است.
گروه ها - لیست گروه هایی که کاربر به آنها تعلق دارد.
اضافی - فیلدهای اضافی که می توانند توسط مکانیسم مجوز استفاده شوند.
Kubernetes میتواند از تعداد زیادی مکانیسم احراز هویت استفاده کند: گواهیهای X509، توکنهای حامل، پروکسی احراز هویت، HTTP Basic Auth. با استفاده از این مکانیسم ها، می توانید تعداد زیادی طرح مجوز را پیاده سازی کنید: از یک فایل ثابت با رمزهای عبور تا OpenID OAuth2.
علاوه بر این، امکان استفاده از چندین طرح مجوز به طور همزمان وجود دارد. به طور پیش فرض، خوشه از موارد زیر استفاده می کند:
نشانه های حساب خدمات - برای حساب های خدمات.
X509 - برای کاربران.
سوال در مورد مدیریت ServiceAccounts خارج از محدوده این مقاله است، اما برای کسانی که می خواهند با جزئیات بیشتر با این موضوع آشنا شوند، توصیه می کنم با صفحات اسناد رسمی. ما نگاهی دقیق تر به موضوع نحوه عملکرد گواهینامه های X509 خواهیم داشت.
گواهی برای کاربران (X.509)
روش کلاسیک کار با گواهینامه ها شامل موارد زیر است:
پردازش درخواست گواهی با استفاده از کلیدهای CA خوشه Kubernetes، دریافت گواهی کاربر (برای دریافت گواهی، باید از حسابی استفاده کنید که به کلید CA کلاستر Kubernetes دسترسی دارد، که به طور پیش فرض در /etc/kubernetes/pki/ca.key):
برای سهولت در انتقال پیکربندی بین حساب ها و سرورها، ویرایش مقادیر کلیدهای زیر مفید است:
certificate-authority
client-certificate
client-key
برای این کار می توانید فایل های مشخص شده در آنها را با استفاده از base64 رمزگذاری کنید و در کانفیگ ثبت کنید و پسوندی را به نام کلیدها اضافه کنید. -data، یعنی دریافت کرده است certificate-authority-data غیره
گواهینامه با kubeadm
با انتشار Kubernetes 1.15 کار با گواهی ها به لطف نسخه آلفا پشتیبانی آن بسیار آسان تر شده است ابزار kubeadm. به عنوان مثال، تولید یک فایل پیکربندی با کلیدهای کاربر اکنون ممکن است شبیه به این باشد:
kubeadm alpha kubeconfig user --client-name=mynewuser --apiserver-advertise-address 192.168.100.200
NB: ضروری آدرس آگهی را می توان در پیکربندی سرور api یافت که به طور پیش فرض در آن قرار دارد /etc/kubernetes/manifests/kube-apiserver.yaml.
پیکربندی به دست آمده برای stdout خروجی خواهد شد. باید در آن ذخیره شود ~/.kube/config حساب کاربری یا فایلی که در یک متغیر محیطی مشخص شده است KUBECONFIG.
عمیق تر حفاری کن
برای کسانی که می خواهند مسائل توضیح داده شده را به طور کامل درک کنند:
مقاله جداگانه در مورد کار با گواهینامه ها در اسناد رسمی Kubernetes؛
حساب مجاز پیش فرض حق فعالیت در خوشه را ندارد. برای اعطای مجوزها، Kubernetes یک مکانیسم مجوز را پیاده سازی می کند.
قبل از نسخه 1.6، Kubernetes از یک نوع مجوز به نام استفاده می کرد ABAC (کنترل دسترسی مبتنی بر ویژگی). جزئیات در مورد آن را می توان در یافت اسناد رسمی. این رویکرد در حال حاضر قدیمی در نظر گرفته میشود، اما همچنان میتوانید از آن در کنار انواع دیگر احراز هویت استفاده کنید.
روش فعلی (و منعطف تر) تقسیم حقوق دسترسی به یک خوشه نامیده می شود RBAC (کنترل دسترسی مبتنی بر نقش). از زمان نسخه ثابت اعلام شده است Kubernetes 1.8. RBAC یک مدل حقوق را پیاده سازی می کند که در آن هر چیزی که به صراحت مجاز نیست ممنوع است. برای فعال کردن RBAC، باید سرور api Kubernetes را با پارامتر راه اندازی کنید --authorization-mode=RBAC. پارامترها در مانیفست با پیکربندی api-server تنظیم می شوند که به طور پیش فرض در امتداد مسیر قرار دارد. /etc/kubernetes/manifests/kube-apiserver.yaml، در بخش command. با این حال، RBAC قبلاً به طور پیشفرض فعال است، بنابراین به احتمال زیاد نباید نگران آن باشید: میتوانید این را با مقدار تأیید کنید authorization-mode (در موارد ذکر شده kube-apiserver.yaml). به هر حال، در میان معانی آن ممکن است انواع دیگری از مجوز وجود داشته باشد (node, webhook, always allow) ، اما بررسی آنها را خارج از محدوده مطالب ترک خواهیم کرد.
به هر حال، ما قبلا منتشر کرده ایم یک مقاله با توضیح نسبتاً دقیق اصول و ویژگی های کار با RBAC، بنابراین بیشتر به فهرست مختصری از اصول و مثال ها محدود می شوم.
موجودیت های API زیر برای کنترل دسترسی در Kubernetes از طریق RBAC استفاده می شوند:
Role и ClusterRole - نقش هایی که برای توصیف حقوق دسترسی به کار می روند:
Role به شما اجازه می دهد تا حقوق درون یک فضای نام را توصیف کنید.
ClusterRole - در داخل خوشه، از جمله به اشیاء خاص خوشه مانند گرهها، آدرسهای اینترنتی غیرمنبعی (یعنی غیر مرتبط با منابع Kubernetes - برای مثال، /version, /logs, /api*);
RoleBinding и ClusterRoleBinding - برای صحافی استفاده می شود Role и ClusterRole به یک کاربر، گروه کاربری یا حساب سرویس.
موجودیتهای Role و RoleBinding با فضای نام محدود میشوند، یعنی. باید در همان فضای نام باشد. با این حال، یک RoleBinding می تواند به یک ClusterRole اشاره کند، که به شما امکان می دهد مجموعه ای از مجوزهای عمومی ایجاد کنید و دسترسی را با استفاده از آنها کنترل کنید.
نقش ها حقوق را با استفاده از مجموعه ای از قوانین شامل:
گروه های API - ببینید اسناد رسمی توسط apiGroups و خروجی kubectl api-resources;
منابع (منابع: pod, namespace, deployment و غیره.)؛
افعال (افعال: set, update و غیره).
نام منابع (resourceNames) - برای مواردی که نیاز به دسترسی به یک منبع خاص دارید و نه به همه منابع از این نوع.
تجزیه و تحلیل دقیق تر مجوز در Kubernetes را می توان در صفحه یافت اسناد رسمی. در عوض (یا بهتر است بگوییم، علاوه بر این)، من مثال هایی می زنم که کار او را نشان می دهد.
نمونه هایی از موجودیت های RBAC
ساده Role، که به شما امکان می دهد لیست و وضعیت پادها را دریافت کنید و آنها را در فضای نام نظارت کنید target-namespace:
مثال ClusterRole، که به شما امکان می دهد لیست و وضعیت پادها را دریافت کنید و آنها را در کل خوشه نظارت کنید:
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
# секции "namespace" нет, так как ClusterRole задействует весь кластер
name: secret-reader
rules:
- apiGroups: [""]
resources: ["secrets"]
verbs: ["get", "watch", "list"]
مثال RoleBinding، که به کاربر اجازه می دهد mynewuser "خواندن" غلاف در فضای نام my-namespace:
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
name: read-pods
namespace: target-namespace
subjects:
- kind: User
name: mynewuser # имя пользователя зависимо от регистра!
apiGroup: rbac.authorization.k8s.io
roleRef:
kind: Role # здесь должно быть “Role” или “ClusterRole”
name: pod-reader # имя Role, что находится в том же namespace,
# или имя ClusterRole, использование которой
# хотим разрешить пользователю
apiGroup: rbac.authorization.k8s.io
ممیزی رویداد
به طور شماتیک، معماری Kubernetes را می توان به صورت زیر نشان داد:
جزء کلیدی Kubernetes مسئول پردازش درخواست ها است api-server. تمام عملیات روی خوشه از طریق آن انجام می شود. می توانید اطلاعات بیشتری در مورد این مکانیسم های داخلی در مقاله بخوانید.با اجرای kubectl run در Kubernetes چه اتفاقی می افتد؟'.
حسابرسی سیستم یک ویژگی جالب در Kubernetes است که به طور پیش فرض غیرفعال است. این به شما امکان می دهد تمام تماس ها را به API Kubernetes وارد کنید. همانطور که ممکن است حدس بزنید، تمام اقدامات مربوط به نظارت و تغییر وضعیت خوشه از طریق این API انجام می شود. شرح خوبی از قابلیت های آن را می توان (طبق معمول) در اسناد رسمی K8s. در ادامه سعی می کنم موضوع را به زبان ساده تری ارائه کنم.
بنابراین، برای فعال کردن حسابرسی، باید سه پارامتر مورد نیاز را به کانتینر در api-server ارسال کنیم که در زیر با جزئیات بیشتر توضیح داده شده است:
علاوه بر این سه پارامتر ضروری، بسیاری از تنظیمات اضافی مرتبط با ممیزی وجود دارد: از چرخش گزارش تا توضیحات وب هوک. مثالی از پارامترهای چرخش log:
--audit-log-maxbackup=10
--audit-log-maxsize=100
--audit-log-maxage=7
اما ما در مورد آنها با جزئیات بیشتر صحبت نخواهیم کرد - می توانید تمام جزئیات را در آن بیابید مستندات kube-apiserver.
همانطور که قبلا ذکر شد، تمام پارامترها در مانیفست با پیکربندی api-server (به طور پیش فرض) تنظیم می شوند /etc/kubernetes/manifests/kube-apiserver.yaml)، در بخش command. بیایید به 3 پارامتر مورد نیاز برگردیم و آنها را تجزیه و تحلیل کنیم:
audit-policy-file - مسیر فایل YAML که خط مشی حسابرسی را توصیف می کند. بعداً به محتویات آن باز خواهیم گشت، اما فعلاً متذکر می شوم که فایل باید توسط فرآیند api-server قابل خواندن باشد. بنابراین لازم است آن را در داخل کانتینر سوار کنید که برای آن می توانید کد زیر را به بخش های مربوطه کانفیگ اضافه کنید:
audit-log-format - فرمت گزارش حسابرسی پیش فرض است json، اما قالب متن قدیمی نیز موجود است (legacy).
سیاست حسابرسی
حال در مورد فایل مذکور که سیاست لاگ را تشریح می کند. اولین مفهوم خط مشی حسابرسی این است level, سطح ورود به سیستم. آنها به شرح زیر است:
None - وارد نشوید؛
Metadata - ثبت فراداده درخواست: کاربر، زمان درخواست، منبع هدف (غلاف، فضای نام و غیره)، نوع عمل (فعل) و غیره؛
Request - ثبت فراداده و بدنه درخواست؛
RequestResponse - فراداده ثبت نام، بدنه درخواست و بدنه پاسخ.
دو سطح آخر (Request и RequestResponse) درخواست هایی را که به منابع دسترسی نداشتند (دسترسی به آدرس های اینترنتی غیرمنبعی) ثبت نکنید.
همچنین تمام درخواست ها انجام می شود چند مرحله:
RequestReceived - مرحله ای که درخواست توسط پردازنده دریافت می شود و هنوز در طول زنجیره پردازشگرها ارسال نشده است.
ResponseStarted - سرصفحه های پاسخ ارسال می شوند، اما قبل از ارسال بدنه پاسخ. ایجاد شده برای پرس و جوهای طولانی مدت (به عنوان مثال، watch);
ResponseComplete - بدن پاسخ ارسال شده است، اطلاعات بیشتری ارسال نخواهد شد.
Panic - هنگامی که یک موقعیت غیرعادی تشخیص داده شود، رویدادها ایجاد می شوند.
برای رد شدن از هر مرحله ای که می توانید استفاده کنید omitStages.
در یک فایل خط مشی، میتوانیم چندین بخش را با سطوح مختلف گزارش توصیف کنیم. اولین قانون تطبیق یافت شده در شرح خط مشی اعمال خواهد شد.
شبح kubelet تغییرات مانیفست را با پیکربندی api-server نظارت می کند و در صورت شناسایی، ظرف را با api-server راه اندازی مجدد می کند. اما یک نکته مهم وجود دارد: تغییرات در فایل سیاست توسط آن نادیده گرفته می شود. پس از ایجاد تغییرات در فایل سیاست، باید api-server را به صورت دستی راه اندازی مجدد کنید. از آنجایی که api-server به عنوان راه اندازی می شود غلاف استاتیک، تیم kubectl delete باعث راه اندازی مجدد آن نمی شود. شما باید این کار را به صورت دستی انجام دهید docker stop در kube-masters، که در آن خط مشی حسابرسی تغییر کرده است:
هنگام فعال کردن حسابرسی، مهم است که به یاد داشته باشید بار روی kube-apiserver افزایش می یابد. به طور خاص، مصرف حافظه برای ذخیره سازی زمینه درخواست افزایش می یابد. ثبت تنها پس از ارسال سرصفحه پاسخ آغاز می شود. بار همچنین به پیکربندی خط مشی حسابرسی بستگی دارد.
نمونه هایی از سیاست ها
بیایید با استفاده از مثال ها به ساختار فایل های خط مشی نگاه کنیم.
در اینجا یک فایل ساده است policyبرای ثبت همه چیز در سطح Metadata:
در خط مشی می توانید لیستی از کاربران را مشخص کنید (Users и ServiceAccounts) و گروه های کاربری. به عنوان مثال، اینگونه است که کاربران سیستم را نادیده می گیریم، اما بقیه موارد را در سطح ثبت می کنیم Request:
منابع (منابع، به شرح زیر است: pod, configmaps و غیره) و گروه های منابع (apiGroups).
توجه! منابع و گروه های منبع (گروه های API، به عنوان مثال apiGroups)، و همچنین نسخه های نصب شده آنها در خوشه را می توان با استفاده از دستورات به دست آورد:
kubectl api-resources
kubectl api-versions
خط مشی حسابرسی زیر به عنوان نمایشی از بهترین شیوه ها در ارائه شده است مستندات ابری علی بابا:
apiVersion: audit.k8s.io/v1beta1
kind: Policy
# Не логировать стадию RequestReceived
omitStages:
- "RequestReceived"
rules:
# Не логировать события, считающиеся малозначительными и не опасными:
- level: None
users: ["system:kube-proxy"]
verbs: ["watch"]
resources:
- group: "" # это api group с пустым именем, к которому относятся
# базовые ресурсы Kubernetes, называемые “core”
resources: ["endpoints", "services"]
- level: None
users: ["system:unsecured"]
namespaces: ["kube-system"]
verbs: ["get"]
resources:
- group: "" # core
resources: ["configmaps"]
- level: None
users: ["kubelet"]
verbs: ["get"]
resources:
- group: "" # core
resources: ["nodes"]
- level: None
userGroups: ["system:nodes"]
verbs: ["get"]
resources:
- group: "" # core
resources: ["nodes"]
- level: None
users:
- system:kube-controller-manager
- system:kube-scheduler
- system:serviceaccount:kube-system:endpoint-controller
verbs: ["get", "update"]
namespaces: ["kube-system"]
resources:
- group: "" # core
resources: ["endpoints"]
- level: None
users: ["system:apiserver"]
verbs: ["get"]
resources:
- group: "" # core
resources: ["namespaces"]
# Не логировать обращения к read-only URLs:
- level: None
nonResourceURLs:
- /healthz*
- /version
- /swagger*
# Не логировать сообщения, относящиеся к типу ресурсов “события”:
- level: None
resources:
- group: "" # core
resources: ["events"]
# Ресурсы типа Secret, ConfigMap и TokenReview могут содержать секретные данные,
# поэтому логируем только метаданные связанных с ними запросов
- level: Metadata
resources:
- group: "" # core
resources: ["secrets", "configmaps"]
- group: authentication.k8s.io
resources: ["tokenreviews"]
# Действия типа get, list и watch могут быть ресурсоёмкими; не логируем их
- level: Request
verbs: ["get", "list", "watch"]
resources:
- group: "" # core
- group: "admissionregistration.k8s.io"
- group: "apps"
- group: "authentication.k8s.io"
- group: "authorization.k8s.io"
- group: "autoscaling"
- group: "batch"
- group: "certificates.k8s.io"
- group: "extensions"
- group: "networking.k8s.io"
- group: "policy"
- group: "rbac.authorization.k8s.io"
- group: "settings.k8s.io"
- group: "storage.k8s.io"
# Уровень логирования по умолчанию для стандартных ресурсов API
- level: RequestResponse
resources:
- group: "" # core
- group: "admissionregistration.k8s.io"
- group: "apps"
- group: "authentication.k8s.io"
- group: "authorization.k8s.io"
- group: "autoscaling"
- group: "batch"
- group: "certificates.k8s.io"
- group: "extensions"
- group: "networking.k8s.io"
- group: "policy"
- group: "rbac.authorization.k8s.io"
- group: "settings.k8s.io"
- group: "storage.k8s.io"
# Уровень логирования по умолчанию для всех остальных запросов
- level: Metadata
برای پاسخگویی سریع به رویدادهای حسابرسی، این امکان وجود دارد وب هوک را توصیف کنید. این موضوع در پوشش داده شده است اسناد رسمی، آن را خارج از محدوده این مقاله می گذارم.
نمایش نتایج: از
این مقاله مروری بر مکانیسمهای امنیتی اولیه در خوشههای Kubernetes ارائه میکند که به شما امکان میدهد حسابهای کاربری شخصیسازی شده ایجاد کنید، حقوق آنها را جدا کنید و اقدامات آنها را ثبت کنید. امیدوارم برای کسانی که در تئوری یا عملی با چنین مسائلی مواجه هستند مفید واقع شود. من همچنین توصیه می کنم لیستی از مطالب دیگر در مورد امنیت در Kubernetes را که در "PS" آورده شده است بخوانید - شاید در میان آنها جزئیات لازم در مورد مشکلات مربوط به خود را پیدا کنید.