Nginx ile Let’s Encrypt Wildcard ve Joker Sertifika Kurulumu

Bir web sunucusu yönetirken en çok baş ağrıtan şeylerden biri sertifika yönetimidir. Özellikle onlarca subdomain çalıştırıyorsanız, her biri için ayrı ayrı sertifika almak, yenilemek ve yapılandırmak gerçek bir kabusa dönüşebilir. İşte burada wildcard sertifikalar hayat kurtarıcı oluyor. *.example.com gibi tek bir sertifika ile tüm subdomainlerinizi kapsayabilirsiniz. Bu yazıda Nginx üzerinde Let’s Encrypt wildcard sertifikasını nasıl alacağınızı, yapılandıracağınızı ve otomatik yenileme sürecini nasıl kuracağınızı adım adım ele alacağız.

Wildcard Sertifika Nedir ve Neden Lazım?

Standart bir SSL sertifikası yalnızca belirli bir domain veya subdomain için geçerlidir. www.example.com için aldığınız sertifika api.example.com ya da mail.example.com için çalışmaz. Her subdomain için ayrı sertifika almanız gerekir.

Wildcard sertifika ise *.example.com biçiminde tanımlanır ve bu domaine ait tüm birinci seviye subdomainleri kapsar. Yani api.example.com, shop.example.com, blog.example.com gibi tüm subdomainler tek bir sertifikayla korunur.

Avantajları:

  • Tek sertifika ile tüm subdomainler korunur
  • Sertifika yenileme operasyonu tek noktadan yapılır
  • Yeni subdomain eklerken tekrar sertifika almanıza gerek kalmaz
  • Nginx yapılandırması sadeleşir

Dikkat edilmesi gereken bir nokta: Wildcard sertifikalar yalnızca bir seviye derinliği kapsar. .example.com geçerliyken .sub.example.com için ayrıca sertifika almanız gerekir.

DNS-01 Challenge Zorunluluğu

Let’s Encrypt wildcard sertifika alabilmek için HTTP-01 challenge değil, DNS-01 challenge kullanmak zorundasınızdır. Bu önemli bir fark çünkü HTTP-01 challenge’da Certbot bir dosyayı web sunucunuza yerleştirerek doğrulama yapar. DNS-01’de ise DNS kayıtlarınıza bir TXT kaydı eklemeniz gerekir.

Bu durum iki senaryo doğurur:

  • Manuel yöntem: DNS sağlayıcınıza giriş yapıp TXT kaydını elle eklersiniz. Basit ama otomatik yenileme için uygun değil.
  • Otomatik yöntem: DNS sağlayıcınızın API’sini destekleyen bir Certbot plugin kullanırsınız. Yenileme tamamen otomatik hale gelir.

Bu yazıda her iki yöntemi de göstereceğim. Gerçek ortamlarda her zaman otomatik yöntemi tercih edin.

Ön Hazırlık

Başlamadan önce sisteminizde şunların kurulu ve hazır olduğundan emin olun:

  • Ubuntu 20.04 veya 22.04 (ya da Debian tabanlı bir sistem)
  • Nginx kurulu ve çalışıyor olmalı
  • Domain adınızın DNS yönetimine erişiminiz olmalı
  • Root veya sudo yetkisi

Certbot ve Nginx plugin’ini kuralım:

sudo apt update
sudo apt install -y certbot python3-certbot-nginx

Eğer DNS sağlayıcınız Cloudflare ise, Cloudflare DNS plugin’ini de kurmanız gerekecek:

sudo apt install -y python3-certbot-dns-cloudflare

Diğer popüler DNS sağlayıcıları için plugin’ler:

  • python3-certbot-dns-digitalocean: DigitalOcean DNS
  • python3-certbot-dns-route53: AWS Route53
  • python3-certbot-dns-google: Google Cloud DNS
  • python3-certbot-dns-ovh: OVH DNS

Manuel Yöntem ile Wildcard Sertifika Almak

Hızlı test ortamları veya DNS sağlayıcınız için plugin yoksa manuel yöntemi kullanabilirsiniz. Komutu çalıştırdığınızda Certbot size bir TXT kaydı verecek ve bunu DNS paneline eklemenizi isteyecek.

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

Komut çalıştıktan sonra şuna benzer bir çıktı göreceksiniz:

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

Press Enter to Continue

Bu değeri DNS panelinize gidin ve _acme-challenge.example.com adında bir TXT kaydı olarak ekleyin. DNS değişikliğinin yayılmasını beklemek için birkaç dakika verin, sonra Enter’a basın.

Sertifika başarıyla alındığında /etc/letsencrypt/live/example.com/ dizininde dosyalar oluşacak.

Dezavantaj: Manuel yöntemde sertifika yenilemesi de manuel yapılmak zorundadır. 90 günde bir bu işlemi tekrarlamanız gerekir. Production ortamları için kesinlikle otomatik yönteme geçin.

Cloudflare ile Otomatik Wildcard Sertifika

Cloudflare kullananlar için en temiz yöntem bu. Cloudflare API token oluşturup Certbot’a tanıtacaksınız.

API Token Oluşturma

