Zayıf SSL Yapılandırmalarını Tespit Etme: sslyze ve testssl.sh Kullanımı

SSL/TLS yapılandırma hataları, güvenlik açıklarının en sık karşılaşılan ve aynı zamanda en kolay gözden kaçan türlerinden biri. Bir sunucuyu yıllarca çalıştırabilirsin, her şey “çalışıyor” görünür, ama arka planda BEAST, POODLE veya Heartbleed gibi açıklara kapı aralayan eski protokoller ve zayıf cipher suite’ler sessizce bekliyordur. Bu yazıda, SSL/TLS yapılandırmalarını derinlemesine analiz etmek için kullanılan iki güçlü aracı, sslyze ve testssl.sh‘yi ele alacağız. Sadece kurulum ve temel kullanım değil, gerçek senaryolarda nasıl işe yaradıklarını da göreceğiz.

SSL/TLS Güvenliği Neden Bu Kadar Önemli?

Yönettiğin bir web sunucusunda HTTPS çalışıyor diye her şeyin yolunda olduğunu düşünmek çok yaygın bir hata. Sertifika var, kilit ikonu görünüyor, tamam değil mi? Hayır, değil.

Birkaç gerçek hayat senaryosu düşün:

  • Üç yıl önce kurduğun Nginx sunucusu hala TLS 1.0 destekliyor
  • PCI-DSS denetimine giriyorsun ve auditor SSLv3 desteklendiğini buluyor
  • HSTS header yok, downgrade attack’a açıksın
  • RC4 cipher’ları hala aktif çünkü eski bir Java client ile uyumluluk için “geçici olarak” açık bırakılmış

Bu tür sorunları bulmak için iki farklı yaklaşım sunan araçlara ihtiyacın var: hem programatik olarak kullanabileceğin Python tabanlı sslyze, hem de bash ortamında dependency gerektirmeden çalışan testssl.sh.

sslyze Nedir ve Nasıl Kurulur?

sslyze, Python ile yazılmış, SSL/TLS sunucu analizi için geliştirilmiş açık kaynaklı bir araç. Nabp Labs tarafından geliştiriliyor ve özellikle otomasyona entegre etmek istediğinde çok işe yarıyor. JSON çıktısı alabilmesi, CI/CD pipeline’larına kolayca dahil edilmesini sağlıyor.

Kurulum

# pip ile kurulum (Python 3.7+ gerekli)
pip3 install sslyze

# Veya pipx ile izole ortamda
pipx install sslyze

# Kurulumu doğrula
sslyze --version

Kali Linux veya Parrot OS kullanıyorsan muhtemelen zaten kurulu gelir, ama versiyonu kontrol etmeni öneririm çünkü paket repo’daki versiyon güncel olmayabilir.

# Kali için güncel versiyon
pip3 install --upgrade sslyze

Temel Kullanım

# Temel tarama - tüm plugin'leri çalıştırır
sslyze hedefsite.com

# Belirli port ile tarama
sslyze hedefsite.com:8443

# JSON formatında çıktı al
sslyze --json_out sonuc.json hedefsite.com

# Birden fazla hedef tara
sslyze hedef1.com hedef2.com hedef3.com

# Sadece sertifika bilgisini kontrol et
sslyze --certinfo hedefsite.com

Önemli sslyze Parametreleri

–certinfo: Sertifika zinciri, geçerlilik tarihi, OCSP durumu gibi detayları getirir

–sslv2: SSLv2 protokolünün desteklenip desteklenmediğini test eder

–sslv3: SSLv3 desteğini (POODLE açığı) kontrol eder

–tlsv1: TLS 1.0 desteğini kontrol eder

–tlsv1_1: TLS 1.1 desteğini kontrol eder

–tlsv1_2: TLS 1.2 desteğini kontrol eder

–tlsv1_3: TLS 1.3 desteğini kontrol eder

–heartbleed: Heartbleed (CVE-2014-0160) açığını test eder

