API Gateway ile Merkezi Güvenlik Yönetimi

Mikroservis mimarisine geçen her ekibin er ya da geç karşılaştığı bir sorun var: onlarca API endpoint’i, farklı kimlik doğrulama mekanizmaları, dağınık rate limiting kuralları ve her serviste tekrarlanan güvenlik kodu. Bu kaosu düzene sokmak için API Gateway tam olarak ihtiyacınız olan şey. Ama “bir gateway kuralım” demek kolay, merkezi güvenlik yönetimini gerçekten işler hale getirmek ayrı bir hikaye.

Bu yazıda Kong, AWS API Gateway ve NGINX tabanlı çözümler üzerinden gerçek dünya senaryolarıyla API güvenliğini nasıl merkezileştireceğinizi, rate limiting’den JWT doğrulamaya, IP whitelisting’den audit log’lara kadar her şeyi adım adım ele alacağız.

API Gateway Neden Merkezi Güvenlik İçin İdeal?

Klasik monolitik uygulamalarda güvenlik katmanı genellikle tek bir noktada yönetilirdi. Mikroservislere geçince bu yapı parçalandı. Şimdi her servis kendi kimlik doğrulamasını yapıyor, her ekip farklı kütüphaneler kullanıyor, güvenlik yamalarını on farklı repoya uygulamanız gerekiyor.

API Gateway bu sorunu cross-cutting concern yaklaşımıyla çözüyor. Kimlik doğrulama, yetkilendirme, rate limiting, SSL termination ve logging gibi işlemleri tek bir katmanda toplayarak her backend servisinizin bu yükü taşımasına gerek kalmıyor. Backend servisleriniz sadece iş mantığına odaklanıyor.

Gerçek dünya örneği: 15 mikroservisi olan bir e-ticaret platformunda çalışıyorsunuz. Her serviste JWT doğrulama kodu var, bazılarında eksik, bazılarında yanlış implemente edilmiş. Bir güvenlik açığı bulunduğunda 15 farklı yerde düzeltme yapıyorsunuz. Gateway merkezileştirmesiyle bu iş tek noktaya iniyor.

Kong ile Temel Gateway Kurulumu

Kong, production ortamlarında en yaygın kullanılan açık kaynak API Gateway çözümlerinden biri. Docker üzerinde hızlıca ayağa kaldıralım:

# Docker Compose ile Kong + PostgreSQL kurulumu
version: '3'
services:
  kong-database:
    image: postgres:13
    environment:
      POSTGRES_USER: kong
      POSTGRES_DB: kong
      POSTGRES_PASSWORD: kongpassword
    volumes:
      - kong-data:/var/lib/postgresql/data

  kong-migration:
    image: kong:3.4
    command: kong migrations bootstrap
    environment:
      KONG_DATABASE: postgres
      KONG_PG_HOST: kong-database
      KONG_PG_USER: kong
      KONG_PG_PASSWORD: kongpassword
    depends_on:
      - kong-database

  kong:
    image: kong:3.4
    environment:
      KONG_DATABASE: postgres
      KONG_PG_HOST: kong-database
      KONG_PG_USER: kong
      KONG_PG_PASSWORD: kongpassword
      KONG_PROXY_ACCESS_LOG: /dev/stdout
      KONG_ADMIN_ACCESS_LOG: /dev/stdout
      KONG_PROXY_ERROR_LOG: /dev/stderr
      KONG_ADMIN_ERROR_LOG: /dev/stderr
      KONG_ADMIN_LISTEN: 0.0.0.0:8001
    ports:
      - "8000:8000"   # Proxy port
      - "8001:8001"   # Admin API
      - "8443:8443"   # HTTPS proxy
    depends_on:
      - kong-migration

volumes:
  kong-data:

Kurulum tamamlandıktan sonra ilk servisinizi ekleyelim:

# Backend servis tanımlama
curl -i -X POST http://localhost:8001/services 
  --data name=user-service 
  --data url=http://user-backend:3000

# Route ekleme
curl -i -X POST http://localhost:8001/services/user-service/routes 
  --data paths[]=/api/users 
  --data methods[]=GET 
  --data methods[]=POST 
  --data strip_path=false

