Nginx ile SSL Session Cache ve OCSP Stapling Yapılandırması

HTTPS trafiğini optimize etmek, sadece güvenlik değil aynı zamanda performans meselesidir. Özellikle yüksek trafikli bir web sunucusunda SSL/TLS el sıkışmalarının (handshake) maliyeti gerçekten ciddi kaynak tüketimine yol açabilir. Bu yazıda Nginx üzerinde SSL Session Cache yapılandırması ve OCSP Stapling’i nasıl doğru şekilde kuracağını, neden bu ikisinin birlikte çalışmasının önemli olduğunu ve gerçek dünya senaryolarında karşılaştığın sorunları nasıl çözeceğini ele alacağız.

SSL Session Cache Nedir ve Neden Önemlidir?

Her yeni HTTPS bağlantısı kurulduğunda sunucu ve istemci arasında bir TLS handshake süreci gerçekleşir. Bu süreç kriptografik işlemler içerdiğinden CPU açısından oldukça pahalıdır. Kullanıcı her yeni isteğinde bu süreci baştan yaşamak zorunda kalırsa hem sunucu hem de istemci tarafında gereksiz gecikme oluşur.

SSL Session Cache, daha önce tamamlanmış TLS oturumlarının bilgilerini belirli bir süre boyunca sunucu belleğinde saklar. Aynı istemci tekrar bağlandığında bu önbelleklenmiş oturum bilgisi kullanılarak handshake süreci kısaltılır. Sonuç olarak:

  • Sunucu CPU kullanımı belirgin şekilde düşer
  • Bağlantı kurulum süresi azalır
  • Özellikle mobil istemcilerde kullanıcı deneyimi iyileşir

Nginx üzerinde iki farklı session cache mekanizması bulunur:

  • builtin: Her worker process kendi önbelleğini tutar, memory açısından verimsizdir
  • shared: Tüm worker process’ler aynı önbelleği paylaşır, üretim ortamları için doğru seçimdir

Temel SSL Session Cache Yapılandırması

Nginx’te SSL session cache’i etkinleştirmek için nginx.conf dosyasında http bloğu içinde global ayarlar yapman ya da doğrudan server bloğunda tanımlaMan gerekir. Genel pratik, global olarak tanımlayıp ihtiyaç halinde override etmektir.

# /etc/nginx/nginx.conf veya /etc/nginx/conf.d/ssl.conf

http {
    # Paylaşılan SSL session cache - 10MB yaklaşık 40.000 oturum saklar
    ssl_session_cache shared:SSL:10m;

    # Oturum bilgisinin önbellekte tutulma süresi
    ssl_session_timeout 1d;

    # TLS 1.3 için session ticket'ları devre dışı bırak (güvenlik için)
    ssl_session_tickets off;

    # Güvenli cipher suite listesi
    ssl_ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384;
    ssl_prefer_server_ciphers off;

    # Desteklenen TLS versiyonları
    ssl_protocols TLSv1.2 TLSv1.3;
}

Burada ssl_session_cache shared:SSL:10m ifadesindeki SSL cache’in adıdır, 10m ise 10 megabyte anlamına gelir. Yoğun trafikli sunucularda bu değeri 20m veya daha yükseğe çıkarabilirsin.

ssl_session_tickets off ayarına özellikle dikkat et. Session ticket’lar istemci tarafında oturum bilgisi saklar ancak forward secrecy açısından riskler barındırır. Ticket key yenileme mekanizması yoksa eski trafiğin sonradan şifresi çözülebilir. Güvenliği performansın önünde tutuyorsan bu ayarı kapalı tut.

Gerçek Dünya Senaryosu: E-Ticaret Sitesi Optimizasyonu

Diyelim ki 500.000 günlük ziyaretçisi olan bir e-ticaret sitesi yönetiyorsun. Günün belirli saatlerinde (özellikle kampanya dönemlerinde) Nginx worker process’lerinin CPU kullanımı %90’ı aşıyor ve sayfa yükleme süreleri ciddi biçimde artıyor. Access log’lara baktığında aynı kullanıcıların kısa süre içinde defalarca yeni SSL handshake yaptığını görüyorsun.

