Apache’de SSL Sertifikası Kurulumu ve Yapılandırması

Web sunucunuzda HTTPS’i aktif etmek artık bir lüks değil, zorunluluk. Tarayıcılar HTTP sitelerini “Güvenli Değil” olarak işaretliyor, Google sıralamalarında HTTPS siteleri öne çıkıyor ve kullanıcılarınızın verilerini korumak etik bir sorumluluk haline geldi. Bu yazıda Apache web sunucusunda SSL sertifikası kurulumunu, yapılandırmasını ve yaygın sorunların çözümünü adım adım ele alacağız. Hem Let’s Encrypt ile ücretsiz sertifika hem de ticari sertifika kurulumunu işleyeceğiz.

Ön Gereksinimler ve Ortam Hazırlığı

Başlamadan önce sisteminizin hazır olduğundan emin olalım. Bu rehberde Ubuntu/Debian tabanlı sistemler üzerinde çalışıyoruz, ancak RHEL/CentOS için farklılıkları da belirteceğiz.

Gereksinimler:

  • Apache 2.4 veya üzeri kurulu ve çalışıyor olmalı
  • Root veya sudo yetkisi
  • Sunucunuza yönlendirilmiş bir domain adı (A kaydı düzgün çalışmalı)
  • 80 ve 443 portları açık olmalı

Önce Apache’nin kurulu olup olmadığını ve versiyonunu kontrol edelim:

apache2 -v
# ya da RHEL/CentOS için:
httpd -v

# Servis durumunu kontrol et
systemctl status apache2

SSL modülünün aktif olup olmadığını kontrol edin:

apache2ctl -M | grep ssl

Eğer çıktıda ssl_module görmüyorsanız modülü etkinleştirmeniz gerekiyor:

# SSL modülünü etkinleştir
sudo a2enmod ssl
sudo a2enmod rewrite  # HTTP'den HTTPS'e yönlendirme için gerekli

# Apache'yi yeniden başlat
sudo systemctl restart apache2

Let’s Encrypt ile Ücretsiz SSL Sertifikası

Let’s Encrypt, otomatik sertifika yönetimi için en popüler seçenek. Certbot aracı ile kurulum inanılmaz derecede kolaylaşıyor.

Certbot Kurulumu

# Ubuntu/Debian
sudo apt update
sudo apt install certbot python3-certbot-apache -y

# RHEL/CentOS 8+
sudo dnf install certbot python3-certbot-apache -y

# Eski CentOS 7
sudo yum install epel-release -y
sudo yum install certbot python3-certbot-apache -y

Sertifika Alma ve Otomatik Yapılandırma

Certbot’un en güzel özelliği Apache yapılandırmasını otomatik olarak düzenleyebilmesi:

# Tek domain için sertifika al ve Apache'yi otomatik yapılandır
sudo certbot --apache -d siteniz.com -d www.siteniz.com

# Sadece sertifika al, Apache'ye dokunma (manuel yapılandırma için)
sudo certbot certonly --apache -d siteniz.com -d www.siteniz.com

# Wildcard sertifika için (DNS doğrulaması gerektirir)
sudo certbot certonly --manual --preferred-challenges=dns -d "*.siteniz.com" -d siteniz.com

Certbot başarılı olduğunda sertifika dosyaları /etc/letsencrypt/live/siteniz.com/ dizinine yerleştirilir:

  • fullchain.pem: Sertifika ve ara sertifikalar (chain) birleştirilmiş hali
  • privkey.pem: Özel anahtar (private key)
  • cert.pem: Sadece domain sertifikası
  • chain.pem: Ara sertifikalar

Sertifika Yenileme (Renewal) Ayarları

Let’s Encrypt sertifikaları 90 günde bir yenilenmesi gerekiyor. Certbot kurulduğunda genellikle otomatik cron veya systemd timer ayarlar, ama kontrol etmek iyi bir alışkanlık:

# Systemd timer'ı kontrol et
sudo systemctl status certbot.timer

# Timer yoksa manuel cron ekle
sudo crontab -e
# Şu satırı ekle:
0 3 * * * /usr/bin/certbot renew --quiet --post-hook "systemctl reload apache2"

# Yenileme simülasyonu yap (gerçekten yenilemez, sadece test eder)
sudo certbot renew --dry-run

Manuel SSL Sertifikası Kurulumu (Ticari Sertifikalar)

Şirket ortamlarında genellikle DigiCert, Comodo, GlobalSign gibi ticari CA’lardan sertifika satın alınır. Bu durumda süreci manuel yönetmeniz gerekir.

CSR (Certificate Signing Request) Oluşturma

