تخفیف برای اولین خرید سرویس ابری با کد تخفیف: Welcome2XaaS
ما با محدودکردن حق استفاده از اینترنت مخالفیم.
اطلاعات بیشتر

امنیت در Kubernetes (بخش اول)

آکادمی ابری زس
امنیت در Kubernetes (بخش اول)

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

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

کوبرنتیز


Object مربوط به secret در kubernetes 


Secret در کوبرنتیز به ما اجازه می‌دهد تا اطلاعات حساس خود را مدیریت و ذخیره کنیم. اطلاعات حساس و مهمی‌مانند password‌ها و OAuth tokens و کلید SSH را می‌توان در secret تعریف و نگهداری کرد. ذخیره سازی اطلاعات محرمانه در secret نسبت به قرار دادن کلمه به کلمه آن در ساختار pod یا image کانتینر امن‌تر و انعطاف پذیرتر است. در این مقاله به معماری و طراحی‌های مختلف Secret در کوبرنتیز خواهیم پرداخت. 
Secret در Kubernetes مفهومی‌به نام Object است که شامل اطلاعاتی حساسی از قبیل رمز وToken و کلید (Key) است. اگر این اطلاعات حساس و مهم نبودند می‌توانستیم آنها را در ساختار Pod‌های کوبرنتیز یا image‌هایی که Deploy  می‌کنیم پیاده سازی کنیم. 
برای استفاده ایمن از Secret‌ها تیم کوبرنتیز موارد زیر را توصیه کرده است


1-رمز نگاری secret‌ها با استفاده از kind به نام EncryptionConfiguration در ساختار yaml (فعال کردن Enable Encryption at Rest برای secret‌ها )


با استفاده از Kind به نام EncryptionConfiguration می‌توان secret‌ها و داده‌ها را رمز نگاری کرد که در نمونه yaml زیر می‌توان به مثالی در این خصوص اشاره کرد. 


apiVersion: apiserver. config. k8s. io/v1
kind: EncryptionConfiguration
resources:
 - resources:
  - secrets
  providers:
  - identity: {}
  - aesgcm:
    keys:
    - name: key1
     secret: c2VjcmV0IGlzIHNlY3VyZQ==
    - name: key2
     secret: dGhpcyBpcyBwYXNzd29yZA==
  - aescbc:
    keys:
    - name: key1
     secret: c2VjcmV0IGlzIHNlY3VyZQ==
    - name: key2
     secret: dGhpcyBpcyBwYXNzd29yZA==
  - secretbox:
    keys:
    - name: key1
     secret: YWJjZGVmZ2hpamtsbW5vcHFyc3R1dnd4eXoxMjM0NTY=


2-فعال کردن و استفاده از configure RBAC rules


می‌توان خواندن و نوشتن Secret‌ها را با این قابلیت محدود کرد، Secretها می‌توانند توسط هر شخصی که دسترسی به ایجاد کردن Pod‌ها را داشته باشد، به دست آورده شود.


استفاده و فراخوانی از Secret در kind‌های مختلف 


Secret-1 می‌تواند در یک یا چندین کانتینر به عنوان فایل در volume‌های mount  شده kubernetes مورد استفاده قرار گرفته شود.(در قسمت دوم مقاله مثال‌ها ارائه خواهد شد )
2-Secret می‌تواند به عنوان environment variable در کانتینر‌ها مورد استفاده قرار گرفته شود. (در قسمت دوم مقاله مثال‌ها ارائه خواهد شد )
3-Secret می‌تواند توسط Kubelet زمانیکه در حال Pull کردن image‌ها برای Pod است، استفاده شود. (در قسمت دوم مقاله مثال‌ها ارائه خواهد شد )

نام secret باید valid و معتبر و مطابق با ساختار نام گذاری DNS subdomain name باشد. که ساختار این نامگذاری در RFC 1123 مشخص شده است. در ساختار yaml فایل‌ها که Kind آن‌ها secret باشد دو فیلد به نام‌های stringData و data وجود دارند که می‌توان از آنها استفاده کرد. استفاده از این فیلد‌ها اختیاری و بر حسب نیاز است. تمام مقادیر و کلید‌هایی که برای فیلد data مورد استفاده قرار می‌گیرند می‌بایست به صورت base64-encoded  شده باشند و در صورتیکه تمایل به base64-encoded کردن دیتا‌ها نداشته باشیم می‌توانیم از فیلد stringData در ساختار yaml خود بهره‌مند شویم. دیتا و اطلاعات موجود در فیلد‌های Data و stringData  باید از نوع alphanumeric و شامل – (dash) و _ (under line) و  یا. (dot) باشند. اگر یک KEY یکسان در فیلد‌های stringData  و data تعریف شده باشند، مقادیر stringData  دارای الویت است. زمانی‌که می‌خواهیم secret ایجاد کنیم (ساختار yaml با kind از نوع secretداشته باشیم) می‌توانیم نوع Secret خود را در فیلدی به نام type مشخص کنیم. به عبارتی دیگر secret‌های دارای type‌های مختلفی هستند، type‌های مختلف در secret با توجه به نوع نیاز استفاده از آن می‌توانند مورد استفاده قرار گرفته شوند. کوبرنتیز برای استفاده از سناریو‌های مختلف رایج type‌های مختلفی برای secret معرفی کرده است که بسته به نیاز می‌توان از هر یک استفاده کرد که محدودیت‌ها و validations‌های کوبرنتیز برای هر type استفاده شده در secret متفاوت است. در جدول زیر می‌توانیم type‌های مختلف secret در کوبرنتیز را مشاهده کنیم. 
نکته : بر حسب نیاز در صورتی‌که بخواهیم محتویاتی را به base64 کد کنیم و در فیلد string مربوط به secret خود قرار دهیم می‌توانیم با کمک دستور echo محتویات فایل خود را base64 کنیم. 
echo -n "password" | base64
در خروجی کامند بالا عبارت password به صورت base64 کد خواهد شد. که خروجی آن مطابق با تصویر زیر است. 


  کوبرنتیز