Bu durumda önce mevcut durumu ölçmen gerekir:

# SSL handshake istatistiklerini izlemek için stub_status modülünü etkinleştir
# nginx.conf içinde server bloğuna ekle

server {
    listen 127.0.0.1:8080;
    
    location /nginx_status {
        stub_status on;
        allow 127.0.0.1;
        deny all;
    }
}
# Anlık durumu kontrol et
curl http://127.0.0.1:8080/nginx_status

# Çıktı örneği:
# Active connections: 847
# server accepts handled requests
#  15234821 15234821 48392847
# Reading: 12 Writing: 48 Waiting: 787

Session cache’i etkinleştirdikten sonra aynı metrikleri izlersen “accepts” ile “handled” arasındaki farkın kapandığını ve genel CPU kullanımının düştüğünü göreceksin.

OCSP Stapling Nedir?

SSL sertifikasının geçerliliğini doğrulamak için tarayıcıların sertifika yetkilisinin (CA) OCSP (Online Certificate Status Protocol) sunucusuna sorgu göndermesi gerekir. Bu sürecin iki temel sorunu var:

  • Gizlilik: Kullanıcının hangi siteyi ziyaret ettiği CA’ya iletilir
  • Gecikme: OCSP sunucusu yavaş ya da erişilemez durumdaysa bağlantı kurulumu yavaşlar

OCSP Stapling, bu sorunu zarif bir şekilde çözer. Nginx, CA’dan OCSP yanıtını düzenli aralıklarla kendisi alır ve bunu SSL handshake sırasında istemciye doğrudan “zımbanlar” (staple eder). Böylece istemci ayrı bir OCSP sorgusu yapmak zorunda kalmaz.

Avantajları şunlardır:

  • Bağlantı kurulum süresi kısalır
  • Kullanıcı gizliliği korunur
  • CA’nın OCSP sunucusundaki geçici aksaklıklar son kullanıcıyı etkilemez

OCSP Stapling Yapılandırması

OCSP Stapling’i doğru yapılandırmak birkaç adım gerektirir. Öncelikle sertifika zincirinin tam olması gerekir.

# Tam sertifika zinciri oluşturma (Let's Encrypt örneği)
# Let's Encrypt genellikle bunu otomatik oluşturur ama kontrol edelim

cat /etc/letsencrypt/live/example.com/fullchain.pem | openssl x509 -noout -issuer -subject
# subject: CN = example.com
# issuer: C = US, O = Let's Encrypt, CN = R3

Sertifika zinciri hazırsa Nginx yapılandırmasına OCSP Stapling ekleyebilirsin:

# /etc/nginx/conf.d/example.com.conf

server {
    listen 443 ssl http2;
    server_name example.com www.example.com;

    # Sertifika dosyaları
    ssl_certificate /etc/letsencrypt/live/example.com/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/example.com/privkey.pem;

    # Güvenilir CA sertifikaları (OCSP doğrulaması için)
    ssl_trusted_certificate /etc/letsencrypt/live/example.com/chain.pem;

    # OCSP Stapling etkinleştir
    ssl_stapling on;
    ssl_stapling_verify on;

    # DNS resolver - OCSP sunucusunu çözmek için gerekli
    # Google DNS veya Cloudflare kullanabilirsin
    resolver 8.8.8.8 8.8.4.4 1.1.1.1 valid=300s;
    resolver_timeout 5s;

    # Session cache ayarları
    ssl_session_cache shared:SSL:10m;
    ssl_session_timeout 1d;
    ssl_session_tickets off;

    # Modern TLS yapılandırması
    ssl_protocols TLSv1.2 TLSv1.3;
    ssl_ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305;
    ssl_prefer_server_ciphers off;

    # HSTS (isteğe bağlı ama önerilir)
    add_header Strict-Transport-Security "max-age=63072000" always;

    root /var/www/example.com;
    index index.html;

    location / {
        try_files $uri $uri/ =404;
    }
}

resolver Ayarının Önemi

resolver direktifi sık atlanır ve bu da OCSP Stapling’in sessiz sedasız çalışmamasına yol açar. Nginx, OCSP sunucusunun IP adresini çözümleyebilmek için bir DNS sunucusuna ihtiyaç duyar. Bu ayarı unutursan:

# Nginx error log'da şuna benzer bir hata görürsün:
# [error] 12345#0: OCSP_basic_verify() failed while requesting certificate status
# [warn] 12345#0: no resolver defined to resolve ocsp.int-x3.letsencrypt.org

Eğer internal bir DNS sunucun varsa resolver olarak onu kullanabilirsin:

resolver 192.168.1.53 valid=60s;
resolver_timeout 3s;

OCSP Stapling’i Doğrulama

Yapılandırmayı uyguladıktan sonra çalışıp çalışmadığını test etmen gerekir. Nginx’i yeniden başlattıktan hemen sonra OCSP yanıtı henüz alınmamış olabilir, birkaç saniye beklemen gerekebilir.

# Nginx'i yeniden yükle
nginx -t && systemctl reload nginx

# OCSP Stapling'i test et
echo QUIT | openssl s_client -connect example.com:443 -status 2>/dev/null | grep -A 10 "OCSP Response"

Başarılı bir çıktı şöyle görünür:

OCSP Response Data:
    OCSP Response Status: successful (0x0)
    Response Type: Basic OCSP Response
    Version: 1 (0x0)
    Responder Id: ...
    Produced At: Dec 15 10:00:00 2024 GMT
    Responses:
    Certificate ID:
      Hash Algorithm: sha1
      Issuer Name Hash: ...
    Cert Status: good
    This Update: Dec 15 10:00:00 2024 GMT
    Next Update: Dec 22 10:00:00 2024 GMT

Eğer çıktıda OCSP response: no response sent görürsen birkaç dakika bekleyip tekrar dene. Nginx ilk başladığında OCSP yanıtını arka planda almaktadır.

Birden Fazla Site ile Çalışmak

Birden fazla sanal host yönetiyorsan session cache’i global tanımlamak ve OCSP ayarlarını her server bloğunda yapmak en temiz yaklaşımdır.