–robot: ROBOT saldırısına karşı açık olup olmadığını kontrol eder

–reneg: Güvensiz renegotiation desteğini test eder

–resum: Session resumption davranışını analiz eder

–http_headers: HSTS ve güvenlik header’larını kontrol eder

–early_data: TLS 1.3 early data (0-RTT) desteğini test eder

–elliptic_curves: Desteklenen elliptic curve’leri listeler

–json_out: Çıktıyı JSON formatında dosyaya yazar

Gerçek Senaryo: Toplu Sunucu Taraması

Diyelim ki şirketinde 20-30 tane subdomain var ve hepsinin SSL yapılandırmasını kontrol etmen gerekiyor. Bunu manuel yapmak yerine bir script ile otomatize edebilirsin:

#!/bin/bash
# ssl_audit.sh - Toplu SSL denetimi

TARGETS_FILE="hedefler.txt"
SONUC_DIR="ssl_audit_$(date +%Y%m%d)"
mkdir -p $SONUC_DIR

while IFS= read -r hedef; do
    echo "[*] Taraniyor: $hedef"
    sslyze --certinfo --heartbleed --robot 
           --sslv2 --sslv3 --tlsv1 --tlsv1_1 
           --http_headers 
           --json_out "${SONUC_DIR}/${hedef////_}.json" 
           "$hedef" 2>/dev/null
    
    # Kritik sorunları hemen ekrana bas
    if grep -q '"is_vulnerable_to_heartbleed": true' "${SONUC_DIR}/${hedef////_}.json" 2>/dev/null; then
        echo "[KRITIK] $hedef - Heartbleed acigi tespit edildi!"
    fi
    
    sleep 1  # Rate limiting
done < "$TARGETS_FILE"

echo "[+] Tarama tamamlandi. Sonuclar: $SONUC_DIR"

Bu script’i cron’a bağlayarak haftalık çalıştırabilirsin. Eğer kritik bir değişiklik varsa, output’u grep’leyip mail at.

sslyze JSON Çıktısını Parse Etme

# Python ile JSON analizi
python3 << 'EOF'
import json
import sys

with open('sonuc.json') as f:
    data = json.load(f)

for server_scan in data['server_scan_results']:
    hostname = server_scan['server_location']['hostname']
    
    # Scan hatasi var mi kontrol et
    if server_scan['scan_status'] == 'ERROR':
        print(f"HATA: {hostname} taranamadi")
        continue
    
    scan_result = server_scan['scan_result']
    
    # SSL 3.0 kontrolu
    ssl3 = scan_result.get('ssl_3_0_cipher_suites', {})
    if ssl3.get('status') == 'COMPLETED':
        accepted = ssl3['result'].get('accepted_cipher_suites', [])
        if accepted:
            print(f"UYARI [{hostname}]: SSLv3 destekleniyor! ({len(accepted)} cipher)")
    
    # Heartbleed kontrolu
    hb = scan_result.get('heartbleed', {})
    if hb.get('status') == 'COMPLETED':
        if hb['result'].get('is_vulnerable_to_heartbleed'):
            print(f"KRITIK [{hostname}]: Heartbleed acigi mevcut!")
    
    print(f"OK: {hostname} analizi tamamlandi")
EOF

testssl.sh Nedir ve Nasıl Kullanılır?

testssl.sh, herhangi bir Python veya özel kütüphane bağımlılığı olmadan çalışan, bash tabanlı bir SSL/TLS test aracı. Sadece OpenSSL (veya bazı durumlarda dahili olarak derlenmiş bir binary) kullanarak son derece kapsamlı testler yapabiliyor. Özellikle hedef sistemde sadece bash ve openssl varsa ya da tam anlamıyla portable bir çözüm istiyorsan tercih edilmeli.

Kurulum

# GitHub'dan indirme
git clone --depth 1 https://github.com/drwetter/testssl.sh.git
cd testssl.sh

# Direkt çalıştır
./testssl.sh --version