کوبرنتیز

کوبرنتیز محدودیتی در نام گذاری secret‌ها ندارد اما با توجه به اینکه از چه type از secret‌ها استفاده می‌کنیم می‌بایست الزمات و syntax مربوط به آن type را در ساختار yaml مربوط به secret خود رعایت کنیم.

امنیت kubernetes


 
شرح انواع مختلف secret درKubernetes 


Opaque


ما در کوبرنتیز می‌توانیم usage ‌های مشخص شده‌ای با تعریف secret از نوع Opaque داشته باشیم. 
برای انجام این کار با کامند Kubectl  به صورت زیر اقدام می‌کنیم. 


kubectl create secret generic empty-secret


با توجه به استفاده از subcommand مربوط به generic  نوع یا type مربوط به secret ایجاد شده Opaque خواهد بود که با کامند زیر می‌توانیم اطلاعات secret ایجاد شده خود را مشاهده کنیم.


kubectl get secret empty-secret


همانطور که در خروجی کامند زیر مشخص است type مربوط به secret ایجاد شده Opaque است. 


NAME      TYPE   DATA  AGE
empty-secret  Opaque  0   2m6s

service account secret 
kubernetes. io/service-account-token
این نوع secret برای ذخیره سازی token جهت شناسایی service account در کوبرنتیز مورد استفاده قرار گرفته می‌شود. زمانی‌که از این نوع secret استفاده می‌کنیم باید اطمینان حاصل کنیم که annotation مشخصی در ساختار yaml آن استفاده شده باشد. این نوع secret حتما می‌بایست ازannotation که مقدار دقیق آن kubernetes. io/service-account. name است استفاده کرده باشد که value دقیق آن نیز می‌بایست هم نام با سرویس اکانتی باشد که برای آن secret تعریف کرده‌ایم. 

به عنوان مثال ما یک سرویس اکانت به نام xaas ایجاد کرده ایم که می‌خواهیم برای این سرویس اکانت secret از نوع 
kubernetes. io/service-account-token
ایجاد کنیم. حتما می‌بایست در این secret مقدارannotation  معادل زیر را داشته باشیم. 


kubernetes. io/service-account. name: "xaas"

نمونه yaml زیر یک مثال برای ایجاد secret به جهت استفاده برای سرویس اکانتی به نام xaas است. 

apiVersion: v1
kind: Secret
metadata:
 name: secret-xaas-sample
 annotations:
  kubernetes. io/service-account. name: "xaas"
type: kubernetes. io/service-account-token
data:
 # You can include additional key value pairs as you do with Opaque Secrets
 extra: YmFyCg==

زمانیکه در کوبرنتیز یک pod ساخته می‌شود کوبرنتیز به صورت اتوماتیک یک service account Secret ایجاد می‌کند و به صورت اتومات پاد ایجاد شده از secret ایجاد شده استفاده خواهد کرد. 
service account token Secret شامل credentials برای دسترسی به API کوبرنتیز است. 
عملکرد و کاربرد‌های سرویس اکانت و service account token نیز در مقالات آینده مورد بررسی قرار خواهد گرفت. 

kubernetes


 
Docker config Secrets


دو نوع type مربوط به secret در کوبرنتیز وجود دارد که از آنها برای ذخیره سازی credentials  جهت دسترسی داکر رجیستری برای image  استفاده می‌شود. 
kubernetes. io/dockercfg1-
زمانی‌ که از این نوع secret استفاده می‌کنیم می‌بایست مطمئن باشیم که مقادیر فیلد data  شامل کلید. dockercfg به صورت رمز نگاری base64 در فایل dockercfg باشند. 

kubernetes. io/dockerconfigjson2-
فرمت جدید مورد استفاده است که به صورت json است و محتوای فیلد data از رمز نگاری base64 استفاده می‌کند. 
نمونه زیر ساختار yaml برای secret مربوط به docker است. 


apiVersion: v1
kind: Secret
metadata:
 name: secret-dockercfg
type: kubernetes. io/dockercfg
data:
. dockercfg: |
    ""


همانطور که در مثال مشخص است مسیر فایل حاوری secret با رمزگاری base64 در آن استفاده شده است. در صورتیکه تمایل به رمزنگاری نداشتیم باشیم می‌توانیم به جای فیلد data از stringDataاستفاده کنیم. 
هنگامی‌که از این نوع manifest در ساختار yaml فایل‌های خود استفاده می‌کنیم API سرور بررسی می‌کند که آیا کلید مود انتظار در فیلد data وجود دارد یا خیر. 
درصورتی که فایل داکری حاوی secret موجود نباشد و یا به هر دلیلی نیاز به ساخت secret به صورت کامندی باشد می‌توانیم طبق مثال زیر اقدام به Docker registry Secret نماییم.

 

kubectl create secret docker-registry secret-tiger-docker \
 --docker-username=tiger \
 --docker-password=pass113 \
 --docker-email=tiger@acme. com


در قسمت دوم مقاله که به زودی منتشر خواهد شد به ادامه معرفی type‌های secret با ذکر مثال خواهیم پرداخت. 

...
...