# Servisi doğrulama
curl -i http://localhost:8000/api/users

JWT Tabanlı Kimlik Doğrulama

JWT doğrulamayı her servise yazmak yerine gateway seviyesinde merkezi olarak yönetelim. Kong’un JWT plugin’i bu iş için biçilmiş kaftan:

# JWT plugin'i servise ekle
curl -X POST http://localhost:8001/services/user-service/plugins 
  --data name=jwt 
  --data config.secret_is_base64=false 
  --data config.claims_to_verify[]=exp 
  --data config.key_claim_name=iss 
  --data config.maximum_expiration=3600

# Kong consumer oluştur
curl -X POST http://localhost:8001/consumers 
  --data username=mobile-app 
  --data custom_id=mobile-client-001

# Consumer için JWT credential oluştur
curl -X POST http://localhost:8001/consumers/mobile-app/jwt 
  --data algorithm=HS256 
  --data secret=your-256-bit-secret-key-here

# Oluşturulan key ve secret'ı kaydet
# Response: {"key":"abc123...", "secret":"your-secret..."}

Uygulama tarafında token üretimi şöyle görünür:

# JWT token oluşturma (Node.js ile örnek)
# Payload içinde 'iss' claim'i Kong consumer key'i olmalı
# Header: {"alg":"HS256","typ":"JWT"}
# Payload: {"iss":"abc123...","exp":1735689600,"sub":"user_id_123"}

# Token doğrulamak için test isteği
curl -i http://localhost:8000/api/users 
  -H "Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..."

# Token olmadan istek - 401 döner
curl -i http://localhost:8000/api/users
# HTTP/1.1 401 Unauthorized
# {"message":"Unauthorized"}

Rate Limiting ile DDoS Koruması

Rate limiting olmayan bir API gateway yarım kalmış demektir. Saldırıları ve aşırı yüklenmeleri engellemek için katmanlı bir yaklaşım benimseyin:

# Global rate limiting - tüm servisler için
curl -X POST http://localhost:8001/plugins 
  --data name=rate-limiting 
  --data config.minute=100 
  --data config.hour=1000 
  --data config.policy=redis 
  --data config.redis_host=redis 
  --data config.redis_port=6379 
  --data config.hide_client_headers=false 
  --data config.fault_tolerant=true

# Belirli bir servis için daha sıkı limit
curl -X POST http://localhost:8001/services/payment-service/plugins 
  --data name=rate-limiting 
  --data config.minute=30 
  --data config.hour=500 
  --data config.policy=redis 
  --data config.redis_host=redis 
  --data config.limit_by=ip

# Consumer bazlı farklı limitler (premium vs free tier)
curl -X POST http://localhost:8001/consumers/premium-user/plugins 
  --data name=rate-limiting 
  --data config.minute=500 
  --data config.hour=10000 
  --data config.policy=redis 
  --data config.redis_host=redis

Redis entegrasyonu önemli çünkü birden fazla gateway instance’ınız varsa sayaçların merkezi tutulması gerekiyor. Redis olmadan her pod kendi sayacını tutar ve limitler düzgün çalışmaz.

IP Whitelisting ve Blacklisting

Bazı endpoint’lere sadece belirli IP aralıklarından erişim izni vermek kritik bir güvenlik katmanı. Özellikle admin API’leri ve internal servis iletişimi için bu yaklaşım zorunlu:

# IP kısıtlama plugin'i - whitelist yaklaşımı
curl -X POST http://localhost:8001/services/admin-service/plugins 
  --data name=ip-restriction 
  --data config.allow[]=10.0.0.0/8 
  --data config.allow[]=172.16.0.0/12 
  --data config.allow[]=192.168.1.100 
  --data config.status=403 
  --data "config.message=Bu endpoint'e erişim yetkiniz yok"

# Blacklist yaklaşımı - belirli IP'leri engelle
curl -X POST http://localhost:8001/plugins 
  --data name=ip-restriction 
  --data config.deny[]=185.220.101.0/24 
  --data config.deny[]=198.54.117.0/24

# Mevcut konfigürasyonu kontrol et
curl -s http://localhost:8001/services/admin-service/plugins | 
  python3 -m json.tool | grep -A 20 "ip-restriction"

