İçindekiler
- 1 Kahvede Başlayan Telaş: Let’s Encrypt Tıkandı, Sonra Ne Oldu?
- 2 ACME’yi Kafada Netleştirelim: Neden Yedekli CA?
- 3 acme.sh Temelleri: Hesap Kayıtları, Anahtarlar, Dosya Düzeni
- 4 Sertifika Alma: DNS-01 ile Çok Alan Adı, Rakipsiz Esneklik
- 5 Asıl Numara: Let’s Encrypt → ZeroSSL Otomatik Fallback
- 6 Oran Limitlerine Sakin Kalmak: Zaman, Dalga ve Jitter
- 7 Dağıtım ve Güvenlik: Dosya Yolları, Yetkiler, Sırların Saklanması
- 8 Gözlemleme: Log, Metrik ve Küçük Alarmcıklar
- 9 Operasyonel İpuçları: Küçük Dokunuşlar, Büyük Rahatlık
- 10 Gerçekçi Bir Akış: Baştan Sona Mini Senaryo
- 11 Kaynaklar: Kısa Kısa, Doğru Kapılar
- 12 Kapanış: Yedekli CA, Sakin Otomasyon ve Rahat Bir Gece Uykusu
Kahvede Başlayan Telaş: Let’s Encrypt Tıkandı, Sonra Ne Oldu?
Hiç sabah kahveni alıp güne sakince başlamak isterken, monitörde kırmızı bir uyarı gözünüze çarpmadı mı? Benim geçtiğimiz hafta başıma geldi. Gece çalışan bir dağıtımda, onlarca alan adının sertifikası planlandığı gibi yenilenecekti. Cron saatini bilinçli seçmişim, sistemde kilit dosyası var, her şey kitabına uygun. Derken birden loglar peş peşe fırlamaya başladı: 429 hataları, süre aşımı uyarıları, “çok fazla istek” imaları… Kısacası Let’s Encrypt tarafında bir sürü küçük ama moral bozan işaret. O anda kafamda tek bir düşünce dönüp durdu: Ya şu an müşterilerin bir kısmı sertifikasız kalırsa?
O an anladım ki asıl mesele otomasyonun varlığı değil, otomasyonun dayanıklılığıymış. Birincil Sertifika Otoritesi (CA) olarak Let’s Encrypt harika; fakat yük anlarında, altyapınız büyüdükçe, bazı günler işler sıkışabiliyor. Tam da bu yüzden, acme.sh ile ikinci bir CA’yı cepte tutmak şahane bir sigorta. Benim tercihim ZeroSSL oldu. Plan şöyle: Birincil Let’s Encrypt, tıkanırsak, otomatik ve kibar bir geçişle ZeroSSL. Bu yazıda o planı adım adım, basit örneklerle ve canlı deneyim tadında anlatacağım.
Birlikte, acme.sh ile çok alan adını akıllıca yöneten, oran limitlerine sakin kalan, olası kesintilerde panik yerine prosedürle yürüyen “ye-dek-li CA” kurulumunu konuşacağız. Arada birkaç pratik script paylaşacağım, küçük tuzaklardan bahsedeceğim, sonunda da “tamam, ben bunu yarın uygulayabilirim” rahatlığıyla kapanış yapacağız.
ACME’yi Kafada Netleştirelim: Neden Yedekli CA?
ACME dediğimiz şey, sertifika alıp yenilemeyi otomatiğe bağlayan akıllı bir anlaşma. İstemci aracı (bizim için acme.sh) ile CA arasında konuşma geçiyor, alan adının sana ait olduğunu kanıtlıyorsun, CA da sana sertifika veriyor. Burada kritik olan, bu konuşmanın her zaman akması. Çünkü trafik akıyor, kullanıcılar beklemez. Bir de üretimde işler büyüyünce, tek bir hareketle bir sürü alan adına sertifika alıyorsun; işte orada küçük gecikmeler koca bir domino etkisine dönüşebiliyor.
Yedekli CA fikri şuradan doğuyor: Birincil CA’nın tarafında yoğunluk olabilir, senin günlük sıran biraz uzayabilir, ya da sen aynı anda çok fazla sertifika talep ediyor olabilirsin. Böyle bir durumda “tamam, o zaman ikinci CA’dan alalım” demek kadar rahatlatıcı bir şey olmuyor. Bu sadece iş sürekliliği değil, aynı zamanda ölçeklenebilirlik reçetesi. Mesela şöyle düşünün: Bir pazar günü sosyal medya kampanyası patladı, müşteriler yeni alt alan adlarını panelden eklemeye başladı. Sistem otomatik sertifika veriyor. Derken bir yerde minik bir tıkanıklık; eğer yedeğin yoksa, küçük bir uyarı bir anda büyük bir yangına dönüşebilir.
Benim tecrübemde, bunu önlemek için atılacak ilk adım, acme.sh’yi iki CA’yı da tanıyacak şekilde hazırlamak. Let’s Encrypt birincil, ZeroSSL yedek. Böylece normal günlerde bildiğimiz düzen devam ediyor; olağanüstü günlerdeyse, arka planda zarif bir geçişle bakım yapar gibi ilerliyoruz. Bunu kurarken en çok sevdiğim şey, mimarinin sade kalması. Ekstra karmaşa yok, yalnızca ihtiyatlı bir “B planı”.
acme.sh Temelleri: Hesap Kayıtları, Anahtarlar, Dosya Düzeni
İki CA için iki hesap, tek düzende hayat
Önce aracıdan başlayalım. acme.sh hafif, taş gibi çalışan bir komut satırı aracı. Kurulumdan sonra kendi dizininde hesap anahtarlarını, sertifikaları ve logları saklıyor. En sevdiğim tarafı, farklı CA’larla rahat konuşması. Let’s Encrypt için bir hesap kaydı, ZeroSSL için de ayrı bir hesap kaydı açıyoruz. Böylece her CA ile iletişimin kimliği, kullanım limitleri ve imza akışı tertemiz ayrışıyor.
Let’s Encrypt hesabını açmak için basitçe şöyle bir komut yeterli:
acme.sh --register-account -m [email protected] --server letsencrypt
ZeroSSL’nin küçük bir farkı var: Hesap yaratırken EAB (External Account Binding) bilgisi veriyoruz. Bu bilgileri ZeroSSL panelinden veya API sayfalarından alabilirsiniz. Komut şu şekilde ilerliyor:
export ZEROSSL_EAB_KID="<EAB_KID>"
export ZEROSSL_EAB_HMAC_KEY="<EAB_HMAC_KEY>"
acme.sh --register-account
-m [email protected]
--server zerossl
--eab-kid "$ZEROSSL_EAB_KID"
--eab-hmac-key "$ZEROSSL_EAB_HMAC_KEY"
Bu aşamada dikkat edilecek iki şey var. Birincisi, e-posta adresi operasyonel bir adres olsun; bildirimler kaybolmasın. İkincisi, EAB anahtarlarını ortam değişkenlerinde tutun, loglara düşmesin. Küçük bir not: acme.sh ile isterseniz EAB değerlerini doğrudan parametrelerle de verebilirsiniz, fakat ortam değişkenleri hem okunaklı hem de güvenli kalıyor.
Varsayılan CA’yı seçmek
acme.sh’de varsayılan CA’yı belirlemek gayet düz. Ben genelde Let’s Encrypt’i varsayılan tutuyorum, çünkü düzenli iş akışında onu kullanmak istiyorum. Şöyle işliyor:
acme.sh --set-default-ca --server letsencrypt
Bu, “her zamanki yol Let’s Encrypt, ama dilersem komut bazında ZeroSSL kullanırım” anlamına geliyor. Birazdan fallback script’inde de göreceksiniz; otomatik kararları küçük kontrollerle tattıracağız.
Sertifika Alma: DNS-01 ile Çok Alan Adı, Rakipsiz Esneklik
Webroot mu, DNS-01 mi?
Webroot yöntemi ufak projelerde pratik, ancak çok alan adı, çok kiracılı SaaS ve küme içi servislerde DNS-01 dünyanın en tatlı esnekliği. Tek bir doğrulama ile wildcard’a uzanırsınız, arka uç dağıtarak yükü paylaştırırsınız, uygulama katmanına mecbur kalmazsınız. Ben kalabalık ortamlarda API destekli DNS-01’i tercih ediyorum.
acme.sh, pek çok DNS sağlayıcısının API’sini doğrudan destekliyor. Uygun ortam değişkenlerini verip, sağlayıcıyı seçtiğinizde, gerisini o hallediyor. Örneğin bulut DNS’lerden biri için şöyle bir kalıp düşünün:
export CF_Token="<TOKEN>"
export CF_Account_ID="<ACCOUNT>"
acme.sh --issue -d example.com -d "*.example.com"
--dns dns_cf
--server letsencrypt
--keylength ec-256
--log --debug 2
Burada hem çıplak alan adı hem wildcard birlikte alınıyor. Önemli bir alışkanlık: Log’u ve gerekirse debug seviyesini açık tutun. Sertifika yenilemeleri gece yarısı sessiz sedasız koşuyor; ne olup bittiğini hızlı görürsünüz.
ECDSA + RSA ikilisi
Uyumluluk kaygısı olan ortamlarda ECDSA ve RSA’yı birlikte yayınlamak rahat ettirir. acme.sh ile önce ECDSA, ardından RSA sertifika alıp aynı domain klasöründe yönetebilirsiniz. Örnek olarak, önce ECDSA’yı alalım:
acme.sh --issue -d example.com -d "*.example.com"
--dns dns_cf
--server letsencrypt
--keylength ec-256
Ardından RSA:
acme.sh --issue -d example.com -d "*.example.com"
--dns dns_cf
--server letsencrypt
--keylength 2048
Kurulum sırasında iki anahtar tipini de servisinizde ayrı dosya yollarıyla gösterebilir, web sunucusunda her ikisini aynı anda yükleyebilirsiniz. Bu yaklaşımı anlatırken detaya boğmayayım; önemli olan yapı taşları. İki anahtar tipi, iki sertifika, tek alan adında uyumlu sunum.
Asıl Numara: Let’s Encrypt → ZeroSSL Otomatik Fallback
Neyi tetik sayacağız?
Fallback demek, planlı bir geri çekilme demek. Peki hangi şartlarda devreye girmeli? Ben üç pratik tetik belirliyorum. Birincisi, oran limitine yakalanma sinyalleri. acme.sh loglarında “çok fazla istek” tadında mesajlar, 429 kodları, tekrarlı çakılmalar. İkincisi, ağ sorunları ve zaman aşımı. Üçüncüsü, bakım ve planlı kesintiler, bazen CA tarafından kısa süreli pencereler olur. Bu durumda beklemek yerine yedeğe geçmek, özellikle ciddi trafik taşıyan sistemlerde rahatlatıyor.
Bunun altına bir de yük planı koyuyorum. Yenilemeleri tüm filoda aynı dakika koşturmazsınız; dalga dalga, küçük gruplar halinde. Böylece fall-back gerekirse bile sakin bir geçiş yaşanır. Bir anda yüzlerce isteği ZeroSSL’ye de yığmazsınız; küçük dozlarla tatlı tatlı ilerlersiniz.
Basit bir wrapper: Önce Let’s Encrypt, olmazsa ZeroSSL
Gelelim mutfağa. Mantık şu: Üretim cron’una bir wrapper script koyuyoruz. Script, önce Let’s Encrypt ile deniyor, hata tipini anlamaya çalışıyor; eğer belirlediğimiz hatalardan biriyse, aynı komutu ZeroSSL ile tekrar deniyor. Her iki durumda da log’lanıyor, metriklere işleniyor. Aşağıya bir çekirdek örnek bırakıyorum; fikir versin, kendi ortamınıza göre güzelleştirin:
#!/usr/bin/env bash
set -euo pipefail
DOMAIN="$1" # örn: example.com
ALT_DOMAINS=("*.example.com")
DNS_PLUGIN="dns_cf" # sağlayıcınıza göre güncelleyin
RELOAD_CMD="systemctl reload nginx"
LOG_FILE="/var/log/acme-fallback.log"
LOCK_FILE="/var/lock/acme-$DOMAIN.lock"
issue_with() {
local server="$1" # letsencrypt | zerossl
acme.sh --issue -d "$DOMAIN" ${ALT_DOMAINS[@]/#/-d }
--dns "$DNS_PLUGIN"
--server "$server"
--keylength ec-256
--log || return $?
# Başarılıysa kur ve reload
acme.sh --install-cert -d "$DOMAIN"
--ecc
--key-file /etc/ssl/private/$DOMAIN-ecc.key
--fullchain-file /etc/ssl/certs/$DOMAIN-ecc.fullchain
--reloadcmd "$RELOAD_CMD"
}
should_fallback() {
local err="$1"
# Basit sezgisel: 429, rate, timeout gibi işaretler
echo "$err" | grep -qiE "429|rate|too many|timeout|temporarily|retry" && return 0
return 1
}
{
flock -n 9 || { echo "$(date -Is) lock bekleniyor" >> "$LOG_FILE"; exit 0; }
echo "$(date -Is) $DOMAIN LE ile deniyorum" >> "$LOG_FILE"
if issue_with "letsencrypt" 2>&1; then
echo "$(date -Is) $DOMAIN LE başarılı" >> "$LOG_FILE"
exit 0
else
ERR_MSG=$(tail -n 50 ~/.acme.sh/acme.sh.log || true)
if should_fallback "$ERR_MSG"; then
echo "$(date -Is) $DOMAIN ZeroSSL fallback deniyorum" >> "$LOG_FILE"
if issue_with "zerossl" 2>&1; then
echo "$(date -Is) $DOMAIN ZeroSSL başarılı" >> "$LOG_FILE"
exit 0
else
echo "$(date -Is) $DOMAIN ZeroSSL de başarısız" >> "$LOG_FILE"
exit 2
fi
else
echo "$(date -Is) $DOMAIN Hata fallback tetiklemiyor" >> "$LOG_FILE"
exit 1
fi
fi
} 9>"$LOCK_FILE"
Bu kadar. Basit ama iş görür. Burada birkaç detay var. Birincisi, flock ile tek seferde tek işlem koşmasını sağladım. İkincisi, hata metni üzerinden sezgisel bir kontrol var; elbette kendi log formatınıza göre daha akıllı kurallar yazabilirsiniz. Üçüncüsü, kurulum ve sunucu reload’u her iki yolda da aynı.
Staging ile prova
Ben her yeni akışa staging ile prova yaptırırım. Let’s Encrypt’in test ortamı işinizi görür; ZeroSSL tarafında da test uçlarını gözden geçirin. Böylece her şey gerçek dünyaya çıkmadan, DNS izinleriniz, env değişkenleriniz, reload komutlarınız prova alır. Let’s Encrypt oran limitleri dokümanı elinizin altında olsun; bazı ipuçları plan yaparken çok yardımcı.
Oran Limitlerine Sakin Kalmak: Zaman, Dalga ve Jitter
Hepsi aynı dakikada yenilenmesin
İşin sırrı, yenileme takvimini akıllı kurmak. Mesela tüm sertifikaları ayın aynı gününde, aynı dakikada yenilemeye kalkmayın. Küçük gruplar, farklı saatler, hatta birkaç dakikalık jitter eklemek bile mucize gibi işliyor. Böylece ne birincil CA’yı ne yedeği bunaltıyorsunuz. Yedekli CA’ya geçtiğiniz anlarda bile trafik nazik akıyor.
Bir diğer ufak ayar, yenileme eşiğini biraz yukarıda tutmak. Yüzde yüz bittiği gün değil de, birkaç gün öncesinden planlı yenileme sizi rahatlatır. acme.sh zaten otomatik cron ekliyor; ama büyük filolarda kendi scheduling katmanınızı da koyup dalga dalga yayınlama fikri çok hoş çalışıyor.
SAN ve wildcard ile “az sayıda, anlamlı sertifika”
Aynı domain grubu için birden çok sertifika çıkarmak yerine, mantıklı SAN setleri ve wildcard’larla akıllı paketler oluşturmak hem keyifli hem verimli. Bu sayede gereksiz sertifika sayısı azalır, oran limitleriyle aranıza tatlı bir mesafe koyarsınız. Şu yazıda, bu yaklaşımı daha detaylı anlattım: Let’s Encrypt rate limit’lerine takılmadan çok alan adında SSL almak için tatlı stratejiler. Bir göz atın, özellikle çok alan adı olan ekipler için ufuk açıcı oluyor.
Dağıtım ve Güvenlik: Dosya Yolları, Yetkiler, Sırların Saklanması
Dosya düzenini baştan kur
Üretimde işler stabil kalsın istiyorsanız, sertifika ve anahtar yollarınızı baştan netleştirin. Ben genelde /etc/ssl altında alan adı başına klasörler kullanıyorum, anahtar dosyalarının yetkilerini en kısıtlı şekilde tutuyorum. acme.sh’nin --install-cert adımıyla bu yolları sabitleyip web sunucusuna reload verince, yayın katmanı hiç dokunulmadan temiz bir akış elde ediliyor.
Ortam değişkenleri ve sır yönetimi
DNS API token’ları, EAB bilgileri… Bunların hepsi kıymetli. CI/CD pipelinelarında maskelenmiş değişkenler, prod sunucularda da sadece acme.sh’nin aksesine izin verilen servis hesapları kullanmak optimum. Log seviyesini açarken de bir an durup düşünün; debug kültürü güzel ama gizli bilgi sızdırmasın. Hatta bazı ortamlarda, sırların değişim sıklığını artırıp kısa ömürlü erişim belirteçlerine geçmek de iyi geliyor.
Gözlemleme: Log, Metrik ve Küçük Alarmcıklar
“Gece iyi geçti mi?” sorusunun cevabı
Benim küçük bir gecelik ritüelim var: Sabah kahveyle birlikte gecenin log özetine bir göz atarım. acme.sh kendi log dosyasını tutuyor; fallback wrapper’ınız da ayrı bir log yazsın. Oradan basit bir metrik toplayıp “kaç deneme Let’s Encrypt ile oldu, kaç tanesi yedeğe geçti?” sorusuna cevap üretmek hem sağlık raporu gibi hem de erken uyarı sistemi.
Hata oranı artıyorsa, tetik koşullarını gözden geçirirsiniz. Ya çok sık aralıklarla deniyorsunuzdur, ya da bir grubu aynı dakikaya yığmışsınızdır. Bazen de sadece internet tarafında küçük çalkantılar. Alarm seviyelerini makul tutun; sabaha kadar telefon çalsın istemeyiz. Birkaç başarısız denemeden sonra toplu alarm üretmek iyi bir denge sağlıyor.
Operasyonel İpuçları: Küçük Dokunuşlar, Büyük Rahatlık
Test ortamı, üretim ortamı ve hesap ayrımı
Staging, test, preprod ve prod için hesapları ve EAB bilgilerinin saklandığı yerleri ayrı tutmak, kafayı müthiş rahatlatıyor. Böylece yanlış ortamda yanlış CA hesabını kullanma riski ortadan kalkıyor. Ayrıca staging’de bol bol deneyip prod’daki yenileme dalgalarına dokunmadan öğrenme şansınız oluyor.
Retry politikası ve nezaket
Her başarısız denemede saniyede bir tekrar etmek yerine, nazik bir geri çekilme uygulayın. Birkaç dakika bekleyip yeniden deneyin; eğer fallback tetiklenecekse zaten edecek. Bu, hem birincil CA’ya hem de yedeğe olan saygınızı gösterir. Unutmayın: İyi vatandaş olmak, uzun vadede altyapınızın dost kazanması demek.
Değişim günleri
Arada bir, özellikle yoğun sezonlardan önce, fallback senaryosunu canlıya yakın koşullarda prova edin. Bir iki alan adı üzerinde Let’s Encrypt’i bilinçli olarak başarısız sayıp ZeroSSL’ye geçisin. Script’in kilitleri tutuyor mu, log’da istediğiniz veriyi görüyor musunuz, reload sonrası servis ayakta mı? Küçük bir akşam seansıyla büyük stresleri sıfırlarsınız.
Gerçekçi Bir Akış: Baştan Sona Mini Senaryo
Şöyle düşünün. Pazartesi sabahı, saat başında yenileme dalgasının ilki koşacak. Cron, wrapper script’i çağırıyor. İlk alan adları Let’s Encrypt’ten tatlı tatlı düşüyor. Derken, üçüncü grupta birkaç alan adı 429 yemeye başlıyor. Script, log satırında bunu fark ediyor. “Tamam,” diyor, “sakin olalım, ZeroSSL’yi yoklayalım.” Deneme başarılı. Sertifika kuruldu, web sunucusu reload oldu. Son kullanıcı hiçbir şey fark etmeden yoluna devam ediyor.
İlerleyen saatlerde trafik normale dönüyor. Bir sonraki dalgada sistem Let’s Encrypt’e geri dönüyor. Yani fallback bir geçiş bileti, kalıcı taşınma değil. Akşamüstü raporlarına bakınca görüyorsunuz: Bugün 120 sertifika başarıyla yenilenmiş, 7’si ZeroSSL’ye düşmüş. Bu, işte tam olarak görmek istediğimiz resim. Planlı, ölçülü, nazik bir ölçeklenme.
Kaynaklar: Kısa Kısa, Doğru Kapılar
acme.sh’nin kendisi çok güzel belgelenmiş. Vakit ayırıp göz atmak, küçük bayrakları ezberlemek inanılmaz hız kazandırıyor: acme.sh resmi deposu ve dokümantasyonu. Let’s Encrypt tarafında, oran limitlerinin mantığını, istisnaları ve güzel ipuçlarını şuradan okuyabilirsiniz: Let’s Encrypt rate limits dokümanı. ZeroSSL cephesinde ise EAB akışı, uç noktalar ve örnekler işinizi kolaylaştırır: ZeroSSL ACME dokümantasyonu ve EAB detayları.
Kapanış: Yedekli CA, Sakin Otomasyon ve Rahat Bir Gece Uykusu
Toparlayalım. Sertifika otomasyonu, basit bir komutla başlayan ama ölçek büyüdükçe ince ayar isteyen bir iş. acme.sh ile Let’s Encrypt’i birincil, ZeroSSL’yi yedek tuttuğunuz bir kurgu, sizi hem oran limitleri hem de beklenmedik kesintiler karşısında güçlü kılıyor. Küçük bir wrapper, nazik bir retry politikası, iyi seçilmiş yenileme takvimi ve düzgün log/metric düzeni… Hepsi bir araya gelince, “ofiste panik yok, kahve sıcak” günler artıyor.
Eğer çok alan adı yönetiyorsanız, wildcard ve SAN stratejileriyle gereksiz yoğunluğu baştan budayın. DNS-01 ile doğrulama otomatik akarken, sır yönetimini sıkı tutun, staging ile prova yapmayı ihmal etmeyin. Unutmayın: Bazen mesele sertifikayı almak değil, her defasında güvenle almak. Bu yazıdaki örnekleri kendi ortamınıza uyarlarken, küçük deneylerle yolunuzu bulmanız işinizi kolaylaştırır.
Umarım bu rehber günün bir yerinde size nefes aldırır. Bir gün, sabah kahvesinde loglarda kırmızı satırlar görürseniz, aklınıza şu cümle gelsin: “Sakin ol, fallback var.” Bir dahaki yazıda, bu akışı daha da tatlandıran küçük otomasyon hilelerinden konuşalım. Şimdilik hoşça kalın, kuyruktaki sertifikalarınız gökyüzündeki bulutlar kadar yumuşak olsun.
