Bir web altyapısı yönetiyorsunuz ve onlarca subdomain’iniz var: app.sirket.com, api.sirket.com, mail.sirket.com, dev.sirket.com… Her biri için ayrı SSL sertifikası almak hem pahalı hem de yönetimi kabusa çeviren bir süreç. İşte tam bu noktada wildcard SSL sertifikaları hayat kurtarıcı oluyor. Tek bir sertifika ile bir domain’in tüm alt domainlerini kapsayabiliyorsunuz. Bu yazıda wildcard SSL’i derinlemesine inceleyecek, Let’s Encrypt ile ücretsiz nasıl alabileceğinizi ve production ortamında nasıl kuracağınızı adım adım göstereceğim.
Wildcard SSL Sertifikası Nedir?
Standart bir SSL sertifikası yalnızca belirtilen domain için geçerlidir. sirket.com için aldığınız sertifika www.sirket.com için de çalışabilir ama api.sirket.com için artık geçersiz sayılır. Wildcard sertifikaları ise *.sirket.com şeklinde tanımlanarak o domain’in bir seviye altındaki tüm subdomain’leri kapsar.
Önemli bir nokta: Wildcard sertifikası yalnızca bir seviye derinliği kapsar. Yani *.sirket.com sertifikası şunları kapsar:
app.sirket.comapi.sirket.commail.sirket.comdev.sirket.comstaging.sirket.com
Ama şunları kapsamaz:
sirket.com(apex domain, ayrıca eklenmelidir)v2.api.sirket.com(iki seviye derinlik)test.app.sirket.com(iki seviye derinlik)
Bu sınırlamayı göz önünde bulundurarak altyapınızı planlamanız gerekiyor. Eğer iç içe subdomain yapınız varsa, o seviye için ayrı bir wildcard sertifikası (*.api.sirket.com gibi) almanız gerekecek.
Let’s Encrypt ile Ücretsiz Wildcard Sertifika
Let’s Encrypt, 2018’den itibaren wildcard sertifikalarını destekliyor. Ancak standart HTTP doğrulaması (HTTP-01 challenge) wildcard için çalışmıyor. Bunun yerine DNS-01 challenge kullanmanız zorunlu.
DNS-01 challenge mantığı şu şekilde: Sertifika otoritesi size bir token veriyor, siz bu token’ı DNS TXT kaydı olarak ekliyorsunuz, CA da DNS’i sorgulayarak domain sahibi olduğunuzu doğruluyor.
Certbot Kurulumu
Ubuntu/Debian sistemlerde:
sudo apt update
sudo apt install certbot python3-certbot-dns-cloudflare -y
# Versiyonu kontrol et
certbot --version
CentOS/RHEL sistemlerde:
sudo dnf install epel-release -y
sudo dnf install certbot python3-certbot-dns-cloudflare -y
Manuel DNS Doğrulama ile Wildcard Sertifika Alma
DNS sağlayıcınızın Certbot plugin’i yoksa manuel yöntemi kullanabilirsiniz. Bu yöntem otomatik yenileme için uygun değil ama kavramı anlamak için mükemmel:
sudo certbot certonly
--manual
--preferred-challenges dns
-d "sirket.com"
-d "*.sirket.com"
Bu komutu çalıştırdığınızda Certbot size şöyle bir çıktı verecek:
Please deploy a DNS TXT record under the name:
_acme-challenge.sirket.com
with the following value:
xK3mN9pQ2rT5vW8yB1cE4hJ7nM0sR3uV6wA9bD2fG5iL
DNS paneline gidip bu TXT kaydını ekliyorsunuz, sonra Enter’a basıyorsunuz. Birkaç dakika beklemek gerekebilir çünkü DNS propagasyonu zaman alıyor.
Cloudflare DNS Plugin ile Otomatik Wildcard Sertifika
Production ortamı için otomatik yenileme şart. Cloudflare kullanıyorsanız bu işi çok temiz yapabilirsiniz:
# Cloudflare API token için credentials dosyası oluştur
sudo mkdir -p /etc/letsencrypt/cloudflare
sudo nano /etc/letsencrypt/cloudflare/credentials.ini
Dosya içeriği:
# Cloudflare API token (önerilen yöntem)
dns_cloudflare_api_token = YOUR_CLOUDFLARE_API_TOKEN_HERE
Güvenlik için dosya izinlerini kısıtlayın:
sudo chmod 600 /etc/letsencrypt/cloudflare/credentials.ini
sudo chown root:root /etc/letsencrypt/cloudflare/credentials.ini
Şimdi sertifikayı alın:
sudo certbot certonly
--dns-cloudflare
--dns-cloudflare-credentials /etc/letsencrypt/cloudflare/credentials.ini
--dns-cloudflare-propagation-seconds 30
-d "sirket.com"
-d "*.sirket.com"
--email [email protected]
--agree-tos
--non-interactive
Başarılı bir çıktı şöyle görünür:
Successfully received certificate.
Certificate is saved at: /etc/letsencrypt/live/sirket.com/fullchain.pem
Key is saved at: /etc/letsencrypt/live/sirket.com/privkey.pem
This certificate expires on 2024-06-15.
These files will be updated when the certificate renews.
Nginx’te Wildcard SSL Yapılandırması
Sertifikayı aldıktan sonra web sunucunuza entegre etmeniz gerekiyor. Gerçek hayatta sıkça gördüğüm senaryo şu: Birden fazla subdomain farklı backend servislere proxy geçiyor.
Temel Nginx SSL Bloğu
sudo nano /etc/nginx/conf.d/sirket.com.conf
# HTTP'den HTTPS'e yönlendirme
server {
listen 80;
server_name sirket.com *.sirket.com;
return 301 https://$host$request_uri;
}
# Ana domain
server {
listen 443 ssl http2;
server_name sirket.com;
ssl_certificate /etc/letsencrypt/live/sirket.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/sirket.com/privkey.pem;
# Modern TLS ayarları
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;
ssl_prefer_server_ciphers off;
ssl_session_timeout 1d;
ssl_session_cache shared:SSL:10m;
ssl_stapling on;
ssl_stapling_verify on;
# HSTS başlığı
add_header Strict-Transport-Security "max-age=63072000; includeSubDomains; preload" always;
root /var/www/sirket.com;
index index.html;
location / {
try_files $uri $uri/ =404;
}
}
# API subdomain - Node.js backend'e proxy
server {
listen 443 ssl http2;
server_name api.sirket.com;
ssl_certificate /etc/letsencrypt/live/sirket.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/sirket.com/privkey.pem;
ssl_protocols TLSv1.2 TLSv1.3;
ssl_ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256;
ssl_prefer_server_ciphers off;
location / {
proxy_pass http://127.0.0.1:3000;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection 'upgrade';
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_cache_bypass $http_upgrade;
}
}
Yapılandırmayı test edip yükleyin:
sudo nginx -t
sudo systemctl reload nginx
Wildcard Subdomain ile Dinamik Proxy
Daha gelişmiş bir senaryo: Subdomain adına göre otomatik routing yapan bir yapı. Örneğin bir SaaS ürününde her müşterinin kendi subdomaini var.
# Dinamik subdomain routing
server {
listen 443 ssl http2;
server_name ~^(?P<tenant>[^.]+).sirket.com$;
ssl_certificate /etc/letsencrypt/live/sirket.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/sirket.com/privkey.pem;
ssl_protocols TLSv1.2 TLSv1.3;
ssl_prefer_server_ciphers off;
location / {
proxy_pass http://127.0.0.1:8080;
proxy_set_header X-Tenant-ID $tenant;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}
}
Bu yapıda musteri1.sirket.com ve musteri2.sirket.com gibi tüm subdomain’ler aynı backend’e gidiyor, ama X-Tenant-ID header’ı sayesinde backend hangi müşteriyle konuştuğunu biliyor.
Apache’de Wildcard SSL Yapılandırması
Apache kullanan sistemler için de temel yapılandırmayı görelim:
sudo nano /etc/apache2/sites-available/sirket.com-ssl.conf
<VirtualHost *:80>
ServerName sirket.com
ServerAlias *.sirket.com
Redirect permanent / https://sirket.com/
</VirtualHost>
<VirtualHost *:443>
ServerName sirket.com
DocumentRoot /var/www/sirket.com
SSLEngine on
SSLCertificateFile /etc/letsencrypt/live/sirket.com/fullchain.pem
SSLCertificateKeyFile /etc/letsencrypt/live/sirket.com/privkey.pem
SSLProtocol all -SSLv3 -TLSv1 -TLSv1.1
SSLCipherSuite ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256
SSLHonorCipherOrder off
SSLSessionTickets off
Header always set Strict-Transport-Security "max-age=63072000"
</VirtualHost>
<VirtualHost *:443>
ServerName api.sirket.com
SSLEngine on
SSLCertificateFile /etc/letsencrypt/live/sirket.com/fullchain.pem
SSLCertificateKeyFile /etc/letsencrypt/live/sirket.com/privkey.pem
SSLProtocol all -SSLv3 -TLSv1 -TLSv1.1
SSLCipherSuite ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256
ProxyPreserveHost On
ProxyPass / http://127.0.0.1:3000/
ProxyPassReverse / http://127.0.0.1:3000/
</VirtualHost>
sudo a2enmod ssl headers proxy proxy_http
sudo a2ensite sirket.com-ssl.conf
sudo apache2ctl configtest
sudo systemctl reload apache2
Otomatik Yenileme Kurulumu
Let’s Encrypt sertifikaları 90 günde bir yenilenmesi gerekiyor. Bunu otomatik hale getirmek için systemd timer veya cron kullanabilirsiniz.
Systemd Timer ile Otomatik Yenileme
Modern Linux sistemlerde certbot kurulumu zaten bir systemd timer ekliyor. Durumunu kontrol edin:
sudo systemctl status certbot.timer
sudo systemctl list-timers | grep certbot
Timer aktif değilse etkinleştirin:
sudo systemctl enable certbot.timer
sudo systemctl start certbot.timer
Yenileme sonrası nginx’i otomatik reload etmek için hook ekleyin:
sudo nano /etc/letsencrypt/renewal-hooks/post/reload-nginx.sh
#!/bin/bash
# Sertifika yenilendikten sonra nginx'i yeniden yükle
systemctl reload nginx
echo "$(date): Nginx reloaded after certificate renewal" >> /var/log/certbot-renewal.log
sudo chmod +x /etc/letsencrypt/renewal-hooks/post/reload-nginx.sh
Yenileme Testini Yapın
# Dry-run ile test et (gerçekten yenilemez, sadece simüle eder)
sudo certbot renew --dry-run
# Çıktıyı kontrol et
sudo certbot certificates
Sertifika Doğrulama ve Test
Kurulumun doğru çalıştığını birkaç farklı şekilde kontrol edebilirsiniz.
Komut Satırından Test
# Temel SSL bağlantı testi
openssl s_client -connect sirket.com:443 -servername sirket.com
# Sertifika bilgilerini görüntüle
echo | openssl s_client -connect sirket.com:443 -servername sirket.com 2>/dev/null | openssl x509 -noout -text | grep -E "Subject|DNS:|Not Before|Not After"
# Wildcard'ın subdomain için geçerli olduğunu test et
echo | openssl s_client -connect api.sirket.com:443 -servername api.sirket.com 2>/dev/null | openssl x509 -noout -subject -dates
# TLS versiyonunu kontrol et
openssl s_client -connect sirket.com:443 -tls1_2
openssl s_client -connect sirket.com:443 -tls1_3
SSL Labs ile Kapsamlı Test
Production’a almadan önce Qualys SSL Labs üzerinden test yapmanızı şiddetle öneririm. A+ rating almak için şu kontrolleri yapın:
# HSTS başlığını kontrol et
curl -sI https://sirket.com | grep -i strict
# Sertifika zincirini doğrula
openssl verify -CAfile /etc/ssl/certs/ca-certificates.crt /etc/letsencrypt/live/sirket.com/fullchain.pem
# Sertifika son kullanma tarihini izle
echo | openssl s_client -connect sirket.com:443 2>/dev/null | openssl x509 -noout -enddate
Yaygın Sorunlar ve Çözümleri
DNS Propagasyon Sorunu
En sık karşılaşılan sorun, DNS TXT kaydı henüz yayılmadan doğrulama girişiminde bulunmak. Cloudflare plugin kullanıyorsanız --dns-cloudflare-propagation-seconds değerini 60’a çıkarabilirsiniz:
sudo certbot certonly
--dns-cloudflare
--dns-cloudflare-credentials /etc/letsencrypt/cloudflare/credentials.ini
--dns-cloudflare-propagation-seconds 60
-d "sirket.com"
-d "*.sirket.com"
Rate Limit Sorunu
Let’s Encrypt’in haftalık rate limitleri var. Test sürecinde aynı domain için çok fazla deneme yaptıysanız bir hafta beklemeniz gerekebilir. Bu yüzden geliştirme ve test aşamasında her zaman --staging parametresini kullanın:
sudo certbot certonly
--dns-cloudflare
--dns-cloudflare-credentials /etc/letsencrypt/cloudflare/credentials.ini
-d "sirket.com"
-d "*.sirket.com"
--staging
Sertifika Dosyası İzin Sorunları
Nginx veya Apache’nin sertifika dosyalarına erişememesi durumunda:
# Dosya izinlerini kontrol et
ls -la /etc/letsencrypt/live/sirket.com/
ls -la /etc/letsencrypt/archive/sirket.com/
# Archive dizini için gerekli izinler
sudo chmod 755 /etc/letsencrypt/live/
sudo chmod 755 /etc/letsencrypt/archive/
sudo chmod 644 /etc/letsencrypt/archive/sirket.com/fullchain*.pem
sudo chmod 600 /etc/letsencrypt/archive/sirket.com/privkey*.pem
Ticari Wildcard Sertifika Kullanımı
Let’s Encrypt her senaryoda uygun olmayabilir. Özellikle organizasyonel doğrulama (OV) veya genişletilmiş doğrulama (EV) gerektiren durumlarda ticari sertifika satın almanız gerekir. Bu durumda CSR (Certificate Signing Request) oluşturmanız gerekiyor:
# Private key oluştur
openssl genrsa -out sirket.com.key 4096
# Wildcard için CSR oluştur
openssl req -new
-key sirket.com.key
-out sirket.com.csr
-subj "/C=TR/ST=Istanbul/L=Istanbul/O=Sirket AS/OU=IT/CN=*.sirket.com"
# CSR içeriğini kontrol et
openssl req -text -noout -verify -in sirket.com.csr
# CSR içeriğini kopyalamak için
cat sirket.com.csr
Bu CSR dosyasının içeriğini sertifika sağlayıcınızın paneline yapıştırıyorsunuz. Sağlayıcı size sertifika dosyalarını gönderdikten sonra Nginx/Apache yapılandırmanıza ekliyorsunuz.
Sertifika İzleme ve Uyarı Sistemi
Production ortamında sertifika son kullanma tarihlerini izlemek kritik. Basit bir script ile bunu otomatize edebilirsiniz:
sudo nano /usr/local/bin/ssl-check.sh
#!/bin/bash
# SSL sertifika son kullanma tarihi kontrolü
# Cron ile günlük çalıştırın: 0 9 * * * /usr/local/bin/ssl-check.sh
DOMAINS=("sirket.com" "api.sirket.com" "app.sirket.com")
ALERT_DAYS=30
EMAIL="[email protected]"
LOG="/var/log/ssl-check.log"
echo "$(date): SSL check started" >> $LOG
for domain in "${DOMAINS[@]}"; do
expiry=$(echo | openssl s_client -connect ${domain}:443 -servername ${domain} 2>/dev/null | openssl x509 -noout -enddate 2>/dev/null | cut -d= -f2)
if [ -z "$expiry" ]; then
echo "$(date): WARNING - Could not check ${domain}" >> $LOG
continue
fi
expiry_epoch=$(date -d "$expiry" +%s)
current_epoch=$(date +%s)
days_left=$(( (expiry_epoch - current_epoch) / 86400 ))
echo "$(date): ${domain} expires in ${days_left} days" >> $LOG
if [ $days_left -lt $ALERT_DAYS ]; then
echo "UYARI: ${domain} sertifikası ${days_left} gün sonra sona eriyor!" |
mail -s "SSL Sertifika Uyarisi: ${domain}" $EMAIL
echo "$(date): Alert sent for ${domain}" >> $LOG
fi
done
echo "$(date): SSL check completed" >> $LOG
sudo chmod +x /usr/local/bin/ssl-check.sh
# Cron'a ekle
echo "0 9 * * * root /usr/local/bin/ssl-check.sh" | sudo tee /etc/cron.d/ssl-check
Sonuç
Wildcard SSL sertifikaları, birden fazla subdomain yöneten herkes için vazgeçilmez bir araç. Let’s Encrypt ile bu işi sıfır maliyetle, Cloudflare gibi DNS provider’ların API’leri sayesinde de tamamen otomatize edilmiş şekilde yapabiliyorsunuz.
Özetlemek gerekirse dikkat etmeniz gereken kritik noktalar şunlar:
- Wildcard sertifikası yalnızca bir seviye alt domain kapsar, derin hiyerarşiler için ayrı sertifika gerekir
- DNS-01 challenge wildcard için zorunludur, HTTP-01 çalışmaz
- Otomatik yenileme hook’larını mutlaka kurun, unutulmuş sertifika production’da büyük sorun demek
- Staging ortamında test ederek rate limit’e takılmaktan kaçının
- Sertifika izleme scriptleri ile erken uyarı sistemi kurun
Altyapınızda onlarca subdomain yönetiyorsanız wildcard sertifika hem operasyonel yükü azaltıyor hem de tutarlı bir güvenlik yapısı sunuyor. Özellikle SaaS ürünleri veya çok kiracılı mimariler için bu yapı neredeyse olmazsa olmaz hale geliyor.