# Önce private key oluştur (2048 bit minimum, 4096 bit önerilir)
sudo openssl genrsa -out /etc/ssl/private/siteniz.com.key 4096

# Private key'i sadece root okuyabilsin
sudo chmod 600 /etc/ssl/private/siteniz.com.key

# CSR oluştur
sudo openssl req -new -key /etc/ssl/private/siteniz.com.key 
  -out /etc/ssl/certs/siteniz.com.csr 
  -subj "/C=TR/ST=Istanbul/L=Istanbul/O=Sirketiniz A.S./CN=siteniz.com"

# CSR içeriğini görüntüle ve doğrula
sudo openssl req -text -noout -verify -in /etc/ssl/certs/siteniz.com.csr

CSR’ı CA’ya gönderdikten sonra size genellikle şu dosyalar gelir:

  • siteniz_com.crt: Domain sertifikanız
  • intermediate.crt veya ca-bundle.crt: Ara sertifikalar

Sertifika Dosyalarını Yerleştirme

# Sertifika dizinleri oluştur
sudo mkdir -p /etc/ssl/certs /etc/ssl/private

# Dosyaları kopyala
sudo cp siteniz_com.crt /etc/ssl/certs/siteniz.com.crt
sudo cp intermediate.crt /etc/ssl/certs/siteniz.com-chain.crt

# Tam chain dosyası oluştur (sertifika + ara sertifikalar)
sudo cat /etc/ssl/certs/siteniz.com.crt /etc/ssl/certs/siteniz.com-chain.crt 
  > /etc/ssl/certs/siteniz.com-fullchain.crt

# İzinleri ayarla
sudo chmod 644 /etc/ssl/certs/siteniz.com-fullchain.crt
sudo chmod 600 /etc/ssl/private/siteniz.com.key

Apache Virtual Host Yapılandırması

Sertifikalar hazır, şimdi Apache’ye bunları kullanmasını söylelim.

Temel SSL Virtual Host Yapılandırması

sudo nano /etc/apache2/sites-available/siteniz.com-ssl.conf

Dosya içeriği:

# HTTP'den HTTPS'e yönlendirme
<VirtualHost *:80>
    ServerName siteniz.com
    ServerAlias www.siteniz.com
    
    # 301 kalıcı yönlendirme
    RewriteEngine On
    RewriteCond %{HTTPS} off
    RewriteRule ^(.*)$ https://%{HTTP_HOST}%{REQUEST_URI} [R=301,L]
</VirtualHost>

# HTTPS Virtual Host
<VirtualHost *:443>
    ServerName siteniz.com
    ServerAlias www.siteniz.com
    
    DocumentRoot /var/www/siteniz.com/public_html
    
    # Loglama
    ErrorLog ${APACHE_LOG_DIR}/siteniz.com-error.log
    CustomLog ${APACHE_LOG_DIR}/siteniz.com-access.log combined
    
    # SSL Temel Ayarlar
    SSLEngine on
    SSLCertificateFile /etc/ssl/certs/siteniz.com.crt
    SSLCertificateKeyFile /etc/ssl/private/siteniz.com.key
    SSLCertificateChainFile /etc/ssl/certs/siteniz.com-chain.crt
    
    # Modern SSL Protokol Ayarları
    SSLProtocol all -SSLv2 -SSLv3 -TLSv1 -TLSv1.1
    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
    
    # HSTS Header (Strict Transport Security)
    Header always set Strict-Transport-Security "max-age=63072000; includeSubDomains; preload"
    
    # Güvenlik Header'ları
    Header always set X-Content-Type-Options "nosniff"
    Header always set X-Frame-Options "SAMEORIGIN"
    Header always set X-XSS-Protection "1; mode=block"
    Header always set Referrer-Policy "strict-origin-when-cross-origin"
    
    <Directory /var/www/siteniz.com/public_html>
        Options -Indexes +FollowSymLinks
        AllowOverride All
        Require all granted
    </Directory>
</VirtualHost>

Headers modülünü etkinleştirip siteyi aktif edin:

sudo a2enmod headers
sudo a2ensite siteniz.com-ssl.conf
sudo apache2ctl configtest  # Yapılandırmayı test et
sudo systemctl reload apache2

SSL Yapılandırmasını Güçlendirme

Varsayılan SSL yapılandırması yeterli güvenliği sağlamayabilir. Mozilla SSL Configuration Generator’dan önerilen ayarları kullanalım.

Global SSL Ayarları (/etc/apache2/conf-available/ssl-params.conf)

sudo nano /etc/apache2/conf-available/ssl-params.conf
# Zayıf protokolleri devre dışı bırak
SSLProtocol all -SSLv2 -SSLv3 -TLSv1 -TLSv1.1

