تخطَّ إلى المحتوى

🔐 شرح أمن API وقواعد البيانات

أمن المايكروسيرفيس

الدرس 16 من 25· ⏱ 5 دقائق قراءة

تحديات أمن المايكروسيرفيس

في تطبيق مونوليثي، كل شيء يعمل في عملية واحدة - الاتصال داخلي وآمن. في المايكروسيرفيس، الخدمات تتواصل عبر الشبكة، مما يفتح ثغرات جديدة:

  • اعتراض الاتصالات بين الخدمات
  • انتحال هوية الخدمة
  • هجمات الرجل في المنتصف (MITM)
  • إدارة الهوية الموزعة

Service-to-Service Auth: mTLS

TLS العادي يؤمن الاتصال من المتصفح إلى الخادم. mTLS (Mutual TLS) يضيف مصادقة متبادلة - كل خدمة تتحقق من هوية الخدمة الأخرى.

TLS عادي:
  Client --> يتحقق من شهادة الخادم --> Server
  Client (غير موثَق) <-- اتصال آمن --> Server

mTLS:
  Client --> يتحقق من شهادة الخادم --> Server
  Client (موثَق بشهادته) <-- اتصال آمن مع مصادقة متبادلة --> Server

تنفيذ mTLS مع Node.js

const https = require('https');
const fs = require('fs');

// الخادم - يطلب شهادة من العميل
const server = https.createServer({
  key: fs.readFileSync('server-key.pem'),
  cert: fs.readFileSync('server-cert.pem'),
  ca: fs.readFileSync('ca-cert.pem'), // سلطة التصديق
  requestCert: true,            // يطلب شهادة العميل
  rejectUnauthorized: true,     // يرفض بدون شهادة صالحة
}, (req, res) => {
  const clientCert = req.socket.getPeerCertificate();
  if (!clientCert.subject) {
    res.statusCode = 401;
    return res.end('Unauthorized');
  }

  // استخراج هوية الخدمة من الشهادة
  const serviceName = clientCert.subject.CN;
  console.log(`Service ${serviceName} connected`);
  res.end('Hello from secure service');
});

server.listen(443);
// العميل - يرسل شهادته
const options = {
  hostname: 'service-b.internal',
  port: 443,
  path: '/',
  key: fs.readFileSync('service-a-key.pem'),
  cert: fs.readFileSync('service-a-cert.pem'),
  ca: fs.readFileSync('ca-cert.pem'),
};

const req = https.request(options, (res) => {
  console.log('Connected with mTLS');
});

API Gateway كحدود أمنية

API Gateway هو نقطة الدخول الوحيدة لكل الخدمات. يطبق الأمان مركزياً.

// API Gateway مع Express Gateway أو Kong
const express = require('express');
const rateLimit = require('express-rate-limit');
const helmet = require('helmet');

const gateway = express();

gateway.use(helmet());
gateway.use(rateLimit({ windowMs: 60000, max: 100 }));

// التحقق من JWT مركزياً
gateway.use('/api/*', (req, res, next) => {
  const token = req.headers.authorization?.split(' ')[1];
  if (!token) return res.status(401).json({ error: 'مطلوب توكن' });

  try {
    const decoded = jwt.verify(token, process.env.JWT_SECRET);
    req.user = decoded;
    // إضافة معلومات المستخدم للخدمات الداخلية
    req.headers['x-user-id'] = decoded.userId;
    req.headers['x-user-role'] = decoded.role;
    next();
  } catch {
    res.status(401).json({ error: 'توكن غير صالح' });
  }
});

// توجيه الطلبات للخدمات
gateway.use('/api/users', proxyTo('http://user-service:3001'));
gateway.use('/api/orders', proxyTo('http://order-service:3002'));

JWT Propagation

عندما يمر الطلب عبر عدة خدمات، يجب تمرير هوية المستخدم بينها:

// تمرير JWT بين الخدمات
async function callService(serviceUrl, userToken) {
  const response = await fetch(serviceUrl, {
    headers: {
      'Authorization': `Bearer ${userToken}`,
      'X-Service-Name': 'order-service',
    },
  });
  return response.json();
}