# Sisteme kur (opsiyonel)
sudo cp testssl.sh /usr/local/bin/
sudo chmod +x /usr/local/bin/testssl.sh

Kali’de apt ile de kurabilirsin:

sudo apt install testssl.sh

Ama yine söylüyorum, GitHub versiyonu her zaman daha güncel. SSL/TLS dünyası hızlı değişiyor ve araçların da güncel olması kritik.

testssl.sh Temel Kullanım

# Tam tarama (tüm testleri çalıştır)
testssl.sh hedefsite.com

# HTTPS için port belirt (default 443)
testssl.sh hedefsite.com:443

# STARTTLS ile SMTP taraması
testssl.sh --starttls smtp mail.sirket.com:25

# STARTTLS ile IMAP
testssl.sh --starttls imap mail.sirket.com:143

# Sadece protokol testleri
testssl.sh --protocols hedefsite.com

# Sadece cipher testleri
testssl.sh --ciphers hedefsite.com

# Sadece açık testleri
testssl.sh --vulnerabilities hedefsite.com

Önemli testssl.sh Parametreleri

–protocols: Desteklenen SSL/TLS protokol versiyonlarını listeler

–ciphers: Tüm desteklenen cipher suite’leri test eder

–cipher-per-proto: Her protokol için ayrı ayrı cipher listesi çıkarır

–server-defaults: Sunucunun varsayılan ayarlarını gösterir

–server-preference: Sunucunun cipher tercihi sırasını analiz eder

–vulnerabilities: Bilinen açıkları (BEAST, BREACH, ROBOT, vb.) kontrol eder

–heartbleed: Sadece Heartbleed testini çalıştırır

–ccs: CCS Injection (CVE-2014-0224) açığını test eder

–ticketbleed: Ticketbleed açığını test eder

–robot: ROBOT açığını test eder

–beast: BEAST açığını test eder

–lucky13: LUCKY13 açığını test eder

–poodle: POODLE açığını test eder

–freak: FREAK açığını test eder

–logjam: Logjam açığını test eder

–drown: DROWN açığını test eder

–headers: HTTP güvenlik header’larını (HSTS, HPKP, vb.) kontrol eder

–starttls: STARTTLS protokolü ile bağlanır (smtp, imap, ftp gibi servisler için)

–html: Sonuçları HTML rapor olarak kaydeder

–jsonfile: JSON formatında çıktı dosyası belirtir

–csvfile: CSV formatında çıktı dosyası belirtir

–logfile: Log dosyası belirtir

–severity: Minimum severity seviyesi (LOW, MEDIUM, HIGH, CRITICAL)

–quiet: Başlık bilgilerini gizler, sadece bulgular gösterilir

Gerçek Senaryo: PCI-DSS Uyumluluk Kontrolü

PCI-DSS uyumluluğu için TLS 1.0 ve 1.1’i devre dışı bırakman, zayıf cipher’ları kaldırman gerekiyor. testssl.sh bunu çok güzel raporluyor:

#!/bin/bash
# pci_ssl_check.sh

TARGET=$1
RAPOR_DIR="pci_raporlar"
TARIH=$(date +%Y%m%d_%H%M%S)

if [ -z "$TARGET" ]; then
    echo "Kullanim: $0 <hedef:port>"
    exit 1
fi

mkdir -p $RAPOR_DIR

echo "[*] PCI-DSS SSL kontrolu basliyor: $TARGET"

testssl.sh 
    --protocols 
    --cipher-per-proto 
    --vulnerabilities 
    --headers 
    --severity MEDIUM 
    --jsonfile "${RAPOR_DIR}/pci_${TARGET//[:/.]/}_${TARIH}.json" 
    --htmlfile "${RAPOR_DIR}/pci_${TARGET//[:/.]/}_${TARIH}.html" 
    --logfile "${RAPOR_DIR}/pci_${TARGET//[:/.]/}_${TARIH}.log" 
    "$TARGET"

echo "[+] Rapor olusturuldu: ${RAPOR_DIR}/"

