Apache ile Let’s Encrypt Wildcard Sertifika Kurulumu

Bir web sunucusu yönetirken en sinir bozucu anlardan biri, her subdomain için ayrı ayrı SSL sertifikası yönetmek zorunda kalmaktır. api.example.com, mail.example.com, static.example.com, admin.example.com… Liste uzayıp gider ve her birinin sertifika yenileme tarihini takip etmek başlı başına bir iş haline gelir. İşte tam bu noktada Let’s Encrypt’in wildcard sertifikaları hayat kurtarıcı oluyor. Tek bir sertifika, *.example.com formatında, tüm alt domainleri kapsıyor. Bu yazıda Apache üzerinde wildcard sertifika kurulumunu, DNS-01 challenge sürecini ve otomatik yenileme konfigürasyonunu adım adım ele alacağız.

Wildcard Sertifika Nedir ve Neden DNS-01 Gerekir?

Let’s Encrypt’in standart HTTP-01 doğrulama yöntemi, tek bir domain için gayet iyi çalışır. Certbot sunucunuza bir dosya koyar, Let’s Encrypt o dosyaya erişip doğrulama yapar ve sertifika verilir. Ama wildcard sertifikalarda bu yöntem çalışmaz.

Wildcard sertifika almak için DNS-01 challenge kullanmanız zorunludur. Bunun nedeni şu: *.example.com sertifikası almak istiyorsanız, Let’s Encrypt sizin gerçekten o domainin sahibi olduğunuzu kanıtlamanızı ister. Bunu yapmanın tek güvenilir yolu, DNS kayıtlarınıza özel bir TXT kaydı eklemektir. Yani sunucunuzun dışarıdan erişilebilir olup olmaması önemli değil, hatta port 80/443 kapalı olsa bile DNS-01 ile sertifika alabilirsiniz.

Bu yöntemin avantajları:

  • Tüm alt domainler tek sertifika: *.example.com sertifikası, sonsuz sayıda subdomain için geçerlidir
  • Sunucu erişimi gerekmez: Firewall arkasındaki sunucularda bile çalışır
  • Geliştirme ortamları: İç ağdaki sunuculara gerçek SSL sertifikası yükleyebilirsiniz

Dezavantajı ise otomasyonun biraz daha karmaşık olmasıdır. DNS sağlayıcınızın API desteği varsa her şey otomatikleştirilebilir, yoksa manuel müdahale gerekir.

Ön Hazırlık ve Gereksinimler

Başlamadan önce elinizde şunlar olmalı:

  • Ubuntu 20.04/22.04 veya CentOS/RHEL 8+ (bu yazıda Ubuntu üzerinden gideceğiz)
  • Apache 2.4+ kurulu ve çalışıyor
  • Bir domain ve DNS yönetim paneline erişim
  • Root veya sudo yetkisi

Certbot’u kurmadan önce sisteminizi güncelleyin:

sudo apt update && sudo apt upgrade -y
sudo apt install snapd -y
sudo snap install --classic certbot
sudo ln -s /snap/bin/certbot /usr/bin/certbot

Certbot kurulumunu doğrulayın:

certbot --version

DNS Sağlayıcınıza Göre Plugin Seçimi

Otomatik DNS-01 doğrulaması için DNS sağlayıcınıza özel bir Certbot plugin’i kullanmanız gerekir. Popüler sağlayıcılar için plugin listesi:

  • Cloudflare: certbot-dns-cloudflare
  • DigitalOcean: certbot-dns-digitalocean
  • Route53 (AWS): certbot-dns-route53
  • Google Cloud DNS: certbot-dns-google
  • Namecheap, GoDaddy, vb.: Manuel DNS veya üçüncü taraf araçlar

Bu yazıda en yaygın kullanılan Cloudflare üzerinden gideceğiz, ama mantık tüm sağlayıcılar için aynı.

Cloudflare API Token Oluşturma

