2014 yılı, internet güvenliği açısından gerçek anlamda bir kabus yılıydı. Önce Nisan ayında Heartbleed, ardından Ekim ayında POODLE açığı dünyayı sarstı. Bu iki açık, “SSL kullanıyorum, güvendeyim” yanılgısının ne kadar tehlikeli olduğunu acı bir şekilde ortaya koydu. Bugün bu iki açığı teknik detaylarıyla ele alacağız, nasıl test edeceğinizi ve nasıl önlem alacağınızı adım adım göstereceğiz.
Heartbleed Nedir ve Neden Bu Kadar Kritikti?
Heartbleed (CVE-2014-0160), OpenSSL kütüphanesinin TLS heartbeat uzantısındaki bir bellek okuma hatasıydı. Saldırgan, özel olarak hazırlanmış bir heartbeat isteği göndererek sunucunun belleğinden 64 KB’a kadar veri okuyabiliyordu. Bu veri içinde özel anahtarlar, oturum çerezleri, kullanıcı adları ve parolalar bulunabiliyordu.
Açığın gerçek tehlikeliliği şuydu: iz bırakmıyordu. Normal log kayıtlarına bakarak bu saldırının gerçekleştiğini anlayamazdınız. Saldırgan sunucunuza giriş yapmadan, hiçbir kimlik doğrulama olmadan, sadece ağ erişimiyle bu veriyi çekebiliyordu.
Etkilenen OpenSSL sürümleri şunlardı:
- 1.0.1 – 1.0.1f: Tam olarak etkilenmiş
- 1.0.2-beta: Beta sürümü etkilenmiş
- 0.9.8 ve 1.0.0: Bu dallar etkilenmemiş
Heartbleed Testi Nasıl Yapılır?
Sisteminizin Heartbleed’e karşı savunmasız olup olmadığını test etmek için birkaç yöntem var.
OpenSSL sürümünü kontrol etmek:
openssl version -a
# OpenSSL 1.0.1f 6 Jan 2014 gibi bir çıktı görüyorsanız kritik tehlike!
# Paket yöneticisi üzerinden kontrol
dpkg -l | grep openssl # Debian/Ubuntu
rpm -qa | grep openssl # RHEL/CentOS
Python ile basit Heartbleed tarama betiği:
# heartbleed-test.py aracını kullanarak test
python heartbleed-test.py hedef-sunucu.com
# Nmap ile test (nmap-vulners scripti gerekli)
nmap -sV --script ssl-heartbleed -p 443 hedef-sunucu.com
# Çıktıda şunu görürseniz sorun var:
# | ssl-heartbleed:
# | VULNERABLE:
# | The Heartbleed Bug is a serious vulnerability in the popular OpenSSL
OpenSSL ile manuel TLS heartbeat testi:
# OpenSSL s_client ile bağlantı testi
openssl s_client -connect sunucu.com:443 -tlsextdebug 2>&1 | grep heartbeat
# "TLS server extension heartbeat" görüyorsanız heartbeat açık
# Heartbeat'i devre dışı bırakarak test etmek
openssl s_client -connect sunucu.com:443 -no_ssl2 -no_ssl3
Heartbleed için Düzeltme Adımları
Önce OpenSSL’i güncelleyin, sonra tüm sertifikalarınızı yenileyin. Bu sırayı atlayıp sadece OpenSSL güncellemesi yapmak yeterli değil çünkü özel anahtarlarınız çoktan çalınmış olabilir.
# Ubuntu/Debian için güncelleme
sudo apt-get update
sudo apt-get install --only-upgrade openssl libssl1.0.0
sudo openssl version # 1.0.1g veya üstü olmalı
# RHEL/CentOS için güncelleme
sudo yum update openssl
sudo rpm -qa openssl
# Güncelleme sonrası OpenSSL kullanan servisleri yeniden başlatın
sudo service nginx restart
sudo service apache2 restart
sudo service postfix restart
# Hangi process'lerin eski libssl kullandığını bulmak
sudo lsof | grep libssl | awk '{print $1}' | sort -u
Heartbleed sonrası yapmanız gerekenler listesi:
- Özel anahtarları yeniden oluşturun: Eski anahtarlar tehlikeye girmiş olabilir
- Yeni CSR (Certificate Signing Request) oluşturun: Eski CSR ile devam etmeyin
- CA’dan yeni sertifika talep edin: Revoke işlemi yapmayı unutmayın
- Tüm oturum tokenlarını geçersiz kılın: Session hijacking riski var
- Kullanıcıları bilgilendirin: Parola değiştirmelerini isteyin
POODLE Açığı: Yaşlı Bir Protokolün Sonu
POODLE (Padding Oracle On Downgraded Legacy Encryption, CVE-2014-3566), SSL 3.0 protokolündeki bir açıktı. Heartbleed’den farklı olarak bu açık OpenSSL implementasyonundaki bir hata değil, SSL 3.0 protokolünün tasarım hatasıydı. Yani yamanın tek yolu SSL 3.0’ı tamamen devre dışı bırakmaktı.
Saldırı senaryosu şöyle işliyordu: Saldırgan, man-in-the-middle konumunda olup TLS bağlantısını düşürüyordu (downgrade attack). İstemci ve sunucuyu SSL 3.0 kullanmaya zorluyordu. Ardından CBC şifreleme modundaki padding oracle açığını kullanarak şifreli trafiği deşifre edebiliyordu.
POODLE, Heartbleed kadar geniş çaplı etki bırakmadı çünkü saldırganın ağ trafiğinize müdahale edebilmesi gerekiyordu. Ama özellikle açık WiFi ağlarında bu senaryo son derece gerçekçiydi.
POODLE Testi ve SSL 3.0 Kontrolü
# SSL 3.0 desteğini test etmek
openssl s_client -connect hedef-sunucu.com:443 -ssl3
# "handshake failure" alıyorsanız SSL 3.0 kapalı, iyisiniz
# Başarılı bağlantı kuruluyorsa ciddi sorun var
# Nmap ile POODLE testi
nmap -sV --version-light --script ssl-poodle -p 443 hedef-sunucu.com
# testssl.sh ile kapsamlı test (çok işe yarayan bir araç)
./testssl.sh --poodle hedef-sunucu.com
testssl.sh aracını sistemize kurmak ve kullanmak:
# testssl.sh kurulumu
git clone --depth 1 https://github.com/drwetter/testssl.sh.git
cd testssl.sh
# Tek komutla kapsamlı SSL/TLS analizi
./testssl.sh hedef-sunucu.com
# Sadece protokol desteğini kontrol etmek
./testssl.sh --protocols hedef-sunucu.com
# JSON formatında rapor almak
./testssl.sh --jsonfile rapor.json hedef-sunucu.com
POODLE için Yapılandırma Düzeltmeleri
Apache için SSL 3.0 devre dışı bırakma:
# /etc/apache2/mods-enabled/ssl.conf veya virtual host dosyanıza ekleyin
SSLProtocol all -SSLv2 -SSLv3
SSLCipherSuite ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384
SSLHonorCipherOrder on
SSLCompression off
# Apache'yi yeniden başlatmadan önce konfigürasyonu test edin
sudo apache2ctl configtest
sudo service apache2 restart
# Değişikliği doğrulayın
openssl s_client -connect localhost:443 -ssl3 2>&1 | grep -i "handshake|error"
Nginx için SSL 3.0 devre dışı bırakma:
# /etc/nginx/conf.d/ssl.conf veya ilgili server bloğuna ekleyin
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:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384;
ssl_prefer_server_ciphers off;
ssl_session_cache shared:SSL:10m;
ssl_session_timeout 1d;
ssl_session_tickets off;
# Nginx konfigürasyonunu test et
sudo nginx -t
sudo systemctl reload nginx
Günümüzde Kapsamlı SSL/TLS Güvenlik Denetimi
Bu iki tarihi açık bugün teknik olarak büyük ölçüde kapatılmış durumda. Ama bu, SSL/TLS güvenliğini göz ardı edebileceğiniz anlamına gelmiyor. Yanlış yapılandırılmış sunucular, eski sürüm bağımlılıklar ve benzeri sorunlar hala yaygın.
Sertifika Durumu ve Geçerlilik Kontrolleri
# Sertifika detaylarını görüntülemek
openssl s_client -connect sunucu.com:443 -servername sunucu.com < /dev/null 2>/dev/null |
openssl x509 -noout -dates -subject -issuer
# Sertifika bitiş tarihini gün cinsinden hesaplamak
cert_expiry() {
local domain=$1
local expiry_date=$(echo | openssl s_client -connect ${domain}:443 -servername ${domain} 2>/dev/null |
openssl x509 -noout -enddate 2>/dev/null | cut -d= -f2)
local expiry_epoch=$(date -d "${expiry_date}" +%s)
local now_epoch=$(date +%s)
local days_left=$(( (expiry_epoch - now_epoch) / 86400 ))
echo "${domain}: ${days_left} gün kaldı (${expiry_date})"
}
cert_expiry ornek-domain.com
# Birden fazla domain için toplu kontrol
for domain in site1.com site2.com site3.com; do
cert_expiry $domain
done
Zayıf Cipher Suite Tespiti
Sadece SSL 3.0 kapatmak yetmez. Zayıf cipher suite’leri de temizlemeniz gerekiyor.
# Desteklenen cipher suite'leri listele
nmap --script ssl-enum-ciphers -p 443 hedef-sunucu.com
# openssl ile desteklenen cipher'ları test etmek
for cipher in $(openssl ciphers 'ALL:eNULL' | tr ':' ' '); do
result=$(echo -n | openssl s_client -connect hedef-sunucu.com:443
-cipher $cipher 2>&1)
if echo "$result" | grep -q "Cipher is $cipher"; then
echo "DESTEKLENIYOR: $cipher"
fi
done
# RC4, DES, 3DES gibi zayıf cipher kullanımını kontrol et
openssl s_client -connect hedef-sunucu.com:443 -cipher RC4 2>&1 |
grep -i "cipher|error|handshake"
HSTS ve Sertifika Sabitleme (Certificate Pinning)
POODLE saldırısının temel mekanizması olan protokol downgrade saldırılarına karşı en etkili korunma yöntemlerinden biri HSTS (HTTP Strict Transport Security)‘dir.
# Apache HSTS yapılandırması
# /etc/apache2/sites-enabled/default-ssl.conf
Header always set Strict-Transport-Security "max-age=31536000; includeSubDomains; preload"
# Nginx HSTS yapılandırması
add_header Strict-Transport-Security "max-age=31536000; includeSubDomains; preload" always;
# HSTS durumunu curl ile kontrol etmek
curl -sI https://hedef-sunucu.com | grep -i strict-transport
# HSTS preload listesinde olup olmadığını kontrol
curl "https://hstspreload.org/api/v2/status?domain=siteniz.com" | python3 -m json.tool
Let’s Encrypt ve Modern Sertifika Yönetimi
Certbot kullanıyorsanız zaten birçok güvenlik best practice’i otomatik olarak uygulanıyor. Ama kontrol etmek her zaman iyi bir alışkanlık.
# Certbot ile SSL sertifikası almak (Nginx)
sudo certbot --nginx -d domain.com -d www.domain.com
# Otomatik yenilemeyi test etmek
sudo certbot renew --dry-run
# Mevcut sertifikaları listelemek
sudo certbot certificates
# Certbot'un oluşturduğu Nginx konfigürasyonunu kontrol et
grep -i "ssl_protocols|ssl_ciphers" /etc/nginx/sites-enabled/default
# Certbot ile oluşturulan sertifika dizinleri
ls -la /etc/letsencrypt/live/domain.com/
# fullchain.pem -> sertifika zinciri
# privkey.pem -> özel anahtar
# cert.pem -> sertifika
# chain.pem -> ara sertifika
Özel anahtar güvenliği konusunda dikkat edilmesi gerekenler:
# Özel anahtar dosyası izinlerini kontrol edin (sadece root okuyabilmeli)
ls -la /etc/letsencrypt/live/domain.com/privkey.pem
# -rw-r--r-- olmamalı! -rw------- veya -r-------- olmalı
# Yanlış izinleri düzeltmek
sudo chmod 600 /etc/ssl/private/sunucu.key
sudo chown root:ssl-cert /etc/ssl/private/sunucu.key
# RSA anahtar uzunluğunu kontrol etmek (en az 2048 bit, tercihen 4096)
openssl rsa -in /etc/ssl/private/sunucu.key -noout -text | grep "Private-Key"
# Yeni 4096 bit RSA anahtar oluşturmak
openssl genrsa -out yeni-anahtar.key 4096
# ED25519 ile modern ve küçük boyutlu anahtar
openssl genpkey -algorithm ED25519 -out ed25519-anahtar.key
Gerçek Dünya Senaryosu: Kurumsal Ortamda SSL Denetimi
Diyelim ki 20 farklı web sunucusu olan bir kurumsal ağı yönetiyorsunuz. Her birini tek tek kontrol etmek yerine otomatik bir denetim betiği kullanabilirsiniz.
#!/bin/bash
# ssl-audit.sh - Toplu SSL güvenlik denetimi
DOMAINS_FILE="domains.txt"
LOG_FILE="/var/log/ssl-audit-$(date +%Y%m%d).log"
ALERT_EMAIL="[email protected]"
WARN_DAYS=30 # 30 gün kala uyarı ver
echo "SSL Denetim Raporu - $(date)" > $LOG_FILE
echo "================================" >> $LOG_FILE
while IFS= read -r domain; do
echo -n "Kontrol ediliyor: $domain ... "
# SSL 3.0 kontrolü
ssl3_result=$(openssl s_client -connect ${domain}:443 -ssl3 2>&1)
if echo "$ssl3_result" | grep -q "Cipher is"; then
echo "KRITIK: $domain - SSL 3.0 AKTIF (POODLE riski!)" >> $LOG_FILE
echo "HATA: SSL 3.0 aktif!"
fi
# TLS 1.2 ve 1.3 desteği kontrolü
tls12=$(openssl s_client -connect ${domain}:443 -tls1_2 2>&1 | grep "Cipher is")
tls13=$(openssl s_client -connect ${domain}:443 -tls1_3 2>&1 | grep "Cipher is")
if [ -z "$tls12" ] && [ -z "$tls13" ]; then
echo "UYARI: $domain - TLS 1.2/1.3 desteklenmiyor" >> $LOG_FILE
fi
# Sertifika bitiş tarihi
expiry=$(echo | openssl s_client -connect ${domain}:443 -servername ${domain} 2>/dev/null |
openssl x509 -noout -enddate 2>/dev/null | cut -d= -f2)
if [ -n "$expiry" ]; then
expiry_epoch=$(date -d "$expiry" +%s 2>/dev/null)
now_epoch=$(date +%s)
days_left=$(( (expiry_epoch - now_epoch) / 86400 ))
if [ $days_left -lt $WARN_DAYS ]; then
echo "UYARI: $domain - Sertifika $days_left gün sonra bitiyor!" >> $LOG_FILE
else
echo "OK: $domain - $days_left gün geçerli" >> $LOG_FILE
fi
fi
echo "tamam"
done < "$DOMAINS_FILE"
# Kritik sorun varsa email gönder
if grep -q "KRITIK|UYARI" $LOG_FILE; then
mail -s "SSL Güvenlik Uyarısı - $(date +%Y-%m-%d)" $ALERT_EMAIL < $LOG_FILE
fi
echo "Denetim tamamlandı. Rapor: $LOG_FILE"
Bu betiği cron’a ekleyerek her gece çalıştırabilirsiniz:
# Crontab'a eklemek
sudo crontab -e
# Şu satırı ekleyin:
# 0 2 * * * /usr/local/bin/ssl-audit.sh
# Betiği çalıştırılabilir yapın
sudo chmod +x /usr/local/bin/ssl-audit.sh
TLS 1.0 ve 1.1’i de Kapatın
POODLE, SSL 3.0 ile ilgiliydi ama TLS 1.0 ve TLS 1.1 da artık güvensiz kabul ediliyor. BEAST, CRIME, BREACH gibi saldırılar bu sürümleri etkiliyor. PCI DSS standartları da 2018’den bu yana TLS 1.0 kullanımını yasaklamış durumda.
Günümüzde sadece TLS 1.2 ve TLS 1.3 kullanılmalı. TLS 1.3, 2018 yılında standartlaştı ve önceki sürümlere kıyasla hem daha hızlı hem de çok daha güvenli.
TLS 1.3’ün getirdiği iyileştirmeler:
- 0-RTT handshake: Daha hızlı bağlantı kurulumu
- Forward secrecy zorunluluğu: Eski trafiğin şifresi çözülemiyor
- Zayıf cipher suite’lerin kaldırılması: MD5, SHA-1, RC4 yok
- RSA key exchange’in kaldırılması: Sadece ECDHE ve DHE kullanılıyor
Sertifika Şeffaflığı (Certificate Transparency)
Son olarak değinmek istediğim bir konu da Certificate Transparency (CT). Heartbleed sonrasında saldırganların çaldığı özel anahtarlarla sahte sertifikalar çıkarma riski gündeme geldi. CT, tüm sertifikaların halka açık log sunucularına kaydedilmesini zorunlu kılıyor.
# Bir domain için CT loglarını sorgulamak
curl "https://crt.sh/?q=domain.com&output=json" | python3 -m json.tool | head -50
# Beklenmedik sertifika var mı kontrol etmek
curl -s "https://crt.sh/?q=%.domain.com&output=json" |
python3 -c "import sys,json; [print(c['name_value']) for c in json.load(sys.stdin)]" |
sort -u
Bu komut, domain’inize ait tüm yayımlanmış sertifikaları listeler. Tanımadığınız bir sertifika görürseniz hesap ele geçirilmiş olabilir.
Sonuç
Heartbleed ve POODLE, internet güvenliği tarihinin en önemli dönüm noktalarından ikisiydi. Bugün bu açıkların üzerinden on yıl geçti ama öğrettikleri dersler hala geçerli.
Heartbleed bize şunu öğretti: Yazılım kütüphaneleri ne kadar yaygın kullanılırsa, içindeki bir hatanın etkisi de o kadar büyük olur. OpenSSL güncellemelerini asla ertelemeyin.
POODLE ise şunu gösterdi: Geriye dönük uyumluluk adına eski ve güvensiz protokolleri canlı tutmak kabul edilemez bir risk. Bağlantısı kesilen birkaç eski istemci için tüm kullanıcılarınızı tehlikeye atmaya değmez.
Pratik eylem listesi olarak şunu öneriyorum:
- Her ay OpenSSL sürümünüzü kontrol edin ve güncel tutun
- SSL 3.0, TLS 1.0, TLS 1.1’i kapalı tutun
- Sertifika bitiş tarihlerini otomatik izleyin
- CT loglarını düzenli olarak gözden geçirin
- HSTS başlığını mutlaka etkinleştirin
- Özel anahtar dosyalarının izinlerini kontrol edin
SSL/TLS güvenliği, bir kez ayarlayıp unutulan bir şey değil. Sürekli izleme, düzenli güncelleme ve proaktif denetim gerektiriyor. Yukarıdaki betikleri ve araçları kendi ortamınıza uyarlayarak başlayabilirsiniz.