# Modern cipher suite (Mozilla Modern profili)
SSLCipherSuite 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:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384

# Sunucu cipher tercihini kapat (client'a bırak)
SSLHonorCipherOrder off

# Session ticket'ları kapat (forward secrecy için)
SSLSessionTickets off

# OCSP Stapling - sertifika doğrulamayı hızlandırır
SSLUseStapling On
SSLStaplingCache "shmcb:logs/ssl_stapling(32768)"
SSLStaplingResponderTimeout 5
SSLStaplingReturnResponderErrors off

# DH Parameters - önceden oluşturulmuş DH parametreleri
SSLOpenSSLConfCmd DHParameters "/etc/ssl/certs/dhparam.pem"

DH parametrelerini oluşturun (bu işlem birkaç dakika sürebilir):

# 4096 bit DH parametreleri oluştur
sudo openssl dhparam -out /etc/ssl/certs/dhparam.pem 4096

# Conf dosyasını etkinleştir
sudo a2enconf ssl-params
sudo systemctl reload apache2

Sertifika Doğrulama ve Test

Kurulum sonrası her şeyin doğru çalıştığını test etmek kritik.

Komut Satırından Test

# SSL bağlantısını test et
openssl s_client -connect siteniz.com:443 -servername siteniz.com

# Sertifika son kullanma tarihini kontrol et
echo | openssl s_client -servername siteniz.com -connect siteniz.com:443 2>/dev/null | openssl x509 -noout -dates

# Desteklenen protokolleri kontrol et
nmap --script ssl-enum-ciphers -p 443 siteniz.com

# SSLyze ile kapsamlı analiz
pip install sslyze
python -m sslyze siteniz.com

# Sertifika chain'ini doğrula
openssl verify -CAfile /etc/ssl/certs/ca-certificates.crt /etc/ssl/certs/siteniz.com.crt

Tarayıcı testlerine ek olarak online araçlar kullanın:

  • SSL Labs (ssllabs.com/ssltest): A+ notu hedefleyin
  • SecurityHeaders.com: HTTP güvenlik header’larını kontrol edin
  • CryptCheck: TLS yapılandırmasını analiz edin

Apache Log’larından SSL Hatalarını İnceleme

# SSL hatalarını filtrele
sudo grep -i "ssl|tls|certificate" /var/log/apache2/error.log | tail -50

# Gerçek zamanlı log takibi
sudo tail -f /var/log/apache2/error.log | grep -i ssl

# Sertifika bilgilerini apache'den sorgula
sudo apache2ctl -S

Gerçek Dünya Senaryosu: Mixed Content Sorunu

Production’a aldığınızda en sık karşılaşılan sorun mixed content hatasıdır. HTTPS siteniz hala HTTP üzerinden kaynak yüklüyor olabilir.

Apache’de bunu header ile zorla düzeltebilirsiniz:

# Virtual host içine ekleyin
Header always set Content-Security-Policy "upgrade-insecure-requests"

Ya da .htaccess ile:

# .htaccess dosyasına ekleyin
<IfModule mod_headers.c>
    Header always set Content-Security-Policy "upgrade-insecure-requests"
</IfModule>

# HTTP'yi HTTPS'e yönlendir
RewriteEngine On
RewriteCond %{HTTPS} off
RewriteRule ^(.*)$ https://%{HTTP_HOST}%{REQUEST_URI} [R=301,L]

# www olmayan'ı www'ya yönlendir
RewriteCond %{HTTP_HOST} !^www. [NC]
RewriteRule ^(.*)$ https://www.%{HTTP_HOST}%{REQUEST_URI} [R=301,L]

Çoklu Domain ve Wildcard Sertifika Kullanımı

Birden fazla subdomain varsa wildcard sertifika çok işe yarar. Kurumsal ortamlarda *.sirket.com gibi sertifikalar yaygın kullanılır.

# Wildcard için CSR oluştur
sudo openssl req -new -key /etc/ssl/private/wildcard.sirket.com.key 
  -out /etc/ssl/certs/wildcard.sirket.com.csr 
  -subj "/C=TR/ST=Istanbul/L=Istanbul/O=Sirket A.S./CN=*.sirket.com"

# SAN (Subject Alternative Name) içeren sertifika için OpenSSL config dosyası
cat > /tmp/san.cnf << EOF
[req]
distinguished_name = req_distinguished_name
req_extensions = v3_req
prompt = no

[req_distinguished_name]
C = TR
ST = Istanbul
L = Istanbul
O = Sirket A.S.
CN = sirket.com

