أمان السحابة والبنية التحتية
أمان الحاويات و Kubernetes
4 دقيقة للقراءة
أمان الحاويات موضوع مقابلة ساخن. يغطي هذا الدرس تقوية Docker، RBAC في Kubernetes، وأنماط أمان المجموعة.
أساسيات أمان Docker
طبقات عزل الحاويات
┌────────────────────────────────────────────────────────────┐
│ نواة المضيف │
├────────────────────────────────────────────────────────────┤
│ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ │
│ │ الحاوية A │ │ الحاوية B │ │ الحاوية C │ │
│ │ │ │ │ │ │ │
│ │ ├─ PID NS │ │ ├─ PID NS │ │ ├─ PID NS │ │
│ │ ├─ NET NS │ │ ├─ NET NS │ │ ├─ NET NS │ │
│ │ ├─ MNT NS │ │ ├─ MNT NS │ │ ├─ MNT NS │ │
│ │ ├─ USER NS │ │ ├─ USER NS │ │ ├─ USER NS │ │
│ │ └─ cgroups │ │ └─ cgroups │ │ └─ cgroups │ │
│ └─────────────┘ └─────────────┘ └─────────────┘ │
└────────────────────────────────────────────────────────────┘
ممارسات Dockerfile الآمنة
# بناء متعدد المراحل لتقليل سطح الهجوم
FROM python:3.12-slim AS builder
WORKDIR /app
COPY requirements.txt .
RUN pip install --no-cache-dir --target=/app/deps -r requirements.txt
# استخدام distroless لوقت تشغيل أدنى
FROM gcr.io/distroless/python3-debian12
# نسخ فقط ما هو مطلوب
COPY /app/deps /app/deps
COPY app.py /app/
# لا تعمل أبداً كـ root
USER nonroot
# استخدام نقطة دخول محددة
ENTRYPOINT ["python", "/app/app.py"]
قائمة فحص أمان Docker
| الممارسة | لماذا تهم |
|---|---|
| مستخدم غير root | يحد من تأثير هروب الحاوية |
| نظام ملفات للقراءة فقط | يمنع التعديلات في وقت التشغيل |
| لا وضع مميز | يمنع الوصول للمضيف |
| حدود الموارد | يمنع DoS |
| صورة أساسية صغيرة | سطح هجوم أصغر |
| لا أسرار في الصور | يمنع كشف بيانات الاعتماد |
| توقيع الصور | يضمن سلامة الصورة |
سؤال المقابلة
س: "ما هو هروب الحاوية وكيف تمنعه؟"
الإجابة: هروب الحاوية هو عندما يكسر المهاجم عزل الحاوية للوصول لنظام المضيف.
الوقاية:
- لا تشغل الحاويات كـ root أبداً
- لا تستخدم علامة
--privilegedأبداً - أسقط كل القدرات:
--cap-drop=ALL - استخدم نظام ملفات جذر للقراءة فقط
- فعّل ملفات seccomp و AppArmor
- حافظ على تحديث النواة ووقت تشغيل الحاوية
- استخدم gVisor أو حاويات Kata للأحمال عالية الأمان
أمان Kubernetes
RBAC (التحكم في الوصول المستند للأدوار)
# الدور: ما هي الإجراءات المسموحة
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
namespace: production
name: pod-reader
rules:
- apiGroups: [""]
resources: ["pods"]
verbs: ["get", "list", "watch"]
- apiGroups: [""]
resources: ["pods/log"]
verbs: ["get"]
---
# ربط الدور: من يحصل على الدور
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
name: read-pods
namespace: production
subjects:
- kind: ServiceAccount
name: monitoring-sa
namespace: production
roleRef:
kind: Role
name: pod-reader
apiGroup: rbac.authorization.k8s.io
معايير أمان Pod
| المستوى | الوصف | حالة الاستخدام |
|---|---|---|
| Privileged | لا قيود | أحمال النظام فقط |
| Baseline | قيود أدنى، يمنع التصعيدات المعروفة | معظم الأحمال |
| Restricted | مقيد بشدة، أفضل ممارسات الأمان | الأحمال الحساسة |
# فرض الأمان المقيد على مستوى مساحة الاسم
apiVersion: v1
kind: Namespace
metadata:
name: secure-apps
labels:
pod-security.kubernetes.io/enforce: restricted
pod-security.kubernetes.io/audit: restricted
pod-security.kubernetes.io/warn: restricted
مواصفات Pod آمنة
apiVersion: v1
kind: Pod
metadata:
name: secure-app
spec:
securityContext:
runAsNonRoot: true
runAsUser: 10000
fsGroup: 10000
seccompProfile:
type: RuntimeDefault
containers:
- name: app
image: myapp:v1.0.0@sha256:abc123... # تثبيت بالملخص
securityContext:
allowPrivilegeEscalation: false
readOnlyRootFilesystem: true
capabilities:
drop: ["ALL"]
resources:
limits:
cpu: "500m"
memory: "256Mi"
requests:
cpu: "100m"
memory: "128Mi"
volumeMounts:
- name: tmp
mountPath: /tmp
volumes:
- name: tmp
emptyDir: {}
automountServiceAccountToken: false # تعطيل إذا لم يكن مطلوباً
سياسات الشبكة
# رفض افتراضي لكل حركة الدخول
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: default-deny-ingress
namespace: production
spec:
podSelector: {}
policyTypes:
- Ingress
---
# السماح بحركة محددة فقط
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: allow-frontend-to-backend
namespace: production
spec:
podSelector:
matchLabels:
app: backend
policyTypes:
- Ingress
ingress:
- from:
- podSelector:
matchLabels:
app: frontend
ports:
- protocol: TCP
port: 8080
إدارة الأسرار في Kubernetes
# سيء: السر في YAML عادي (base64 ليس تشفير!)
apiVersion: v1
kind: Secret
metadata:
name: db-credentials
type: Opaque
data:
password: cGFzc3dvcmQxMjM= # مجرد ترميز base64!
---
# جيد: استخدام مشغل الأسرار الخارجية
apiVersion: external-secrets.io/v1beta1
kind: ExternalSecret
metadata:
name: db-credentials
spec:
refreshInterval: 1h
secretStoreRef:
name: aws-secrets-manager
kind: ClusterSecretStore
target:
name: db-credentials
data:
- secretKey: password
remoteRef:
key: production/database
property: password
نصيحة المقابلة: عند مناقشة أمان Kubernetes، اذكر دائماً الـ 4C للأمان السحابي الأصلي: Code (الكود)، Container (الحاوية)، Cluster (المجموعة)، Cloud (السحابة). كل طبقة تضيف دفاعاً في العمق.
في الدرس التالي، سنغطي هندسة Zero Trust. :::