# TLS 1.0/1.1 uyari kontrolu
if grep -q '"TLSv1"' "${RAPOR_DIR}/pci_${TARGET//[:/.]/}_${TARIH}.json" 2>/dev/null; then
    echo "[UYARI] TLS 1.0 aktif - PCI-DSS uyumsuzlugu!"
fi

STARTTLS Servisleri Test Etme

Sysadminlerin çoğu sadece HTTPS’i test ediyor ama SMTP, IMAP, POP3 gibi servislerdeki SSL yapılandırmaları da en az web sunucu kadar önemli. Özellikle mail sunucuları çoğu zaman unutuluyor:

# Mail sunucusu tam SSL denetimi
testssl.sh --starttls smtp mail.sirket.com:25
testssl.sh --starttls smtp mail.sirket.com:587
testssl.sh --starttls imap mail.sirket.com:143
testssl.sh --starttls pop3 mail.sirket.com:110

# Direkt SSL portlari
testssl.sh mail.sirket.com:993  # IMAPS
testssl.sh mail.sirket.com:995  # POP3S
testssl.sh mail.sirket.com:465  # SMTPS

Geçen ay bir müşteride incelemek için fırsat bulduğumda, web sunucularının tamamen temiz olduğunu ama SMTP sunucusunun hala TLS 1.0 ile SSLv3 desteklediğini gördüm. Klasik “web’e baktık, mail’i unuttuk” durumu.

İki Aracı Karşılaştırmak ve Ne Zaman Hangisini Kullanmak

Her iki araç da güçlü ama farklı senaryolar için daha uygun olabiliyor.

sslyze’ı tercih et eğer:

  • Sonuçları programatik olarak işleyeceksen (JSON parse, API entegrasyonu)
  • CI/CD pipeline’ına SSL taraması ekleyeceksen
  • Büyük ölçekli otomasyon yazıyorsan
  • Python ekosistemiyle çalışıyorsan

testssl.sh’yi tercih et eğer:

  • İnsan tarafından okunabilir, renkli bir terminal çıktısı istiyorsan
  • Bağımlılık olmadan çalışması gerekiyorsa
  • STARTTLS servislerini test edeceksen
  • HTML veya CSV rapor almak istiyorsan
  • Hızlı ve pratik bir denetim yapacaksan

Gerçekte ben ikisini birlikte kullanıyorum. testssl.sh ile hızlı görsel kontrol yapıp, sslyze ile otomasyon yazıyorum.

Bulguları Yorumlamak ve Aksiyon Almak

Araçları çalıştırdın, çıktıyı aldın. Peki ne yapacaksın?

Kritik Bulgular ve Çözümleri

SSLv2/SSLv3 Aktif

Nginx için:

# /etc/nginx/nginx.conf veya site konfigürasyonu
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;

# HSTS ekle
add_header Strict-Transport-Security "max-age=63072000; includeSubDomains; preload" always;

Apache için:

# /etc/apache2/sites-available/sirket.conf
SSLProtocol -all +TLSv1.2 +TLSv1.3
SSLCipherSuite ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384
SSLHonorCipherOrder off
SSLSessionTickets off

Header always set Strict-Transport-Security "max-age=63072000; includeSubDomains; preload"

Değişiklik sonrası hemen test et:

# Duzeltme sonrasi dogrulama
testssl.sh --protocols hedefsite.com
sslyze --sslv2 --sslv3 --tlsv1 hedefsite.com

Otomatik Günlük Kontrol Script’i

#!/bin/bash
# daily_ssl_check.sh - Cron ile gunluk calistir
# Cron: 0 6 * * * /opt/scripts/daily_ssl_check.sh

HEDEFLER=("api.sirket.com:443" "www.sirket.com:443" "mail.sirket.com:993")
MAIL_TO="[email protected]"
LOG="/var/log/ssl_check_$(date +%Y%m%d).log"
SORUN=0