Cloudflare paneline giriş yapın ve şu adımları izleyin:

  1. Sağ üstten profil ikonuna tıklayın, “My Profile” seçin
  2. “API Tokens” sekmesine gidin
  3. “Create Token” butonuna tıklayın
  4. “Edit zone DNS” şablonunu seçin
  5. Zone Resources kısmında sadece ilgili domaininizi seçin
  6. Token’ı oluşturun ve kopyalayın (bir daha göremezsiniz!)

Token’ı güvenli bir dosyaya kaydedin:

sudo mkdir -p /etc/letsencrypt/cloudflare
sudo nano /etc/letsencrypt/cloudflare/credentials.ini

Dosya içeriği şu şekilde olmalı:

# Cloudflare API token
dns_cloudflare_api_token = BURAYA_TOKEN_YAPIŞTIRIN

Bu dosyanın izinlerini hemen kısıtlayın, aksi halde başkaları okuyabilir:

sudo chmod 600 /etc/letsencrypt/cloudflare/credentials.ini
sudo chown root:root /etc/letsencrypt/cloudflare/credentials.ini

Bu adımı atlamayın. API token’ı başkasının eline geçerse DNS kayıtlarınız üzerinde tam kontrol sahibi olabilirler.

Certbot DNS Plugin Kurulumu

sudo snap install certbot-dns-cloudflare
sudo snap set certbot trust-plugin-with-root=ok
sudo snap connect certbot:plugin certbot-dns-cloudflare

Kurulumu test edin:

certbot plugins

Çıktıda dns-cloudflare görünüyorsa hazırsınız.

Wildcard Sertifikayı Almak

Artık sertifikayı alabiliriz. Hem ana domain (example.com) hem de wildcard (*.example.com) için aynı anda sertifika alacağız:

sudo certbot certonly 
  --dns-cloudflare 
  --dns-cloudflare-credentials /etc/letsencrypt/cloudflare/credentials.ini 
  --dns-cloudflare-propagation-seconds 60 
  -d example.com 
  -d "*.example.com" 
  --email [email protected] 
  --agree-tos 
  --no-eff-email

Parametrelerin açıklaması:

  • –dns-cloudflare: DNS-01 challenge için Cloudflare plugin’ini kullan
  • –dns-cloudflare-credentials: API token dosyasının yolu
  • –dns-cloudflare-propagation-seconds 60: DNS yayılımı için beklenecek süre (60 saniye genellikle yeterli, sorun yaşarsanız 120 yapın)
  • -d example.com: Ana domain (wildcard bunu kapsamaz, ayrıca belirtmek gerekir)
  • -d “*.example.com”: Wildcard
  • –agree-tos: Hizmet şartlarını kabul et
  • –no-eff-email: EFF’den eposta gönderilmesin

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

Successfully received certificate.
Certificate is saved at: /etc/letsencrypt/live/example.com/fullchain.pem
Key is saved at:         /etc/letsencrypt/live/example.com/privkey.pem
This certificate expires on 2024-09-15.

Apache Konfigürasyonu

Sertifikayı aldık, şimdi Apache’ye bunu tanıtmamız gerekiyor. Önce SSL modülünün etkin olduğundan emin olun:

sudo a2enmod ssl
sudo a2enmod rewrite
sudo a2enmod headers
sudo systemctl restart apache2

Şimdi bir Virtual Host konfigürasyonu oluşturalım. Diyelim ki api.example.com ve admin.example.com için ayrı uygulamalarınız var:

sudo nano /etc/apache2/sites-available/example.com-ssl.conf
# HTTP'den HTTPS'e yönlendirme
<VirtualHost *:80>
    ServerName example.com
    ServerAlias *.example.com
    RewriteEngine On
    RewriteRule ^(.*)$ https://%{HTTP_HOST}$1 [R=301,L]
</VirtualHost>

