Bir sabah erkenden, kullanıcılardan “Siteniz güvenli değil” uyarısı aldığınıza dair e-postalar gelmeye başlar. Panoya bakarsınız, SSL sertifikanızın dün gece sona erdiğini görürsünüz. O his… Kimse yaşamamalı. SSL sertifika yönetimi, sysadmin hayatının en kritik ama bir o kadar da ihmal edilen konularından biri. Bu yazıda hem otomatik hem de manuel yenileme yöntemlerini, gerçek dünya senaryolarıyla birlikte ele alacağız.
SSL Sertifika Yönetimine Genel Bakış
SSL/TLS sertifikaları artık sadece e-ticaret sitelerinin değil, her türlü web uygulamasının olmazmazı. Let’s Encrypt’in yaygınlaşmasıyla birlikte ücretsiz sertifika almak çok kolaylaştı, ancak bu kolaylık beraberinde “otomatik yenileme kurdum, tamam” rahatlığını da getirdi. İşin kötüsü, o otomatik yenilemenin çalışıp çalışmadığını kontrol etmeyi unutuyoruz.
Sertifika yönetiminde temel olarak iki senaryo var:
- Let’s Encrypt sertifikaları: 90 günlük ömürlü, otomasyona çok uygun
- Ticari CA sertifikaları: 1-2 yıllık ömürlü, genellikle manuel süreç gerektiren
Her iki senaryoyu da detaylıca inceleyelim.
Sertifika Durumunu Kontrol Etmek
Herhangi bir şey yapmadan önce mevcut durumu anlamak lazım. Sertifikanızın ne zaman sona ereceğini öğrenmek için birkaç yöntem var.
OpenSSL ile Kontrol
# Uzak sunucu sertifikasını kontrol et
echo | openssl s_client -servername example.com -connect example.com:443 2>/dev/null | openssl x509 -noout -dates
# Yerel sertifika dosyasını kontrol et
openssl x509 -in /etc/ssl/certs/example.com.crt -noout -dates
# Sertifikanın kaç gün kaldığını hesapla
echo | openssl s_client -servername example.com -connect example.com:443 2>/dev/null
| openssl x509 -noout -checkend 2592000
&& echo "Sertifika 30 gun icinde gecerli"
|| echo "UYARI: Sertifika 30 gun icinde sona erecek!"
-checkend parametresi saniye cinsinden değer alır. 2592000 saniye = 30 gün demek. Bu komutu monitoring scriptlerinize ekleyebilirsiniz.
Toplu Kontrol Scripti
Onlarca domain yönetiyorsanız her birini tek tek kontrol etmek yerine bir script yazın:
#!/bin/bash
# ssl_check.sh - Toplu SSL sertifika kontrol scripti
DOMAINS=("example.com" "blog.example.com" "api.example.com" "shop.example.com")
UYARI_GUNU=30
EMAIL="[email protected]"
for domain in "${DOMAINS[@]}"; do
BITIS=$(echo | openssl s_client -servername "$domain"
-connect "$domain:443" 2>/dev/null
| openssl x509 -noout -enddate 2>/dev/null
| cut -d= -f2)
if [ -z "$BITIS" ]; then
echo "HATA: $domain icin sertifika bilgisi alinamadi"
continue
fi
BITIS_TIMESTAMP=$(date -d "$BITIS" +%s)
SIMDI_TIMESTAMP=$(date +%s)
KALAN_GUN=$(( ($BITIS_TIMESTAMP - $SIMDI_TIMESTAMP) / 86400 ))
if [ "$KALAN_GUN" -lt "$UYARI_GUNU" ]; then
echo "UYARI: $domain sertifikasi $KALAN_GUN gun sonra sona eriyor!"
echo "SSL Uyarisi: $domain icin $KALAN_GUN gun kaldi" |
mail -s "SSL Sertifika Uyarisi" "$EMAIL"
else
echo "OK: $domain - $KALAN_GUN gun kaldi ($BITIS)"
fi
done
Bu scripti cron’a ekleyin ve her sabah çalıştırın. Sürpriz yaşamamanın en kolay yolu budur.
Let’s Encrypt ile Otomatik Sertifika Yenileme
Let’s Encrypt, Certbot istemcisi aracılığıyla sertifika yönetimini büyük ölçüde otomatize etti. Ancak “bir kez kur, unut” mantığıyla yaklaşmak hata olur.
Certbot Kurulumu ve Temel Kullanım
# Ubuntu/Debian için
sudo apt update
sudo apt install certbot python3-certbot-nginx
# CentOS/RHEL için
sudo dnf install epel-release
sudo dnf install certbot python3-certbot-nginx
# Nginx için sertifika al
sudo certbot --nginx -d example.com -d www.example.com
# Apache için sertifika al
sudo certbot --apache -d example.com -d www.example.com
# Standalone mod (web sunucusu olmadan)
sudo certbot certonly --standalone -d example.com
Otomatik Yenileme Kurulumu
Certbot kurulduğunda genellikle otomatik olarak bir systemd timer veya cron job oluşturur. Bunu doğrulayın:
# Systemd timer kontrolü
sudo systemctl status certbot.timer
sudo systemctl list-timers | grep certbot
# Cron job kontrolü
sudo cat /etc/cron.d/certbot
# Manuel test (gerçekten yenilemeden test eder)
sudo certbot renew --dry-run
--dry-run parametresi çok önemli. Gerçek yenileme yapmadan sürecin düzgün çalışıp çalışmadığını test eder. Yeni bir kurulum yaptıktan sonra mutlaka çalıştırın.
Certbot ile Pre ve Post Hook Kullanımı
Gerçek dünyada sertifika yenilenince genellikle web sunucusunu yeniden başlatmanız gerekir. Hook’lar tam burada devreye girer:
# /etc/letsencrypt/renewal-hooks/pre/stop-services.sh
#!/bin/bash
systemctl stop nginx
# /etc/letsencrypt/renewal-hooks/post/start-services.sh
#!/bin/bash
systemctl start nginx
systemctl reload nginx
# Deploy hook - yenileme başarılı olursa çalışır
# /etc/letsencrypt/renewal-hooks/deploy/reload-services.sh
#!/bin/bash
systemctl reload nginx
# Sertifika yenilendi, bildiri gönder
echo "Sertifika yenilendi: $(date)" | mail -s "SSL Yenileme Basarili" [email protected]
Hook dosyalarını çalıştırılabilir yapın:
sudo chmod +x /etc/letsencrypt/renewal-hooks/pre/stop-services.sh
sudo chmod +x /etc/letsencrypt/renewal-hooks/post/start-services.sh
sudo chmod +x /etc/letsencrypt/renewal-hooks/deploy/reload-services.sh
Wildcard Sertifika Yenileme
Alt domain sayısı çoksa wildcard sertifika kullanmak mantıklı olabilir. Ancak wildcard sertifikalar DNS challenge gerektiriyor:
# Wildcard sertifika alma (DNS challenge ile)
sudo certbot certonly
--manual
--preferred-challenges dns
-d "*.example.com"
-d "example.com"
Bu komut çalıştığında Certbot size bir DNS TXT kaydı ekletecek. Manuel süreç olduğu için otomasyonu biraz daha karmaşık. DNS sağlayıcınızın API’si varsa certbot-dns-route53, certbot-dns-cloudflare gibi plugin’lerle bunu da otomatize edebilirsiniz:
# Cloudflare için
sudo pip install certbot-dns-cloudflare
# /etc/letsencrypt/cloudflare.ini dosyası oluşturun
# dns_cloudflare_api_token = YOUR_API_TOKEN_HERE
sudo certbot certonly
--dns-cloudflare
--dns-cloudflare-credentials /etc/letsencrypt/cloudflare.ini
-d "*.example.com"
-d "example.com"
Manuel Sertifika Yenileme: Ticari CA Süreci
Let’s Encrypt her senaryoya uymaz. Özellikle kurumsal ortamlarda, EV (Extended Validation) sertifikası gereken durumlarda veya bazı eski sistemlerde ticari CA sertifikaları kullanmak zorunda kalabilirsiniz.
CSR (Certificate Signing Request) Oluşturma
Manuel yenilemede ilk adım yeni bir CSR oluşturmak:
# Yeni private key ve CSR oluştur
openssl req -new -newkey rsa:2048 -nodes
-keyout /etc/ssl/private/example.com.key
-out /etc/ssl/csr/example.com.csr
-subj "/C=TR/ST=Istanbul/L=Istanbul/O=Sirket Adi/OU=IT/CN=example.com"
# Oluşturulan CSR'ı doğrula
openssl req -text -noout -verify -in /etc/ssl/csr/example.com.csr
# SAN (Subject Alternative Names) ile CSR oluşturmak için
# Önce config dosyası oluşturun
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 Adi
CN = example.com
[v3_req]
keyUsage = keyEncipherment, dataEncipherment
extendedKeyUsage = serverAuth
subjectAltName = @alt_names
[alt_names]
DNS.1 = example.com
DNS.2 = www.example.com
DNS.3 = api.example.com
EOF
openssl req -new -newkey rsa:2048 -nodes
-keyout /etc/ssl/private/example.com.key
-out /etc/ssl/csr/example.com.csr
-config /tmp/san.cnf
CSR’ı oluşturduktan sonra içeriğini CA’nın web paneline yapıştırıyorsunuz. CA doğrulamayı tamamladıktan sonra size .crt veya .pem formatında sertifikayı gönderiyor.
Sertifika Zincirini Doğru Yapılandırmak
Ticari CA sertifikalarında sertifika zinciri (chain) önemli. Eksik chain, mobil tarayıcılarda veya bazı sistemlerde hata verir:
# Sertifika zincirini birleştir
cat /etc/ssl/certs/example.com.crt
/etc/ssl/certs/intermediate.crt
/etc/ssl/certs/root.crt > /etc/ssl/certs/example.com.fullchain.crt
# Zinciri doğrula
openssl verify -CAfile /etc/ssl/certs/root.crt
-untrusted /etc/ssl/certs/intermediate.crt
/etc/ssl/certs/example.com.crt
# Nginx config güncelle
# ssl_certificate /etc/ssl/certs/example.com.fullchain.crt;
# ssl_certificate_key /etc/ssl/private/example.com.key;
Nginx Sertifika Yenileme Süreci
Yeni sertifikayı aldıktan sonra Nginx’e uygulamak:
# Dosyaları yerine koy
sudo cp /tmp/example.com.crt /etc/ssl/certs/example.com.crt
sudo cp /tmp/example.com.key /etc/ssl/private/example.com.key
# Dosya izinlerini ayarla
sudo chmod 644 /etc/ssl/certs/example.com.crt
sudo chmod 600 /etc/ssl/private/example.com.key
sudo chown root:root /etc/ssl/private/example.com.key
# Nginx config test et
sudo nginx -t
# Eğer test başarılıysa reload et (downtime olmadan)
sudo systemctl reload nginx
# Yenilemenin çalıştığını doğrula
echo | openssl s_client -servername example.com -connect example.com:443 2>/dev/null
| openssl x509 -noout -dates
Acil Durum: Sertifika Süresi Dolmuş
Başa dönelim, o kabus senaryosuna. Sertifika süresi dolmuş ve siteniz hata veriyor. Panik yapmayın, adım adım ilerleyin.
Certbot kullanıyorsanız:
# Hemen yenile, 30 gün kuralını atla
sudo certbot renew --force-renewal
# Sadece belirli bir domain için
sudo certbot renew --force-renewal --cert-name example.com
# Yenileme sonrası nginx'i reload et
sudo systemctl reload nginx
Ticari sertifika ve hızlı geçici çözüm gerekiyorsa:
Bazı CA’lar mevcut sertifikanızı aynı CSR ile birkaç saat içinde yeniden verebilir. Destek hattını arayın ve durumu açıklayın. Bu arada Let’s Encrypt ile geçici sertifika alıp sistemi ayağa kaldırabilirsiniz.
Sertifika Yönetimini Ansible ile Otomatize Etmek
Onlarca sunucu yönetiyorsanız her birine tek tek girmek yerine Ansible kullanın. Basit bir playbook örneği:
# ssl_renew.yml
---
- name: SSL Sertifika Yenileme
hosts: webservers
become: yes
vars:
domains:
- example.com
- www.example.com
tasks:
- name: Certbot yükle
package:
name: certbot
state: present
- name: Sertifika süresini kontrol et
shell: |
openssl x509 -in /etc/letsencrypt/live/{{ domains[0] }}/cert.pem
-noout -checkend 2592000
register: cert_check
ignore_errors: yes
changed_when: false
- name: Sertifikayı yenile (30 günden az kaldıysa)
shell: certbot renew --cert-name {{ domains[0] }} --quiet
when: cert_check.rc != 0
notify: Nginx reload
- name: Yenileme sonucunu logla
lineinfile:
path: /var/log/ssl-renewal.log
line: "{{ ansible_date_time.iso8601 }} - {{ inventory_hostname }} - Sertifika yenilendi"
create: yes
when: cert_check.rc != 0
handlers:
- name: Nginx reload
systemd:
name: nginx
state: reloaded
Bu playbook’u cron ile çalıştırabilirsiniz:
# Ansible playbook'u cron ile çalıştır
0 3 * * * /usr/bin/ansible-playbook /opt/ansible/ssl_renew.yml >> /var/log/ssl-ansible.log 2>&1
Monitoring ve Alerting
Sertifika yönetiminin en önemli parçası izleme. Prometheus + Alertmanager kullanıyorsanız blackbox_exporter ile SSL sertifika sürelerini izleyebilirsiniz. Daha basit bir çözüm istiyorsanız:
#!/bin/bash
# ssl_monitor.sh - Cron ile çalıştırılacak monitoring scripti
# Crontab: 0 8 * * * /usr/local/bin/ssl_monitor.sh
KRITIK_GUN=7
UYARI_GUN=30
SLACK_WEBHOOK="https://hooks.slack.com/services/YOUR/WEBHOOK/URL"
check_ssl() {
local domain=$1
local kalan_gun
kalan_gun=$(echo | openssl s_client -servername "$domain"
-connect "$domain:443" 2>/dev/null
| openssl x509 -noout -enddate 2>/dev/null
| cut -d= -f2
| xargs -I{} sh -c 'echo $(( ($(date -d "{}" +%s) - $(date +%s)) / 86400 ))')
if [ -z "$kalan_gun" ]; then
curl -s -X POST -H 'Content-type: application/json'
--data "{"text":"HATA: $domain icin SSL kontrolü yapılamadı!"}"
"$SLACK_WEBHOOK"
return
fi
if [ "$kalan_gun" -lt "$KRITIK_GUN" ]; then
curl -s -X POST -H 'Content-type: application/json'
--data "{"text":"KRITIK: $domain SSL sertifikası $kalan_gun gün sonra sona eriyor!"}"
"$SLACK_WEBHOOK"
elif [ "$kalan_gun" -lt "$UYARI_GUN" ]; then
curl -s -X POST -H 'Content-type: application/json'
--data "{"text":"UYARI: $domain SSL sertifikası $kalan_gun gün sonra sona eriyor."}"
"$SLACK_WEBHOOK"
fi
}
# Domain listesi
DOMAINS=("example.com" "api.example.com" "admin.example.com")
for domain in "${DOMAINS[@]}"; do
check_ssl "$domain"
sleep 2
done
Dikkat Edilmesi Gereken Yaygın Hatalar
Yıllar içinde gördüğüm en sık yapılan hataları paylaşmak istiyorum:
- Private key’i yedeklememek: Sertifika yenilenince private key değişebilir. Her ikisini de yedekleyin.
- Otomatik yenilemeyi test etmemek: Certbot kurdum tamam demek yetmez.
--dry-runile ayda bir test edin. - Port 80’i kapatmak: Let’s Encrypt HTTP-01 challenge için port 80’e ihtiyaç duyar. Firewall kurallarınızı kontrol edin.
- Rate limit’e çarpmak: Let’s Encrypt’in aynı domain için haftada 5 sertifika limiti var. Denemelerinizde önce staging ortamı kullanın.
- Sertifika zincirini eksik bırakmak: Özellikle ticari sertifikalarda intermediate sertifikayı eklemeyi unutmak yaygın bir sorun.
- Dosya izinlerini yanlış ayarlamak: Private key 600 izinli ve root’a ait olmalı. Aksi halde web sunucusu okuyamaz.
- Yenileme loglarını takip etmemek:
/var/log/letsencrypt/letsencrypt.logdosyasını düzenli kontrol edin.
Sonuç
SSL sertifika yönetimi, “bir kez hallettim” diyebileceğiniz bir konu değil. Otomatik yenileme kurduğunuzda bile monitoring şart. Certbot’un otomatik yenileme mekanizması genellikle çok iyi çalışıyor, ama firewall değişiklikleri, DNS sorunları veya servis güncellemeleri yüzünden beklenmedik durumlarda başarısız olabiliyor.
En iyi yaklaşım katmanlı bir strateji benimsemek: Certbot ile otomatik yenilemeyi kurun, hook’larla web sunucusu reload’ını otomatize edin, monitoring scriptiyle sertifika sürelerini takip edin ve kritik domainler için Slack ya da e-posta alertleri ayarlayın. Ticari sertifikalar için takviyenize sertifika bitiş tarihini en az 6 hafta öncesinden ekleyin.
O “Siteniz güvenli değil” e-postalarını bir daha almamak için bugün monitoring scriptinizi kurun. Gelecekteki kendiniz size teşekkür edecek.