# /etc/nginx/nginx.conf - global http bloğu
http {
    # Global SSL ayarları
    ssl_session_cache shared:SSL:20m;
    ssl_session_timeout 1d;
    ssl_session_tickets off;
    ssl_protocols TLSv1.2 TLSv1.3;
    ssl_ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305;
    ssl_prefer_server_ciphers off;

    # OCSP için global resolver
    resolver 8.8.8.8 8.8.4.4 valid=300s;
    resolver_timeout 5s;

    include /etc/nginx/conf.d/*.conf;
}

Her sanal host dosyasında ise yalnızca OCSP’ye özgü sertifika ayarlarını belirtmen yeterli olur:

# /etc/nginx/conf.d/site1.conf
server {
    listen 443 ssl http2;
    server_name site1.com;

    ssl_certificate /etc/ssl/site1/fullchain.pem;
    ssl_certificate_key /etc/ssl/site1/privkey.pem;
    ssl_trusted_certificate /etc/ssl/site1/chain.pem;

    ssl_stapling on;
    ssl_stapling_verify on;

    # ... diğer ayarlar
}

# /etc/nginx/conf.d/site2.conf
server {
    listen 443 ssl http2;
    server_name site2.com;

    ssl_certificate /etc/ssl/site2/fullchain.pem;
    ssl_certificate_key /etc/ssl/site2/privkey.pem;
    ssl_trusted_certificate /etc/ssl/site2/chain.pem;

    ssl_stapling on;
    ssl_stapling_verify on;

    # ... diğer ayarlar
}

Yaygın Sorunlar ve Çözümleri

ssl_trusted_certificate Dosyası Eksik

ssl_stapling_verify on kullandığında ssl_trusted_certificate direktifi zorunludur. Unutursan Nginx şu hatayı verir:

# nginx -t çıktısı:
nginx: [emerg] "ssl_stapling_verify" requires "ssl_trusted_certificate" 
when "ssl_stapling" is used in /etc/nginx/conf.d/example.com.conf:15

Let’s Encrypt kullanıyorsan chain.pem dosyası bu ihtiyacı karşılar. Ticari bir sertifika kullanıyorsan CA’dan ara sertifikaları (intermediate certificates) indirip bir dosyaya birleştirmen gerekir:

# Ara sertifikaları birleştirme örneği
cat intermediate1.crt intermediate2.crt > /etc/ssl/trusted_chain.pem

OCSP Yanıtı Önbelleğe Alınmıyor

Nginx’i her yeniden başlattığında OCSP önbelleği sıfırlanır. Yoğun deploy süreçlerinde bu küçük bir gecikmeye neden olabilir ama pratikte ciddi sorun çıkarmaz. Eğer graceful reload kullanıyorsan eski worker process’ler sona erene kadar OCSP yanıtlarını taşırlar.

Let’s Encrypt Sertifika Yenilemesinden Sonra OCSP Sorunu

Certbot ile otomatik yenileme yapıyorsan yenileme sonrası Nginx’i reload etmen gerekir. Bunun için certbot’un deploy-hook özelliğini kullanabilirsin:

# /etc/letsencrypt/renewal-hooks/deploy/nginx-reload.sh
#!/bin/bash
nginx -t && systemctl reload nginx

chmod +x /etc/letsencrypt/renewal-hooks/deploy/nginx-reload.sh

SSL Yapılandırmasını Kapsamlı Test Etme

Tüm ayarları yaptıktan sonra SSL Labs gibi araçlarla genel puanını kontrol etmek iyi bir pratiktir. Komut satırından da kapsamlı testler yapabilirsin:

# TLS versiyon ve cipher desteğini test et
openssl s_client -connect example.com:443 -tls1_2 2>/dev/null | head -20

# Session reuse çalışıyor mu kontrol et
openssl s_client -connect example.com:443 -reconnect 2>/dev/null | grep -E "New|Reused"
# "Reused, TLSv1.3" çıktısı görüyorsan session cache çalışıyor demektir

# HSTS header kontrolü
curl -sI https://example.com | grep -i strict

# Desteklenen TLS protokollerini listele
nmap --script ssl-enum-ciphers -p 443 example.com

Session reuse testinde Reused yerine sadece New görüyorsan session cache yapılandırmanda bir sorun var demektir. nginx.conf’daki ssl_session_cache direktifini ve log seviyesini artırarak (error_log /var/log/nginx/error.log debug;) daha fazla bilgi toplayabilirsin.

Performans Etikisini Ölçmek

Değişiklikler öncesi ve sonrası karşılaştırma yapmak için wrk veya ab (Apache Benchmark) kullanabilirsin:

# Apache Benchmark ile HTTPS performans testi
# -n: toplam istek sayısı, -c: eş zamanlı bağlantı sayısı
ab -n 10000 -c 100 https://example.com/

# wrk ile daha gelişmiş test
wrk -t4 -c100 -d30s https://example.com/

Session cache etkin olmayan durumda TLS handshake’lerin toplam süreye katkısı genellikle %15-30 arasında olur. Cache etkinleştirildikten sonra bu yük tekrar eden bağlantılarda neredeyse sıfıra iner.

Sonuç

SSL Session Cache ve OCSP Stapling, Nginx’te HTTPS performansını artırmanın en kolay ve etkili yollarından ikisidir. İkisi birlikte çalıştığında:

  • SSL Session Cache tekrar eden bağlantılarda TLS handshake maliyetini ortadan kaldırır
  • OCSP Stapling her bağlantıda yapılacak sertifika doğrulama sorgusunu tek bir merkezi işleme indirir

Yapılandırma süreci göz korkutucu görünse de adımlar nettir: shared session cache tanımla, ssl_stapling on ile OCSP’yi etkinleştir, DNS resolver’ı unutma ve her değişiklikten sonra nginx -t ile sözdizimini doğrula. Prod ortamına almadan önce openssl s_client ile OCSP yanıtını elle kontrol etmek ve SSL Labs gibi bir araçla genel konfigürasyonu test etmek seni pek çok gece çağrısından kurtarır.

Bu iki özellik, özellikle mobil kullanıcı oranı yüksek sitelerde ve e-ticaret gibi her milisaniyenin dönüşüm oranını etkilediği ortamlarda ciddi fark yaratır. Bir kez kurduğunda bakım gerektirmez ve Nginx bu işi sizin adınıza arka planda sessizce yürütür.

Yorum yapın