Gerçek bir senaryo: Production ortamında payment servisine sadece iç ağdan ve belirli partner IP’lerinden erişim izni veriyorsunuz. Dışarıdan gelen her istek otomatik olarak 403 alıyor. Bu basit ama etkili bir güvenlik katmanı.

SSL/TLS Termination ve Sertifika Yönetimi

Gateway seviyesinde SSL termination yaparak backend servislerinizin şifreleme yükünden kurtulmasını sağlayabilirsiniz. Aynı zamanda sertifika yönetimini tek noktada toplarsınız:

# SSL sertifikası yükleme
curl -X POST http://localhost:8001/certificates 
  -F "cert=@/etc/ssl/certs/api.example.com.crt" 
  -F "key=@/etc/ssl/private/api.example.com.key" 
  -F "snis[]=api.example.com" 
  -F "snis[]=*.api.example.com"

# Let's Encrypt ile otomatik sertifika (cert-manager entegrasyonu)
# Kubernetes ortamı için Kong Ingress Controller ile:
kubectl apply -f - <<EOF
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: api-ingress
  annotations:
    kubernetes.io/ingress.class: kong
    cert-manager.io/cluster-issuer: letsencrypt-prod
    konghq.com/https-redirect-status-code: "301"
spec:
  tls:
  - hosts:
    - api.example.com
    secretName: api-tls-secret
  rules:
  - host: api.example.com
    http:
      paths:
      - path: /
        pathType: Prefix
        backend:
          service:
            name: api-service
            port:
              number: 80
EOF

# TLS minimum version zorunlu kılma
curl -X PATCH http://localhost:8001/certificates/{cert-id} 
  --data "tags[]=production" 
  --data "snis[]=api.example.com"

# HTTPS yönlendirme kontrolü
curl -i http://api.example.com/api/users
# HTTP/1.1 301 Moved Permanently
# Location: https://api.example.com/api/users

Merkezi Audit Logging

Güvenlik olaylarını merkezi olarak loglamak, hem compliance gereksinimleri hem de incident response için kritik. Kong’un logging plugin’leri ile bunu kolayca yapabilirsiniz:

# HTTP Log plugin ile merkezi log sunucusuna gönderim
curl -X POST http://localhost:8001/plugins 
  --data name=http-log 
  --data config.http_endpoint=http://logstash:5044 
  --data config.method=POST 
  --data config.timeout=10000 
  --data config.keepalive=60000 
  --data config.flush_timeout=2 
  --data config.retry_count=10 
  --data config.queue_size=1

# File log - yerel loglama için
curl -X POST http://localhost:8001/plugins 
  --data name=file-log 
  --data config.path=/var/log/kong/access.log 
  --data config.reopen=true

# Kafka entegrasyonu - yüksek hacimli logging için
curl -X POST http://localhost:8001/plugins 
  --data name=kafka-log 
  --data config.bootstrap_servers[].host=kafka 
  --data config.bootstrap_servers[].port=9092 
  --data config.topic=kong-access-logs 
  --data config.timeout=10000 
  --data config.keepalive=60000

Log formatını özelleştirmek için custom plugin veya transformation kullanabilirsiniz. Loglarınızda mutlaka şunlar olsun:

  • consumer.id: Kimin istek attığı
  • request.headers.x-forwarded-for: Gerçek client IP
  • response.status: HTTP durum kodu
  • latencies.request: Toplam istek süresi
  • route.id: Hangi route’tan geçtiği
  • service.id: Hangi servise gittiği

OWASP Koruması ve Request Validation

API’leri OWASP Top 10’a karşı korumak için gateway seviyesinde request validation ve WAF entegrasyonu şart:

# Request Validator plugin ile input validation
curl -X POST http://localhost:8001/services/user-service/plugins 
  --data name=request-validator 
  --data config.body_schema='{"type":"object","required":["email","password"],"properties":{"email":{"type":"string","format":"email"},"password":{"type":"string","minLength":8,"maxLength":128}}}' 
  --data config.parameter_schema='[{"name":"user_id","in":"path","required":true,"schema":{"type":"integer"}}]' 
  --data config.version=draft4 
  --data config.verbose_response=false