# Ana domain
<VirtualHost *:443>
    ServerName example.com
    DocumentRoot /var/www/html

    SSLEngine on
    SSLCertificateFile /etc/letsencrypt/live/example.com/fullchain.pem
    SSLCertificateKeyFile /etc/letsencrypt/live/example.com/privkey.pem

    # Güvenlik başlıkları
    Header always set Strict-Transport-Security "max-age=31536000; includeSubDomains"
    Header always set X-Content-Type-Options "nosniff"
    Header always set X-Frame-Options "SAMEORIGIN"

    ErrorLog ${APACHE_LOG_DIR}/example.com-error.log
    CustomLog ${APACHE_LOG_DIR}/example.com-access.log combined
</VirtualHost>

# API subdomain
<VirtualHost *:443>
    ServerName api.example.com
    DocumentRoot /var/www/api

    SSLEngine on
    SSLCertificateFile /etc/letsencrypt/live/example.com/fullchain.pem
    SSLCertificateKeyFile /etc/letsencrypt/live/example.com/privkey.pem

    # Proxy ayarları (Node.js, Python vb. arka plan uygulaması için)
    ProxyPreserveHost On
    ProxyPass / http://127.0.0.1:3000/
    ProxyPassReverse / http://127.0.0.1:3000/

    ErrorLog ${APACHE_LOG_DIR}/api.example.com-error.log
    CustomLog ${APACHE_LOG_DIR}/api.example.com-access.log combined
</VirtualHost>

# Admin subdomain
<VirtualHost *:443>
    ServerName admin.example.com
    DocumentRoot /var/www/admin

    SSLEngine on
    SSLCertificateFile /etc/letsencrypt/live/example.com/fullchain.pem
    SSLCertificateKeyFile /etc/letsencrypt/live/example.com/privkey.pem

    # IP kısıtlaması - sadece ofis IP'si erişebilsin
    <Directory /var/www/admin>
        Require ip 203.0.113.0/24
        Require ip 10.0.0.0/8
    </Directory>

    ErrorLog ${APACHE_LOG_DIR}/admin.example.com-error.log
    CustomLog ${APACHE_LOG_DIR}/admin.example.com-access.log combined
</VirtualHost>

Proxy modüllerine ihtiyaç varsa etkinleştirin:

sudo a2enmod proxy
sudo a2enmod proxy_http

Konfigürasyonu aktifleştirin ve test edin:

sudo a2ensite example.com-ssl.conf
sudo apache2ctl configtest
sudo systemctl reload apache2

Syntax OK görüyorsanız her şey yolunda.

SSL Güvenlik Konfigürasyonu

Varsayılan SSL ayarları çoğu zaman yeterince güvenli değildir. Modern ve güvenli bir konfigürasyon için aşağıdaki ayarları /etc/apache2/conf-available/ssl-params.conf dosyasına ekleyin:

sudo nano /etc/apache2/conf-available/ssl-params.conf
# Eski ve güvensiz protokolleri devre dışı bırak
SSLProtocol all -SSLv3 -TLSv1 -TLSv1.1

# Güçlü cipher suite'ler
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 aktif et
SSLHonorCipherOrder off

# OCSP Stapling - sertifika doğrulamayı hızlandırır
SSLUseStapling on
SSLStaplingCache "shmcb:logs/ssl_stapling(32768)"

# Session cache
SSLSessionCache shmcb:/var/run/apache2/scache(512000)
SSLSessionCacheTimeout 300

Bu konfigürasyonu etkinleştirin:

sudo a2enconf ssl-params
sudo systemctl reload apache2

