מ-perimeter ל-zero trust: מה השתנה

עד בערך 2015, רוב הארגונים — כולל בנקים וחברות מסחר — פעלו לפי מודל ה-perimeter. הרעיון היה פשוט: יש חומת אש, בתוך החומה בטוח, מחוץ לחומה לא בטוח. שירותים פנימיים תקשרו ביניהם ב-HTTP רגיל, בלי הצפנה, בלי אימות. ההנחה הייתה שאם התוקף כבר עבר את החומה — אבוד לו. בפועל, ההנחה הזו התבדתה שוב ושוב.

המודל של Zero Trust, כפי שהוגדר ב-NIST SP 800-207, מבטל את ההנחה הזו. כל בקשה — בין אם מבחוץ או מבפנים — צריכה להיות מאומתת, מורשית, ומוצפנת. אין "אמון" מוגדר מראש רק כי הבקשה הגיעה מהרשת הפנימית.

במערכות פיננסיות, המעבר ל-zero trust הוא לא רק שאלה של best practice. רגולטורים כמו MAS (Monetary Authority of Singapore) ו-PCI DSS דורשים הצפנה של תקשורת פנימית. גם אם אתם לא תחת רגולציה ספציפית, תקיפות כמו גניבת הבנק של בנגלדש ב-2016 הראו שתוקף שנמצא בתוך הרשת הפנימית יכול לגרום נזק של עשרות מיליוני דולרים.

mTLS: הבסיס של zero trust בפועל

mTLS (mutual TLS) הוא המנגנון שבו שני הצדדים של חיבור TLS — גם הלקוח וגם השרת — מזדהים באמצעות תעודות דיגיטליות. זה שונה מ-TLS רגיל (כמו שאתם משתמשים לגלישה באינטרנט), שבו רק השרת מזדהה.

איך mTLS עובד בפועל

בתרחיש טיפוסי של מיקרו-שירותים, שירות A רוצה לקרוא לשירות B. עם mTLS:

  1. שירות A שולח ClientHello עם רשימת cipher suites נתמכים
  2. שירות B מחזיר את התעודה שלו (server certificate)
  3. שירות B מבקש את התעודה של שירות A (CertificateRequest)
  4. שירות A שולח את התעודה שלו
  5. שני הצדדים מאמתים את התעודה של הצד השני מול CA (Certificate Authority) משותף
  6. החיבור מוצפן, ושני הצדדים יודעים מי בצד השני

אתגרי ניהול תעודות

mTLS עובד מצוין בתיאוריה. בפרקטיקה, הבעיה הגדולה היא ניהול התעודות. אם יש לכם 50 מיקרו-שירותים וכל אחד צריך תעודה — מי מנפיק את התעודות? מי מחדש אותן כשהן פגות? מה קורה כשצריך לסובב (rotate) תעודה?

הפתרון הנפוץ הוא cert-manager על Kubernetes בשילוב עם Vault PKI. cert-manager מנפיק תעודות אוטומטית, מחדש אותן לפני התפוגה, ומסובב כשצריך. Vault PKI משמש כ-CA פנימי שמנפיק תעודות קצרות-טווח (בדרך כלל 24 שעות עד 7 ימים).

apiVersion: cert-manager.io/v1
kind: Certificate
metadata:
  name: order-service-cert
  namespace: trading
spec:
  secretName: order-service-tls
  duration: 168h
  renewBefore: 24h
  issuerRef:
    name: vault-pki-issuer
    kind: ClusterIssuer
  commonName: order-service.trading.svc.cluster.local
  dnsNames:
  - order-service.trading.svc.cluster.local

הקונפיגורציה הזו מבקשת תעודה עם תוקף של 7 ימים (168 שעות), עם חידוש אוטומטי 24 שעות לפני התפוגה. התעודה מונפקת על ידי Vault PKI ומאוחסנת כ-Kubernetes Secret.

Service Mesh: Istio מול Linkerd

כשמדובר ב-mTLS בקנה מידה גדול, service mesh הוא הפתרון הפרקטי. שתי האפשרויות הנפוצות הן Istio ו-Linkerd. שתיהן מספקות mTLS שקוף (השירותים עצמם לא צריכים לשנות קוד), אבל הגישות שונות.

קריטריוןIstioLinkerd
mTLS אוטומטיכן (strict mode)כן (mTLS by default)
משאבי proxyEnvoy: ~50-100MB RAM לשירותlinkerd-proxy: ~10-20MB RAM
מורכבות התקנהגבוהה — הרבה CRDsנמוכה — התקנה מינימלית
Policy engineAuthorizationPolicy + OPAServerAuthorization
תצפית (observability)Kiali + Grafana dashboardsBuilt-in dashboard + Prometheus
מתאים לארגונים גדולים עם צוות platformצוותים קטנים-בינוניים