Cloudflare Dashboard’a giriş yapın, sağ üstten profil ikonuna tıklayın, “API Tokens” sekmesine gidin. “Create Token” deyin ve “Edit zone DNS” şablonunu seçin. Zone’u kendi domaininizle sınırlayın. Token’ı oluşturun ve güvenli bir yere not alın.

Credentials Dosyası Oluşturma

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

Dosya içeriği:

# Cloudflare API token
dns_cloudflare_api_token = buraya_cloudflare_api_tokeninizi_yazin

Dosyayı güvenli hale getirin, root dışında kimse okuyamasın:

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

Sertifikayı Alın

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

--dns-cloudflare-propagation-seconds 60 parametresi Certbot’un DNS kaydının yayılması için 60 saniye beklemesini sağlar. Bazı durumlarda DNS propagation daha uzun sürebilir, 120 saniyeye de çıkarabilirsiniz.

İşlem başarılı olursa sertifika dosyalarınız şurada olacak:

  • /etc/letsencrypt/live/example.com/fullchain.pem: Sertifika zinciri
  • /etc/letsencrypt/live/example.com/privkey.pem: Private key
  • /etc/letsencrypt/live/example.com/cert.pem: Sertifika
  • /etc/letsencrypt/live/example.com/chain.pem: Ara sertifika

Nginx Yapılandırması

Sertifikalar hazır. Şimdi Nginx’i yapılandıralım. Wildcard sertifikanın güzel yanı, tüm subdomainleriniz için aynı sertifika bloğunu kullanabilmeniz.

Ana Site Yapılandırması

sudo nano /etc/nginx/sites-available/example.com
# HTTP'den HTTPS'e yönlendirme
server {
    listen 80;
    listen [::]:80;
    server_name example.com *.example.com;
    
    return 301 https://$host$request_uri;
}

# Ana domain
server {
    listen 443 ssl http2;
    listen [::]:443 ssl http2;
    server_name example.com www.example.com;

    ssl_certificate /etc/letsencrypt/live/example.com/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/example.com/privkey.pem;
    
    include /etc/nginx/snippets/ssl-params.conf;

    root /var/www/example.com/html;
    index index.html index.php;

    location / {
        try_files $uri $uri/ =404;
    }
}

SSL Parametreleri Snippet Dosyası

Tekrar tekrar aynı SSL yapılandırmasını yazmak yerine bir snippet oluşturun, her virtual host’ta include edin:

sudo nano /etc/nginx/snippets/ssl-params.conf
ssl_protocols TLSv1.2 TLSv1.3;
ssl_prefer_server_ciphers on;
ssl_ciphers 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;
ssl_session_timeout 1d;
ssl_session_cache shared:SSL:10m;
ssl_session_tickets off;
ssl_stapling on;
ssl_stapling_verify on;
resolver 8.8.8.8 8.8.4.4 valid=300s;
resolver_timeout 5s;
add_header Strict-Transport-Security "max-age=63072000" always;
add_header X-Frame-Options DENY;
add_header X-Content-Type-Options nosniff;
add_header X-XSS-Protection "1; mode=block";

Subdomain Yapılandırmaları

Her subdomain için ayrı dosya oluşturabilirsiniz. Sertifika satırları aynı kalıyor, sadece server_name ve root değişiyor:

sudo nano /etc/nginx/sites-available/api.example.com
server {
    listen 443 ssl http2;
    listen [::]:443 ssl http2;
    server_name api.example.com;

    ssl_certificate /etc/letsencrypt/live/example.com/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/example.com/privkey.pem;
    
    include /etc/nginx/snippets/ssl-params.conf;

    location / {
        proxy_pass http://127.0.0.1:3000;
        proxy_http_version 1.1;
        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_set_header Upgrade $http_upgrade;
        proxy_set_header Connection "upgrade";
    }
}

Yapılandırmaları aktif edin ve test edin:

sudo ln -s /etc/nginx/sites-available/example.com /etc/nginx/sites-enabled/
sudo ln -s /etc/nginx/sites-available/api.example.com /etc/nginx/sites-enabled/

sudo nginx -t
sudo systemctl reload nginx

Dinamik Subdomain Yapılandırması

Bazen çok sayıda subdomain vardır ve hepsi aynı backend’e ya da dizin yapısına yönlendirilir. Bu durumda tek bir server block ile tüm subdomainleri yakalayabilirsiniz:

server {
    listen 443 ssl http2;
    listen [::]:443 ssl http2;
    server_name ~^(?P<subdomain>.+).example.com$;

    ssl_certificate /etc/letsencrypt/live/example.com/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/example.com/privkey.pem;
    
    include /etc/nginx/snippets/ssl-params.conf;

    # Her subdomain kendi dizinine yonlendiriliyor
    root /var/www/sites/$subdomain/public;
    index index.html index.php;

    access_log /var/log/nginx/$subdomain.access.log;
    error_log /var/log/nginx/$subdomain.error.log;

    location / {
        try_files $uri $uri/ =404;
    }
}