// Middleware في كل خدمة للتحقق من JWT
function authenticateRequest(req, res, next) {
  const token = req.headers.authorization?.split(' ')[1]
    || req.headers['x-user-token']; // من API Gateway
  if (!token) return res.status(401).json({ error: 'مطلوب توكن' });

  try {
    req.user = jwt.verify(token, process.env.JWT_SECRET);
    next();
  } catch {
    res.status(401).json({ error: 'توكن غير صالح' });
  }
}

Distributed Identity: OAuth 2.0 و OpenID Connect

معرف الهوية الموزع (IDP):
  - Keycloak: مفتوح المصدر
  - Auth0: خدمة سحابية
  - Azure AD: للمؤسسات
  - Okta: هوية كخدمة

التدفق:
  Client --> API Gateway --> IDP (Auth)
  API Gateway <-- JWT <-- IDP
  API Gateway --> Service A (مع JWT)
  API Gateway --> Service B (مع JWT)
  Service A --> Service B (مع Service Token)

Service Mesh: Istio و Linkerd

Service Mesh يضيف طبقة أمان شفافة بين الخدمات دون تغيير الكود.

# Istio: تفعيل mTLS تلقائياً
apiVersion: security.istio.io/v1beta1
kind: PeerAuthentication
metadata:
  name: default
  namespace: production
spec:
  mtls:
    mode: STRICT # كل الاتصالات يجب أن تستخدم mTLS
---

# Istio: قواعد الوصول بين الخدمات
apiVersion: security.istio.io/v1beta1
kind: AuthorizationPolicy
metadata:
  name: orders-policy
spec:
  selector:
    matchLabels:
      app: order-service
  rules:
    - from:
        - source:
            principals: ["cluster.local/ns/production/sa/user-service"]
      to:
        - operation:
            methods: ["GET"]
            paths: ["/api/orders/*"]
# Linkerd: تفعيل mTLS
apiVersion: linkerd.io/v1alpha2
kind: ServiceProfile
metadata:
  name: payment-service.production.svc.cluster.local
spec:
  routes:
    - condition:
        method: POST
        pathRegex: /api/payments
      isRetryable: true

فوائد Service Mesh للأمن

  • mTLS تلقائي بين كل الخدمات
  • تشفير كل الاتصالات دون تغيير الكود
  • سياسات الوصول (Authorization Policies)
  • تسجيل كل الاتصالات (Audit Trail)
  • تحديد الخدمات المسموح لها بالتواصل

سياقات الأمان (Security Contexts)

# Kubernetes Pod Security Context
apiVersion: v1
kind: Pod
metadata:
  name: secure-pod
spec:
  securityContext:
    runAsNonRoot: true
    runAsUser: 1000
    fsGroup: 2000
    seccompProfile:
      type: RuntimeDefault
  containers:
    - name: app
      securityContext:
        allowPrivilegeEscalation: false
        capabilities:
          drop: ["ALL"]
        readOnlyRootFilesystem: true

Network Policies

# Kubernetes NetworkPolicy - منع الوصول غير المصرح به
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: api-allow-only
spec:
  podSelector:
    matchLabels:
      app: payment-service
  ingress:
    - from:
        - podSelector:
            matchLabels:
              app: order-service
        - namespaceSelector:
            matchLabels:
              name: monitoring
      ports:
        - port: 3000
  egress:
    - to:
        - podSelector:
            matchLabels:
              app: database
      ports:
        - port: 5432

أفضل ممارسات أمن المايكروسيرفيس

  • استخدم mTLS لكل الاتصالات بين الخدمات
  • ضع API Gateway كطبقة أمان مركزية
  • أعد توجيه JWT بين الخدمات (Propagation)
  • استخدم Service Mesh (Istio/Linkerd) لإدارة الاتصالات
  • طبق Network Policies لعزل الخدمات
  • استخدم Secrets Management (Vault) بدلاً من env vars
  • سجل كل الاتصالات بين الخدمات
  • طبق Rate Limiting على Gateway وكل خدمة

⚠️ في المايكروسيرفيس، الثغرة في خدمة واحدة قد تنتقل لخدمات أخرى. افترض أن كل خدمة قد تخترق - وصمم الدفاعات بناءً على هذا الافتراض (Zero Trust Architecture).

🎯 التالي: أساسيات اختبار الاختراق

شرح أمن المايكروسيرفيس — أمن API وقواعد البيانات بالعربي
أمن المايكروسيرفيسأمن API وقواعد البيانات بالعربي · The Code Fix

هل كان هذا الدرس مفيدًا؟