SSL konfigürasyonunuzu test etmek için [SSL Labs](https://www.ssllabs.com/ssltest/) kullanabilirsiniz. Yukarıdaki ayarlarla A+ almanız gerekir.

Otomatik Yenileme Kurulumu

Let’s Encrypt sertifikaları 90 günde bir sona erer. Certbot kurulumu zaten bir systemd timer oluşturur ama wildcard sertifikalar için bunu kontrol edip düzenlememiz gerekiyor.

Mevcut timer durumunu kontrol edin:

sudo systemctl status certbot.timer
sudo systemctl list-timers | grep certbot

Yenileme konfigürasyonunu kontrol edin:

sudo cat /etc/letsencrypt/renewal/example.com.conf

Bu dosya şuna benzer görünmeli:

[renewalparams]
account = HESAP_ID
authenticator = dns-cloudflare
dns_cloudflare_credentials = /etc/letsencrypt/cloudflare/credentials.ini
dns_cloudflare_propagation_seconds = 60
server = https://acme-v02.api.letsencrypt.org/directory

Eğer bu parametreler yoksa veya yanlışsa elle düzeltebilirsiniz.

Yenileme işlemini test edin (gerçekten yenilemez, sadece test eder):

sudo certbot renew --dry-run

Çıktıda hata yoksa otomatik yenileme çalışacak demektir.

Apache’yi Otomatik Yeniden Başlatma

Sertifika yenilendiğinde Apache’nin yeni sertifikayı yüklemesi için yeniden başlatılması gerekir. Bunun için certbot’un deploy-hook özelliğini kullanın:

sudo nano /etc/letsencrypt/renewal-hooks/deploy/reload-apache.sh
#!/bin/bash
# Sertifika yenilendiğinde Apache'yi yeniden yükle
systemctl reload apache2
echo "$(date): Apache reloaded after certificate renewal" >> /var/log/certbot-deploy.log

Script’i çalıştırılabilir yapın:

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

Bu hook, her başarılı yenileme sonrasında Apache’yi otomatik olarak yeniden yükler. reload kullandık, restart değil. reload ile mevcut bağlantılar kesilmez, bu production ortamları için önemlidir.

Manuel DNS Doğrulaması (API Yoksa)

DNS sağlayıcınızın Certbot plugin’i yoksa veya API desteği sunmuyorsa manuel yöntem kullanmanız gerekir. Bu yöntemde otomatik yenileme çalışmaz ama yılda 4 kez manuel işlem yaparak idare edebilirsiniz:

sudo certbot certonly 
  --manual 
  --preferred-challenges dns 
  -d example.com 
  -d "*.example.com" 
  --email [email protected] 
  --agree-tos

Certbot size şöyle bir mesaj gösterecek:

Please deploy a DNS TXT record under the name:
_acme-challenge.example.com

with the following value:
xKBZMdBGMeQkbI6Dz0NaRsIFe4GZqc9aLXL3DeSgTs

Once this is deployed, press Enter to continue

DNS panelinize gidin, _acme-challenge.example.com için TXT kaydı ekleyin, DNS yayılmasını bekleyin (5-10 dakika), sonra Enter’a basın. İki farklı TXT değeri için iki kez yapmanız gerekebilir.

TXT kaydının yayıldığını doğrulamak için:

dig TXT _acme-challenge.example.com @8.8.8.8

Gerçek Dünya Senaryosu: E-ticaret Sitesi

Bir e-ticaret projesi üzerinde çalıştığınızı düşünün. Şu subdomainlere ihtiyacınız var:

  • www.example.com – Ana mağaza
  • api.example.com – Mobil uygulama API’si
  • cdn.example.com – Statik dosyalar
  • admin.example.com – Yönetim paneli
  • pay.example.com – Ödeme sayfası

Tek bir wildcard sertifika ile bunların hepsini karşılayabilirsiniz. Üstelik ileride blog.example.com veya support.example.com eklemek istediğinizde sertifika için hiçbir şey yapmanıza gerek yoktur.

Wildcard sertifika alındıktan sonra her subdomain için sadece bir VirtualHost bloğu yeterlidir ve hepsi aynı sertifika dosyalarını kullanır. Bu hem disk alanından tasarruf sağlar hem de yönetim kolaylığı getirir.

Sertifika Süresini İzleme

Production ortamında sertifika son kullanma tarihini izlemek kritik önemdedir. Basit bir monitoring scripti:

sudo nano /usr/local/bin/check-ssl-expiry.sh
#!/bin/bash
DOMAIN="example.com"
CERT_FILE="/etc/letsencrypt/live/${DOMAIN}/cert.pem"
DAYS_WARNING=30
ALERT_EMAIL="[email protected]"

# Sertifika son kullanma tarihini al
EXPIRY_DATE=$(openssl x509 -enddate -noout -in "$CERT_FILE" | cut -d= -f2)
EXPIRY_EPOCH=$(date -d "$EXPIRY_DATE" +%s)
NOW_EPOCH=$(date +%s)
DAYS_LEFT=$(( (EXPIRY_EPOCH - NOW_EPOCH) / 86400 ))

echo "Sertifika son kullanma: $EXPIRY_DATE"
echo "Kalan gün: $DAYS_LEFT"

if [ $DAYS_LEFT -lt $DAYS_WARNING ]; then
    echo "UYARI: Sertifika $DAYS_LEFT gün içinde sona erecek!" | 
    mail -s "SSL Sertifika Uyarısı - ${DOMAIN}" "$ALERT_EMAIL"
fi
sudo chmod +x /usr/local/bin/check-ssl-expiry.sh

Crontab’a ekleyin:

sudo crontab -e
# Her gün sabah 8'de SSL sertifika süresini kontrol et
0 8 * * * /usr/local/bin/check-ssl-expiry.sh

Yaygın Sorunlar ve Çözümleri

Rate limit hatası: Let’s Encrypt, aynı domain için haftada 5 sertifika sınırı koyar. Test sırasında --staging flag’ini kullanın:

sudo certbot certonly 
  --dns-cloudflare 
  --dns-cloudflare-credentials /etc/letsencrypt/cloudflare/credentials.ini 
  --staging 
  -d example.com 
  -d "*.example.com"

DNS yayılım sorunu: --dns-cloudflare-propagation-seconds değerini 120’ye çıkarın. Bazı DNS sağlayıcılarda yayılım daha uzun sürebilir.

Permissions hatası: Credentials dosyasının izinlerini kontrol edin. 600 olmalı, başka türlü certbot okumayı reddeder.

Apache başlamıyor: apache2ctl configtest ile konfigürasyon hatalarını bulun. Çoğunlukla sertifika dosya yolu hatalıdır.

Wildcard alt alan çalışmıyor: DNS’de *.example.com için A kaydı olduğundan emin olun. Sertifika var ama DNS kaydı yoksa subdomain erişilemez.

Sertifika bilgilerini görüntülemek ve sorun gidermek için:

# Tüm sertifikaları listele
sudo certbot certificates

# Belirli bir domain için detay
sudo openssl x509 -in /etc/letsencrypt/live/example.com/cert.pem -text -noout | grep -A 2 "Subject Alternative"

Sonuç

Apache üzerinde Let’s Encrypt wildcard sertifikası kurmak başta karmaşık görünebilir, ama bir kez doğru kurulumu yaptıktan sonra neredeyse sıfır bakım gerektiriyor. DNS-01 challenge mekanizması, API destekleyen bir DNS sağlayıcısıyla birleşince tamamen otomatik bir sertifika yaşam döngüsü elde ediyorsunuz.

Özetlemek gerekirse yapılan işlemler şunlar: Certbot ve DNS plugin’ini kurduk, DNS sağlayıcısı için API kimlik bilgilerini güvenli şekilde sakladık, tek komutla hem ana domain hem wildcard için sertifika aldık, Apache Virtual Host konfigürasyonunu tüm subdomainler için düzenledik ve otomatik yenileme ile Apache reload hook’unu ayarladık.

Production ortamında bu kurulumu tamamladıktan sonra birkaç şeyi düzenli olarak kontrol etmenizi öneririm: certbot renew --dry-run komutunu ayda bir çalıştırın, SSL Labs testi ile güvenlik skorunuzu takip edin ve sertifika son kullanma tarihlerini monitoring sisteminize ekleyin. Böyle bir altyapıyla SSL sertifikası meselesini bir daha düşünmek zorunda kalmayacaksınız.

Yorum yapın