# Bot Detection plugin
curl -X POST http://localhost:8001/plugins 
  --data name=bot-detection 
  --data "config.allow[]=googlebot" 
  --data "config.allow[]=bingbot"

# Correlation ID enjeksiyonu - distributed tracing için
curl -X POST http://localhost:8001/plugins 
  --data name=correlation-id 
  --data config.header_name=X-Correlation-ID 
  --data config.generator=uuid 
  --data config.echo_downstream=true

# Response header güvenlik eklentisi
curl -X POST http://localhost:8001/plugins 
  --data name=response-transformer 
  --data "config.add.headers[]=X-Content-Type-Options:nosniff" 
  --data "config.add.headers[]=X-Frame-Options:DENY" 
  --data "config.add.headers[]=X-XSS-Protection:1; mode=block" 
  --data "config.add.headers[]=Strict-Transport-Security:max-age=31536000; includeSubDomains" 
  --data "config.remove.headers[]=Server" 
  --data "config.remove.headers[]=X-Powered-By"

AWS API Gateway ile Serverless Güvenlik

Eğer AWS ekosistemindeyseniz API Gateway + Lambda Authorizer kombinasyonu güçlü bir merkezi güvenlik katmanı sağlıyor:

# Lambda Authorizer oluşturma ve API Gateway'e bağlama
# Önce Lambda fonksiyonunu deploy edin, sonra API Gateway'de authorizer tanımlayın

# AWS CLI ile authorizer ekleme
aws apigateway create-authorizer 
  --rest-api-id YOUR_API_ID 
  --name "CentralJWTAuthorizer" 
  --type TOKEN 
  --authorizer-uri "arn:aws:apigateway:eu-west-1:lambda:path/2015-03-31/functions/arn:aws:lambda:eu-west-1:ACCOUNT_ID:function:jwt-authorizer/invocations" 
  --identity-source "method.request.header.Authorization" 
  --authorizer-result-ttl-in-seconds 300

# Usage plan ve API key yönetimi
aws apigateway create-usage-plan 
  --name "BasicPlan" 
  --description "Basic tier - 1000 req/day" 
  --api-stages apiId=YOUR_API_ID,stage=prod 
  --throttle burstLimit=100,rateLimit=50 
  --quota limit=1000,period=DAY

# API key oluştur ve usage plan'a bağla
API_KEY_ID=$(aws apigateway create-api-key 
  --name "partner-api-key" 
  --enabled 
  --query 'id' 
  --output text)

aws apigateway create-usage-plan-key 
  --usage-plan-id USAGE_PLAN_ID 
  --key-id $API_KEY_ID 
  --key-type API_KEY

# WAF entegrasyonu
aws wafv2 associate-web-acl 
  --web-acl-arn "arn:aws:wafv2:eu-west-1:ACCOUNT_ID:regional/webacl/ApiProtection/WEB_ACL_ID" 
  --resource-arn "arn:aws:apigateway:eu-west-1::/restapis/YOUR_API_ID/stages/prod"

Güvenlik Monitoring ve Alerting

Merkezi güvenliğin son halkası monitoring. Anomali tespiti ve hızlı tepki için alerting pipeline’ı kurun:

# Prometheus metrics toplayıcısı aktifleştirme
curl -X POST http://localhost:8001/plugins 
  --data name=prometheus 
  --data config.status_code_metrics=true 
  --data config.latency_metrics=true 
  --data config.bandwidth_metrics=true 
  --data config.upstream_health_metrics=true

# Grafana alert kuralı için PromQL sorguları
# Rate limiting aşımlarını izle:
# rate(kong_http_requests_total{code="429"}[5m]) > 10

# 5xx hata oranını izle:
# sum(rate(kong_http_requests_total{code=~"5.."}[5m])) / sum(rate(kong_http_requests_total[5m])) > 0.05

# Anormal latency spike tespiti:
# histogram_quantile(0.95, rate(kong_request_latency_ms_bucket[5m])) > 2000

# Log analizi için shell script - şüpheli IP tespiti
#!/bin/bash
LOG_FILE="/var/log/kong/access.log"
THRESHOLD=100