הגדרת mTLS strict ב-Istio

הקונפיגורציה הבאה אוכפת mTLS על כל השירותים ב-namespace של trading:

apiVersion: security.istio.io/v1beta1
kind: PeerAuthentication
metadata:
  name: trading-mesh-mtls
  namespace: trading
spec:
  mtls:
    mode: STRICT

מצב STRICT אומר שכל חיבור שאינו mTLS יידחה. זה חשוב בסביבות פיננסיות — PERMISSIVE mode מאפשר גם תעבורה לא מוצפנת, שזה לא מקובל כשמדובר בנתוני תשלומים או פקודות מסחר.

הגדרת Authorization Policy

mTLS מבטיח שהתקשורת מוצפנת ושני הצדדים מזוהים. אבל זה לא מספיק — צריך גם להגדיר מי מורשה לגשת לאן. שירות הלוגים, למשל, לא צריך גישה למסד הנתונים של פקודות המסחר.

apiVersion: security.istio.io/v1beta1
kind: AuthorizationPolicy
metadata:
  name: allow-order-to-payment
  namespace: trading
spec:
  selector:
    matchLabels:
      app: payment-service
  action: ALLOW
  rules:
  - from:
    - source:
        principals: ["cluster.local/ns/trading/sa/order-service"]
    to:
    - operation:
        methods: ["POST"]
        paths: ["/api/v1/payments"]

RBAC גרנולרי עם OPA

Open Policy Agent (OPA) הוא מנוע מדיניות שמאפשר להגדיר כללי הרשאה מורכבים בשפת Rego. בסביבות פיננסיות, RBAC בסיסי (role-based access control) לפעמים לא מספיק — צריך ABAC (attribute-based) או ReBAC (relationship-based).

למשל, מדיניות שאומרת: "רק משתמשים ממחלקת trading, בשעות המסחר, עם IP מטווח מורשה, יכולים לבצע פקודות מעל $100,000." זה לא RBAC פשוט — זה שילוב של role, time, network, ו-transaction attributes.

package trading.authz

default allow = false

allow {
    input.user.department == "trading"
    input.user.role == "senior_trader"
    time.clock(time.now_ns()) >= [9, 0]
    time.clock(time.now_ns()) < [17, 30]
    input.request.amount <= 500000
}

allow {
    input.user.role == "risk_manager"
    input.request.action == "review"
}

מה עושים כשזה נשבר

שום מערכת לא חסינה מתקלות. ב-zero trust, כשמשהו משתבש — תעודה פגה, CA לא זמין, policy שגוי — השירותים פשוט מפסיקים לתקשר. בלי graceful degradation, בלי fallback ל-HTTP.

בסביבה פיננסית, downtime של שירות מסחר זה אירוע חמור. לכן חשוב:

  • ניטור active של תפוגת תעודות — alert כשנותרו פחות מ-48 שעות
  • Circuit breaker ברמת ה-mesh — אם שירות לא מגיב, ה-mesh מנתב מחדש
  • DR plan שכולל שחזור CA ותעודות מגיבוי
  • Runbook מתועד לטיפול בתקלות mTLS — צוות ה-on-call צריך לדעת בדיוק מה לבדוק
טיפ מניסיון: אל תחכו לתקלה הראשונה כדי לגלות שאין לכם runbook. ב-2024, חברת פינטק שמוכרת בתעשייה חוותה downtime של 45 דקות כי תעודת ה-CA הפנימי פגה בסוף שבוע. לא היה מי שיחדש אותה. מאז, הם מגדירים alert על כל תעודה שמתקרבת ל-30 יום לפני תפוגה.

סיכום ומדרג הטמעה

אם אתם מתחילים מאפס, זה סדר הפעולות שאני ממליצה עליו:

  1. מיפוי השירותים ותקשורת ביניהם (service dependency map)
  2. הקמת CA פנימי (Vault PKI או step-ca)
  3. cert-manager על Kubernetes לחידוש אוטומטי
  4. התקנת service mesh (Linkerd לסביבות קטנות, Istio לגדולות)
  5. הפעלת mTLS strict — namespace אחר namespace, לא בבת אחת
  6. הגדרת Authorization Policies
  7. הטמעת OPA למדיניות מורכבת

אל תנסו לעשות הכל בבת אחת. Zero Trust הוא מסע, לא פרויקט. כל צעד בכיוון הנכון משפר את רמת האבטחה.