[v3_req]
keyUsage = keyEncipherment, dataEncipherment
extendedKeyUsage = serverAuth
subjectAltName = @alt_names

[alt_names]
DNS.1 = sirket.com
DNS.2 = www.sirket.com
DNS.3 = api.sirket.com
DNS.4 = mail.sirket.com
EOF

# SAN'lı CSR oluştur
sudo openssl req -new -key /etc/ssl/private/sirket.com.key 
  -out /etc/ssl/certs/sirket.com.csr 
  -config /tmp/san.cnf

Sertifika Sona Erme Takibi

Production ortamında en tehlikeli durum sertifikanın habersiz sona ermesidir. Monitoring eklemek şart:

#!/bin/bash
# ssl-check.sh - Sertifika sona erme kontrolü

DOMAIN=$1
THRESHOLD_DAYS=30
CERT_EXPIRY=$(echo | openssl s_client -servername $DOMAIN 
  -connect $DOMAIN:443 2>/dev/null | openssl x509 -noout -enddate | 
  cut -d= -f2)

EXPIRY_EPOCH=$(date -d "$CERT_EXPIRY" +%s)
NOW_EPOCH=$(date +%s)
DAYS_LEFT=$(( ($EXPIRY_EPOCH - $NOW_EPOCH) / 86400 ))

echo "Domain: $DOMAIN"
echo "Sertifika sona eriş: $CERT_EXPIRY"
echo "Kalan gün: $DAYS_LEFT"

if [ $DAYS_LEFT -lt $THRESHOLD_DAYS ]; then
    echo "UYARI: Sertifika $DAYS_LEFT gün içinde sona eriyor!"
    # Buraya e-posta veya Slack bildirimi ekleyebilirsiniz
    # mail -s "SSL Uyarisi: $DOMAIN" [email protected] <<< "Sertifika $DAYS_LEFT gun icinde sona eriyor!"
    exit 1
fi

exit 0

Script’i çalıştırılabilir yapın ve cron’a ekleyin:

sudo chmod +x /usr/local/bin/ssl-check.sh

# Cron'a ekle - her gün sabah 9'da kontrol et
sudo crontab -e
0 9 * * * /usr/local/bin/ssl-check.sh siteniz.com >> /var/log/ssl-check.log 2>&1

Yaygın Sorunlar ve Çözümleri

“SSL_ERROR_RX_RECORD_TOO_LONG” hatası: Genellikle 443 portuna HTTP trafiği gittiğinde oluşur. Virtual host’un doğru port’u dinlediğini kontrol edin.

“Certificate chain incomplete” uyarısı: Intermediate sertifikanızı SSLCertificateChainFile ile belirtmediğinizde ya da fullchain.pem kullanmadığınızda oluşur.

“SSL handshake failed” hatası:

# OpenSSL ile detaylı hata bilgisi al
openssl s_client -connect siteniz.com:443 -debug 2>&1 | head -100

# Apache hata logunu kontrol et
sudo journalctl -u apache2 --since "1 hour ago" | grep -i ssl

Private key ve sertifika uyuşmuyor:

# Private key modulus
openssl rsa -noout -modulus -in /etc/ssl/private/siteniz.com.key | md5sum

# Sertifika modulus
openssl x509 -noout -modulus -in /etc/ssl/certs/siteniz.com.crt | md5sum

# İkisi aynıysa eşleşiyordur

İzin sorunları:

# Doğru izinleri ayarla
sudo chown root:root /etc/ssl/private/siteniz.com.key
sudo chmod 600 /etc/ssl/private/siteniz.com.key
sudo chown root:root /etc/ssl/certs/siteniz.com.crt
sudo chmod 644 /etc/ssl/certs/siteniz.com.crt

Sonuç

Apache’de SSL kurulumu görünürde basit ama ince noktaları olan bir süreç. Sertifikayı kurmak işin yalnızca ilk adımı. Zayıf cipher’ları devre dışı bırakmak, HSTS header’ı eklemek, OCSP stapling’i aktif etmek ve sertifika yenilemeyi otomatikleştirmek production ortamı için vazgeçilmez adımlar.

Let’s Encrypt ile başlangıç seviyesinde ücretsiz ve hızlı bir şekilde HTTPS’e geçebilirsiniz. Kurumsal ortamlarda ise ticari sertifikalar ve wildcard kullanımı daha pratik olabiliyor. Her iki durumda da SSL Labs’dan A+ notu almayı hedefleyin ve sertifika sona erme takibini mutlaka monitörinize ekleyin. Bir sertifikanın habersiz sona ermesi, saatlerce süren production kesintisine dönüşebilir ve bunu yaşayan herkes bir kez yeterli oluyor.

Yorum yapın