Bu yapıda shop.example.com isteği /var/www/sites/shop/public dizinine, blog.example.com isteği /var/www/sites/blog/public dizinine otomatik olarak yönlendirilir. Yeni bir subdomain eklemek istediğinizde sadece ilgili dizini oluşturmanız yeterli.

Otomatik Yenileme Kurulumu

Let’s Encrypt sertifikaları 90 günde bir sona erer. Certbot kurulumunda genellikle otomatik bir systemd timer ya da cron job oluşturulur, ama bunu doğrulayalım ve özelleştirelim.

Önce mevcut timer’ı kontrol edin:

sudo systemctl status certbot.timer

Eğer aktifse güzel, değilse etkinleştirin:

sudo systemctl enable certbot.timer
sudo systemctl start certbot.timer

Yenileme işleminden sonra Nginx’in otomatik reload edilmesi için bir deploy hook oluşturun:

sudo nano /etc/letsencrypt/renewal-hooks/deploy/reload-nginx.sh
#!/bin/bash
# Sertifika yenilendikten sonra Nginx'i reload et
systemctl reload nginx

# Yenileme tarihini logla
echo "$(date): Sertifika yenilendi ve Nginx reload edildi" >> /var/log/certbot-renewal.log

Script’e çalışma izni verin:

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

Yenileme işlemini simüle ederek test edin:

sudo certbot renew --dry-run

Çıktıda hata görmüyorsanız her şey yolunda demektir.

Manuel Cron Alternatifi

Systemd timer yerine cron kullanmayı tercih ediyorsanız:

sudo crontab -e
# Her gün sabah 3'te ve öğleden sonra 3'te yenileme kontrolü yap
0 3,15 * * * /usr/bin/certbot renew --quiet --post-hook "systemctl reload nginx"

Sertifika Durumu Kontrol Etme

Sertifikanızın ne zaman sona ereceğini ve hangi domainleri kapsadığını görmek için:

sudo certbot certificates

Daha ayrıntılı bilgi için:

sudo openssl x509 -in /etc/letsencrypt/live/example.com/cert.pem -text -noout | grep -E "(Subject|DNS|Not After)"

SSL bağlantısını dışarıdan test etmek için:

openssl s_client -connect example.com:443 -servername example.com 2>/dev/null | openssl x509 -noout -dates -subject

Sık Karşılaşılan Sorunlar ve Çözümleri

DNS propagation hatası: Certbot TXT kaydını göremiyorsa propagation süresini artırın. Bazı DNS sağlayıcılarında bu 5 dakikayı bulabilir. --dns-cloudflare-propagation-seconds değerini 120 veya 180 yapın.

Rate limit hatası: Let’s Encrypt aynı domain için haftada 5 sertifika verme limiti koymuştur. Testlerde --staging flagini kullanın:

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

Nginx yapılandırma hatası: nginx -t ile her zaman yapılandırmayı test edin. Hata mesajı genellikle sorunun tam yerini gösterir.

Sertifika bulunamıyor hatası: Sertifika yolunun doğru olduğundan emin olun. Certbot bazen domain adını farklı organize edebilir:

sudo ls -la /etc/letsencrypt/live/

Çoklu Domain ile Sertifika Genişletme

Mevcut bir sertifikaya yeni domain eklemek için --expand parametresini kullanın:

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

Bu şekilde tek bir sertifika ile birden fazla farklı domain ve bunların wildcard’larını yönetebilirsiniz.

Güvenlik Kontrolleri

SSL Labs gibi araçlarla sertifikanızı ve Nginx güvenlik yapılandırmanızı test edin. Komut satırından hızlı kontrol için:

# SSL/TLS protokol ve cipher kontrolu
nmap --script ssl-enum-ciphers -p 443 example.com

# HSTS kontrolu
curl -sI https://example.com | grep -i strict

Sertifika parmak izini almak ve farklı ortamlarla karşılaştırmak için:

sudo openssl x509 -in /etc/letsencrypt/live/example.com/cert.pem -fingerprint -sha256 -noout

Sonuç

Nginx ile Let’s Encrypt wildcard sertifika yönetimi başta karmaşık görünebilir, özellikle DNS-01 challenge zorunluluğu ve DNS API entegrasyonu nedeniyle. Ama bir kez doğru kurulumu yaptıktan sonra sertifika yönetimi tamamen arka plana çekiliyor. Artık her yeni subdomain için ayrıca sertifika almanıza, yenileme tarihlerini takip etmenize gerek kalmıyor.

En önemli pratik tavsiyem şu: Production ortamlarında kesinlikle Cloudflare, Route53 veya başka bir DNS API entegrasyonu kullanın ve otomatik yenilemeyi test edin. Sertifika süresi dolduğunda kullanıcılarınız güvenlik uyarısı alır ve bu ciddi bir itibar sorunu yaratır. --dry-run testini düzenli çalıştırmak ve yenileme loglarını izlemek bu riski minimize eder.

Wildcard sertifikalar özellikle çok sayıda subdomain yöneten SaaS uygulamaları, mikroservis mimarileri ve multi-tenant platformlar için gerçekten vazgeçilmez bir araç. Kurulum maliyeti bir kere ödendikten sonra getirdiği kolaylık çok değerli.

Yorum yapın