# Son 5 dakikada 100'den fazla 401 üretene IP'leri bul
awk -v threshold=$THRESHOLD '
  /401/ {
    match($0, /"ip":"([^"]+)"/, ip)
    if (ip[1] != "") count[ip[1]]++
  }
  END {
    for (addr in count)
      if (count[addr] >= threshold)
        print count[addr], addr
  }
' <(tail -n 10000 $LOG_FILE) | sort -rn | head -20

Zero Trust Mimarisi ile Entegrasyon

Modern güvenlik anlayışında “ağ içindeyse güvenlidir” yaklaşımı tarihe karıştı. Gateway’inizde Zero Trust prensiplerini uygulamak için her servis-arası isteği de doğrulamanız gerekiyor:

Her istekte şunları kontrol edin:

  • mTLS: Servisler arası iletişimde mutual TLS kullanın, her servis kendi sertifikasıyla kimlik doğrulasın
  • Service-to-service tokens: Backend servisler birbirini çağırırken kısa ömürlü JWT kullanın
  • Scope bazlı yetkilendirme: Token içindeki scope claim’leri ile hangi endpoint’e erişilebileceğini kontrol edin
  • Request signing: Kritik API’larda HMAC tabanlı request imzalama uygulayın
  • Audience validation: Token’ın hangi servis için üretildiğini kontrol edin

Kubernetes ortamında Istio veya Linkerd gibi service mesh çözümleri bu katmanı gateway’in altında otomatik olarak yönetiyor. Kong ile Istio birlikte kullanıldığında dış trafik gateway’den, iç trafik service mesh’ten geçiyor ve güvenlik katmanları örtüşüyor.

Production’da Dikkat Edilecek Noktalar

Yıllarca API gateway yöneten biri olarak şunları söyleyebilirim:

  • Admin API’yi asla internete açmayın: Kong admin API’si (8001 portu) sadece iç ağdan erişilebilir olmalı, önüne mutlaka firewall koyun
  • Secret rotation prosedürü kurun: JWT secret’larını döndürürken downtime yaşamamak için dual-key window stratejisi uygulayın
  • Gateway’i HA’ya alın: Tek nokta arıza noktasından kaçının, en az 3 instance çalıştırın
  • Config’i kod olarak yönetin: Deck veya Kong Terraform provider ile gateway konfigürasyonunuzu Git’te tutun, elle yapılan değişiklikler drift yaratır
  • Health check endpoint’lerini koru: /health ve /metrics endpoint’lerine erişimi kısıtlayın ama monitoring sistemlerinin erişebileceğinden emin olun
  • Timeout değerlerini servise özel ayarlayın: Upstream timeout, connection timeout ve read timeout’ları servis karakteristiğine göre belirleyin

Sonuç

API Gateway ile merkezi güvenlik yönetimi, dağıtık sistemlerin kaçınılmaz karmaşıklığını düzenli hale getirmenin en pratik yolu. JWT doğrulamayı 15 serviste yazmak yerine bir kez gateway’de tanımlıyorsunuz, rate limiting’i her ekip farklı implement etmek yerine merkezi Redis destekli bir çözümle yönetiyorsunuz, güvenlik yamalarını tek noktadan tüm sisteme yayıyorsunuz.

Hangi platformu seçerseniz seçin (Kong, AWS API Gateway, NGINX, Traefik), temel prensipler aynı: kimlik doğrulamayı merkezileştir, tüm trafiği logla, anomalileri izle ve Zero Trust prensiplerini uygula. Bu yazıdaki örnekleri kendi ortamınıza uyarlayarak başlayabilirsiniz. Küçük bir MVP kurarak production trafiğini yavaşça gateway’den geçirmeye başlayın, her şeyi bir günde taşımaya çalışmayın.

Sorularınız olursa yorumlarda buluşalım. Bir sonraki yazıda service mesh ile API gateway’in nasıl birlikte çalıştığına ve hangisinin ne işe yaradığına bakacağız.

Bir yanıt yazın

E-posta adresiniz yayınlanmayacak. Gerekli alanlar * ile işaretlenmişlerdir