for hedef in "${HEDEFLER[@]}"; do
    SONUC=$(sslyze --certinfo --sslv2 --sslv3 --tlsv1 
                   --heartbleed --json_out /tmp/ssl_tmp.json 
                   "$hedef" 2>&1)
    
    # Sertifika bitis tarihini kontrol et
    EXPIRY=$(python3 -c "
import json, datetime
with open('/tmp/ssl_tmp.json') as f:
    d = json.load(f)
try:
    cert = d['server_scan_results'][0]['scan_result']['certificate_info']['result']['certificate_deployments'][0]['received_certificate_chain'][0]
    expiry = cert['not_valid_after']
    exp_date = datetime.datetime.strptime(expiry, '%Y-%m-%dT%H:%M:%S')
    days_left = (exp_date - datetime.datetime.now()).days
    print(days_left)
except:
    print('ERROR')
" 2>/dev/null)
    
    if [[ "$EXPIRY" =~ ^[0-9]+$ ]] && [ "$EXPIRY" -lt 30 ]; then
        echo "[UYARI] $hedef - Sertifika $EXPIRY gun icinde sona eriyor!" | tee -a $LOG
        SORUN=1
    fi
    
    echo "[$hedef] Kontrol tamamlandi" >> $LOG
done

if [ $SORUN -eq 1 ]; then
    mail -s "SSL Uyari - $(date +%Y-%m-%d)" $MAIL_TO < $LOG
fi

rm -f /tmp/ssl_tmp.json

Yaygın Tuzaklar ve Dikkat Edilmesi Gerekenler

Zaman Aşımı Sorunları: Bazı yük dengeleyiciler veya WAF’lar art arda gelen SSL bağlantı denemelerini blokluyor. testssl.sh’ye --connect-timeout ve --openssl-timeout parametrelerini vermek mantıklı.

İç Ağ vs. Dış Ağ Farkı: İç ağdan test ettiğinde farklı sonuçlar alabilirsin. Bir load balancer varsa, dış trafiği başka bir şekilde handle ediyor olabilir. Mümkünse hem iç hem dış ağdan test et.

Test Edilecek Portları Unutmak: 443 dışında 8443, 8080 (bazen HTTPS), 9443 gibi portları da kontrol et. Özellikle uygulama sunucuları (Tomcat, WebSphere) kendi portlarında çalışıyor.

Wildcard Sertifikaları Kötüye Kullanımı: Tarama sırasında aynı sertifikayı kullanan ama farklı yapılandırmalara sahip birden fazla subdomain görebilirsin. Her birini ayrı ayrı test etmek gerek.

False Positive’ler: Özellikle eski OpenSSL versiyonları bazı testlerde yanlış sonuç verebiliyor. sslyze veya testssl.sh şüpheli bir bulgu gösterdiğinde, bunu ikinci bir araçla doğrula.

Sonuç

SSL/TLS güvenliği “bir kere kur, unut” meselesi değil. Yeni açıklar keşfediliyor, protokol versiyonları deprecated oluyor, cipher suite’ler zayıf bululuyor. Dolayısıyla bu taramaları düzenli olarak yapmak gerekiyor.

sslyze ve testssl.sh, birbirini tamamlayan iki araç olarak workflow’una girdiğinde çok güçlü bir denetim mekanizması elde ediyorsun. testssl.sh’nin renkli, insan gözüne hitap eden çıktısını hızlı kontroller için kullanırken, sslyze’ın JSON çıktısını otomasyon ve trend analizi için kullanmak en verimli yaklaşım.

Önerdiğim minimum senaryo şu: Her ay tam tarama, her gün sertifika son kullanma tarihi kontrolü, her deployment sonrası protokol ve cipher kontrolü. Bu üçünü otomatize ettiğinde, SSL kaynaklı güvenlik olaylarını neredeyse sıfıra indirebilirsin. Ve emin ol, bir gün auditor geldiğinde ya da bir açık duyurusu çıktığında, “biz zaten tarıyoruz” diyebilmek paha biçilemez bir rahatlık.

Yorum yapın