SSD Nodes Learn
Rehberler Matt ConnorYazan Matt Connor · Güncellendi 2026-07-24

Ubuntu 24.04 Nginx Certbot Kurulum Rehberi

Ubuntu 24.04 üzerinde apt veya snap ile Certbot kurulumu yapın. Let's Encrypt sertifikası için sudo apt install certbot python3-certbot-nginx komutunu kullanın.

Certbot Kurulumu: apt veya snap

Ubuntu 24.04 üzerinde sudo apt install certbot python3-certbot-nginx, gerçek ve halka açık olarak güvenilen Let's Encrypt sertifikaları düzenleyen çalışan bir Certbot sağlar. Certbot'un resmi dokümantasyonu snap kullanımını önermektedir; aradaki fark azdır — snap sürümü güncel sürümleri takip eder, arşiv paketi ise LTS ile birlikte gelen sürümü takip eder ve güvenlik düzeltmelerini alır.

Birini seçin. İki Certbot kopyası, aynı /etc/letsencrypt ağacını hedefleyen iki farklı yenileme zamanlayıcısı anlamına gelir; unuttuğunuz zamanlayıcı beklenmedik hatalara yol açar.

apt yolu:

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

Bu işlem /usr/bin/certbot, nginx eklentisini, bir certbot.service + certbot.timer çiftini ve systemd altında işlevsiz kalan bir /etc/cron.d/certbot girişini yükler.

snap yolu:

sudo apt remove certbot python3-certbot-nginx
sudo snap install core && sudo snap refresh core
sudo snap install --classic certbot
sudo ln -s /snap/bin/certbot /usr/bin/certbot

Snap, kendi zamanlayıcısı olan snap.certbot.renew.timer ile birlikte gelir. Snap kurulumundan önce apt paketini kaldırın.

Her iki kurulum da sonrasında aynı şekilde çalışır. Certbot 2.x sürümlerinde varsayılan olarak ECDSA (P-256) anahtarları kullanılır; yalnızca ECDSA desteklemeyen istemciler için --key-type rsa parametresini kullanın. Tüm durum verileri /etc/letsencrypt altında tutulur: archive/ gerçek anahtar ve sertifika dosyalarını, live/ güncel dosyalara yönlendirmeleri (symlinks), renewal/ sertifika başına bir yapılandırma dosyasını ve accounts/ ACME hesap anahtarınızı içerir.

HTTP-01 işleminin işleyişi ve 80 portunun neden zorunlu olduğu

HTTP-01 doğrulaması bir geri çağırma (callback) işlemidir. Let's Encrypt'ten example.com için bir sertifika talep edilir; servis, ismi halka açık DNS üzerinden çözer, bulduğu adresteki 80 portuna bir bağlantı açar ve http://example.com/.well-known/acme-challenge/<token> talep eder. Sunucunuz, Certbot'un diske yazdığı token içeriğinin aynısını döndürmelidir. Mekanizma bu şekilde çalışır. Bu durumdan kaynaklanan üç sonuç, sertifika alma işlemlerinin çoğunun başarısız olmasına neden olur.

  • 80 portu sadece dizüstü bilgisayardan değil, halka açık internetten erişilebilir olmalıdır. Bir ufw kuralı, bulut sağlayıcı güvenlik grubu veya yalnızca 443 portuna izin veren bir VPS konsol güvenlik duvarı, sertifika alma ve sonraki tüm yenileme işlemlerini engeller.
  • DNS kaydı halihazırda bu sunucuya işaret etmelidir. Doğrulama sunucusu, dışarıdan kendi sorgulamasını yapar; /etc/hosts kayıtlarınızın veya tarayıcı önbelleğinizin bu işlem için bir önemi yoktur.
  • Eğer bir AAAA kaydı yayınlarsanız, önce IPv6 denenir. IPv6 bağlantısı tamamen başarısız olduğunda Let's Encrypt IPv4 üzerinden tekrar dener; ancak bağlantıyı kabul eden fakat başka bir içerik sunan hatalı bir AAAA kaydı, işlemin doğrudan başarısız olmasına yol açar.

Yönlendirmelere (redirect) izin verilir: Doğrulama, HTTPS'e yapılan bir HTTP yönlendirmesini takip eder; uç noktadaki sertifikanın eksik, süresi dolmuş veya kendi imzalı (self-signed) olması durumu önemsemez. Ancak işlem, 80 portu dışında bir noktadan başlatılamaz. Certbot'un TLS-ALPN-01 uygulaması yoktur, bu nedenle "sadece 443 portunu kullanın" bir çözüm değildir.

Bir kimlik doğrulayıcı seçimi: --nginx, --webroot, --standalone

Eğer nginx halihazırda çalışıyorsa ve alan adını zaten sunuyorsa, doğru varsayılan --nginx seçeneğidir. Certbot yapılandırmanızı ayrıştırır, geçici bir doğrulama konumu ekler, nginx'i yeniden yükler, doğrulamayı yapar ve ardından TLS direktiflerini server bloğunuza yazar. Kesinti yaşanmaz.

sudo certbot --nginx -d example.com -d www.example.com

Yeni bir kurulum için betik kullanımı:

sudo certbot --nginx \
  -d example.com -d www.example.com \
  --agree-tos -m ops@example.com --no-eff-email \
  --redirect --non-interactive

Certbot'un nginx yapılandırmanıza müdahale etmesini istemediğiniz durumlarda --webroot uygundur; örneğin bir şablondan oluşturulan, git üzerinde tutulan veya Ansible ile gönderilen yapılandırmalar için kullanılır. Certbot, yalnızca halihazırda hizmet verdiğiniz bir dizine doğrulama dosyasını yazar.

sudo certbot certonly --webroot -w /var/www/example.com \
  -d example.com -d www.example.com \
  --deploy-hook "systemctl reload nginx"

80 portunda hiçbir servis çalışmıyorsa --standalone uygundur: bir mail sunucusu, yalnızca 443 portunu kullanan bir API veya nginx kurulmadan önce çalışan bir ilk kurulum betiği gibi durumlar. Certbot, birkaç saniyeliğine 80 portuna kendisi bağlanır. Eğer nginx çalışıyorsa işlem başarısız olur; bu durumda nginx servisini durdurun:

sudo certbot certonly --standalone -d mail.example.com \
  --pre-hook "systemctl stop nginx" \
  --post-hook "systemctl start nginx"

Bu kancalar (hooks) sertifikanın yenileme yapılandırmasına kaydedilir. Böylece yenileme sırasında aynı durdurma/başlatma işlemleri otomatik olarak gerçekleştirilir.

Sertifika mevcutken ve mevcut değilken çalışan bir server block

Tavuk-yumurta problemi: nginx, ssl_certificate olmayan bir dosyayı işaret ettiği için başlatılamaz; nginx kapalıyken ise Certbot doğrulama yapamaz. Siteyi önce port 80 üzerinden ayağa kaldırın.

server {
    listen 80;
    listen [::]:80;
    server_name example.com www.example.com;

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

    location ^~ /.well-known/acme-challenge/ {
        root /var/www/example.com;
        default_type "text/plain";
        try_files $uri =404;
    }

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

sudo nginx -t && sudo systemctl reload nginx komutunu çalıştırın, curl -I http://example.com/ yanıtını sistem dışından doğrulayın ve ardından sertifika talebinde bulunun. Sonrasında:

server {
    listen 80;
    listen [::]:80;
    server_name example.com www.example.com;

    location ^~ /.well-known/acme-challenge/ {
        root /var/www/example.com;
        default_type "text/plain";
    }

    location / {
        return 301 https://$host$request_uri;
    }
}

server {
    listen 443 ssl;
    listen [::]:443 ssl;
    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/letsencrypt/options-ssl-nginx.conf;
    ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem;

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

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

ACME konumu üzerindeki ^~ öneki işlevseldir: return 301 bloğunun challenge isteğini yakalamasını engeller. Bu konumu port 80 üzerinde tutmak, sitenin geri kalanı sadece HTTPS üzerinden çalıştığında yenileme işlemlerinin devam etmesini sağlar.

HTTP/2 sözdizimi nginx sürümüne bağlıdır; iki formun karıştırılması başlatma hatasına yol açar. Ubuntu 24.04, satır içi kullanımı gerektiren nginx 1.24 ile gelir — listen 443 ssl http2;. Debian 13, ayrı bir http2 on; direktifi gerektiren daha yeni bir nginx sürümüyle gelir. Önce nginx -v kontrol edilmelidir.

nginx'i live/ adresine yönlendirin, asla archive/ adresine yönlendirmeyin. live/ sembolik bağlantıları her yenilemede güncellenir; archive/ içine sabit bir yol yazmak, süresi dolan bir sertifikaya bağlı kalmanıza neden olur.

Wildcard, DNS-01 demektir ve DNS-01 bir eklenti gerektirir

Bir wildcard sertifikası (*.example.com), HTTP-01 yöntemiyle doğrulanamaz; çünkü dosya çekilecek tek bir hostname bulunmamaktadır. Tek yol DNS-01 yöntemidir: Bir _acme-challenge.example.com TXT kaydı yayınlayarak kontrol sahibi olduğunuzu kanıtlarsınız. Certbot'un bu işlemi otomatik yapabilmesi için DNS sağlayıcınıza ait API kimlik bilgilerine ihtiyacı vardır; sağlayıcı eklentileri bu işe yarar. Tam wildcard sertifikası kılavuzu, TXT kaydı mekaniğini ve manuel moddaki yenileme sorununu kapsar; kısa Cloudflare sürümü aşağıdadır.

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

sudo apt install python3-certbot-dns-cloudflare olan apt yolunda durum farklıdır. Kimlik bilgileri yalnızca root yetkisine sahip bir dosyaya yazılır:

# /root/.secrets/cloudflare.ini
# then: sudo chmod 600 /root/.secrets/cloudflare.ini
dns_cloudflare_api_token = your_scoped_token_here

Token yetkisini, yalnızca ilgili zone için DNS düzenleme haklarıyla sınırlandırın. Bu, DNS'iniz için bir anahtardır; ona bir anahtar gibi davranın.

sudo certbot certonly \
  --dns-cloudflare \
  --dns-cloudflare-credentials /root/.secrets/cloudflare.ini \
  -d example.com -d '*.example.com'

Shell'in glob işlemi yapmaması için wildcard karakterini tırnak içine alın. DNS-01, HTTP-01'in yapamadığı bir sorunu da çözer: Herhangi bir açık 80 portu olmayan hostlar için sertifika sağlar — dahili bir servis, yalnızca bir VPS üzerindeki self-hosted WireGuard VPN üzerinden erişilebilen bir cihaz veya özel bir arayüzdeki yönetim paneli.

Yenileme: 90 gün, zamanlayıcı ve deploy hook

Let's Encrypt sertifikaları 90 gün geçerlidir. Certbot, kalan süre 30 günden az olduğunda yenileme işlemini gerçekleştirir. Bu durum, yenileme işleminin başarısız olması halinde sistemin kapanması yerine, 30 günlük bir düzeltme süreci sağlar. Let's Encrypt artık son kullanma tarihi uyarı e-postaları göndermemektedir; izleme sorumluluğu kullanıcıya aittir.

Kurulumla birlikte gelen zamanlayıcıyı kontrol edin:

systemctl list-timers 'certbot*' 'snap.certbot*'
sudo certbot certificates

certbot renew, /etc/letsencrypt/renewal/ içindeki tüm yapılandırmaları tarar, 30 günlük sürenin dışındakileri atlar ve geri kalanları orijinal çalıştırma bayraklarını kullanarak yeniler. İlk çalıştırma önemlidir; çünkü kaydedilen veri budur.

Diskteki dosyanın yenilenmesi tek başına bir değişiklik yaratmaz; nginx, yeniden yükleme komutu alana kadar eski sertifikayı bellekten sunmaya devam eder. Bir deploy hook tanımlayın:

sudo tee /etc/letsencrypt/renewal-hooks/deploy/reload-nginx.sh >/dev/null <<'EOF'
#!/bin/sh
set -e
nginx -t && systemctl reload nginx
EOF
sudo chmod +x /etc/letsencrypt/renewal-hooks/deploy/reload-nginx.sh

renewal-hooks/deploy/ içindeki yürütülebilir her dosya, başarılı bir yenilemeden sonra çalışır. --deploy-hook bayrağı, yenileme yapılandırmasında renew_hook = ... saklayarak tek bir sertifika için aynı işlevi görür. certbot --nginx sizin yerinize yeniden yükleme yapar; --webroot ve --standalone kurulumları yapmaz. Bir hook eksikliği, certbot certificates yeni bir sertifika raporlarken sitenin süresi dolmuş bir sertifika sunmasına neden olur. Başlangıçta sertifikayı okuyan diğer tüm yapılar da aynı hook işlemine ihtiyaç duyar; Docker, TLS ve yedekleme ile Nextcloud VPS kurulumu gibi konteyner tabanlı uygulamalar da buraya kendi yeniden başlatma veya yeniden yükleme adımını eklemelidir.

Gerçek yenileme testi

sudo certbot renew --dry-run

Bu işlem, Let's Encrypt'in staging ortamına karşı tam doğrulama gerçekleştirir: aynı kod yolu, aynı firewall, aynı DNS kullanılır; rate-limit sınırı uygulanmaz ve diske hiçbir veri yazılmaz. Eğer bugün başarılı olursa, sistem üzerinde bir değişiklik yapılmadığı sürece 60 gün sonraki unattended renewal işlemi de başarılı olacaktır.

Dry run işlemi, reload hook'un tetiklendiğini kanıtlamaz; bu davranış Certbot versiyonuna göre değişiklik gösterir. Bu kısmın testini manuel olarak yapın: hook script'ini doğrudan çalıştırın, systemctl reload nginx işleminin başarılı olduğunu onaylayın ve sudo grep renew_hook /etc/letsencrypt/renewal/example.com.conf durumunu kontrol edin.

Karşılaşabileceğiniz hatalar

Could not bind to IPv4 or IPv6. — nginx port 80'i zaten kullandığı için --standalone hatası alınır. --nginx veya --webroot kullanın ya da çalıştırma sırasında nginx'ı durdurun. Portu kullanan işlemi sudo ss -lntp | grep ':80' ile doğrulayın.

Timeout during connect (likely firewall problem) — Let's Encrypt port 80'e erişemedi. Sorunu dışarıdan inceleyin: sudo ufw status (sudo ufw allow 'Nginx Full' ile açın), ardından VPS sağlayıcısının kendi güvenlik duvarı ve son olarak DNS. Sunucu dışından test edin: curl -sSv http://example.com/.well-known/acme-challenge/test. Geçersiz bir AAAA kaydı da aynı mesajı verir.

unauthorized :: Invalid response from http://example.com/.well-known/acme-challenge/xyz: 404 — port 80 erişilebilir durumdadır ancak token sunulmamaktadır. İstek farklı bir server block içine düşmüştür (default_server kaydına hangi bloğun sahip olduğunu kontrol edin) veya -w parametresine iletilen dizin nginx tarafından sunulan dizin değildir. /var/www/example.com/.well-known/acme-challenge/test konumuna bir dosya ekleyin ve harici olarak erişmeyi deneyin; eğer 404 hatası alıyorsanız sorun sertifika değildir.

DNS problem: NXDOMAIN looking up A for example.com isim halka açık olarak çözümlenemiyor. Henüz yayılmamış yeni kayıtlar veya kayıt kuruluşunuz tarafından sunulmayan bir zone içindeki kayıtlar bu hataya neden olur.

too many certificates already issued for: example.com bir hız sınırıdır (rate limit) ve döngü halinde hata ayıklama yaparken sıkça karşılaşılan durumdur. Let's Encrypt, aynı isim setine sahip mükerrer sertifikalar için haftalık 5 adet sınırı uygular; ayrıca kayıtlı alan adı başına haftalık 50 yeni sertifika izni verir; zaman dışında hiçbir yöntem bu sınırı kaldırmaz. --dry-run ile staging ortamında hata ayıklama yapın.

nginx: [emerg] cannot load certificate "/etc/letsencrypt/live/example.com/fullchain.pem": No such file or directory nginx, hiç oluşturulmamış bir sertifika veya certbot delete ile kaldırılmış bir sertifika için yapılandırılmıştır. TLS server block kısmını yorum satırı yapın, nginx'ı başlatın, sertifikayı oluşturun ve bloğu geri yükleyin.

open() "/etc/letsencrypt/options-ssl-nginx.conf" failed bu dosya nginx plugin paketiyle birlikte gelir. python3-certbot-nginx bulunmayan bir certonly sisteminde, ya plugini ekleyin ya da include satırını kendi ssl_protocols ve ssl_ciphers ayarlarınızla değiştirin.

Ölçeklenebilir yapıda yönetim

Bir sertifika 100 isme kadar veri taşıyabilir ve tek bir certbot --nginx -d a.example.com -d b.example.com ... kullanmak cazip görünebilir; ancak geçersiz bir DNS kaydı doğrulama aşamasında hata verirse, sertifikadaki diğer tüm isimlerin geçerliliğini de yitirmesine neden olur. Her site için ayrı sertifikalar kullanıldığında, hatalar birbirinden bağımsız gerçekleşir; bu durum, birden fazla hizmet barındıran bir sunucu için istenen yöntemdir. Birkaç sitenin ötesine geçildiğinde, ACME destekli bir giriş noktası avantaj sağlar: Docker Compose altında birden fazla uygulama çalıştıran bir Traefik reverse proxy, sertifikaları kendisi talep eder ve yeniler, böylece Certbot sürece dahil edilmesine gerek kalmaz.

/etc/letsencrypt dizinini bütün olarak yedekleyin — sudo tar -czf letsencrypt-$(date +%F).tar.gz -C /etc letsencrypt — sembolik bağlantılar (symlinks) bozulmamalıdır. Bu dizin, aynısını yeniden oluşturamayacağınız ACME hesap anahtarınız olan accounts/ içeriğini barındırır. Yeni bir VPS'e geçiş süreci şu adımlardan ibarettir: dizini -a ile rsync ile taşıyın, Certbot kurun, DNS kayıtlarını güncelleyin ve geçiş yapmadan önce certbot renew --dry-run komutunu çalıştırın.

Sunucuyu yeniden kurmak veya yeni bir LTS sürümüne geçmek, yenileme zamanlayıcısının taşınmasını sağlamaz. Herhangi bir taşıma, snapshot geri yükleme veya dağıtım yükseltme işleminden sonra systemctl list-timers 'certbot*' ve bir --dry-run komutunu çalıştırın. Bu adımın atlanması, herkesin kendi kendine yenilendiğini varsaydığı bir sertifikanın 89 gün sonra, saat 03:00'te geçerliliğini yitirmesine ve sitenin kapanmasına neden olur.

Tüm bu süreçler, kontrolünüz altında olan, genel bir IP adresine sahip ve 80 portu dış dünyaya açık olan bir makine, yani bir VPS için geçerlidir. Yukarıdaki mekanizmalar tüm VPS türlerinde aynıdır.

Aynı sertifika adımları nginx yerine Apache üzerinde de geçerlidir; genel bir sertifikanın uygun olmadığı durumlarda ise Ubuntu üzerinde self-signed bir sertifika iç servisler için yeterlidir.

FAQ

Sitem sadece HTTPS üzerinden hizmet veriyorsa port 80'i açmam gerekir mi?

Evet, HTTP-01 challenge işlemi için gereklidir. Let's Encrypt doğrulama isteğini her zaman port 80 üzerinden başlatır. Certbot, TLS-ALPN-01 implementasyonuna sahip değildir; bu nedenle sadece 443 portuna izin veren bir firewall, hem ilk sertifika oluşturma işlemini hem de sonraki tüm otomatik yenilemeleri engeller. Port 80'den HTTPS'e yönlendirme yapılması uygundur; doğrulama işlemi bu yönlendirmeyi takip eder. Port 80'i tamamen atlamanın tek yolu, bir sağlayıcı eklentisi ile DNS-01 yöntemini kullanmaktır.

Ubuntu 24.04 üzerinde nginx için hangi Certbot'u kurmalıyım: apt mı yoksa snap mi?

apt kullanın. sudo apt install certbot python3-certbot-nginx, Ubuntu 24.04 üzerinde bu kılavuzdaki tüm işlemler için yeterli olan Certbot 2.9.0 sürümünü sağlar, güvenlik yamalarını unattended-upgrades üzerinden alır ve snapd gerektirmez. Snap seçeneğini yalnızca en yeni sürüme hemen ihtiyacınız varsa veya sadece snap olarak dağıtılan bir DNS eklentisi kullanacaksanız tercih edin. Her iki durumda da sadece bir yöntem seçin: iki ayrı kurulum, aynı /etc/letsencrypt dizinine işaret eden iki farklı yenileme zamanlayıcısı demektir ve unutulan zamanlayıcı sorun çıkaracaktır.

Certbot, nginx için wildcard sertifika oluşturabilir mi?

Yalnızca DNS-01 yöntemiyle. *.example.com gibi bir wildcard sertifikanın challenge dosyasını çekebileceği tek bir hostname yoktur; bu nedenle --nginx, --webroot ve --standalone yöntemleri kullanılamaz. DNS sağlayıcınız için gerekli eklentiyi kurun, kısıtlı yetkiye sahip bir API token'ı sadece root yetkisiyle erişilebilen bir kimlik doğrulama dosyasına yerleştirin ve shell globbing işlemini engellemek için wildcard kısmını tırnak içinde belirterek certbot certonly --dns-cloudflare -d example.com -d '*.example.com' komutunu çalıştırın.

Yenileme başarılı olmasına rağmen nginx neden hala eski sertifikayı sunuyor?

nginx sertifikayı bellekte tutar ve yeniden yüklenene (reload) kadar diskteki yeni dosyayı fark etmez. certbot --nginx işlemi sizin yerinize reload işlemini gerçekleştirir, ancak --webroot ve --standalone işlemleri bunu yapmaz; bu durum, yenileme başarılı olsa bile tarayıcının hala süresi dolmak üzere olan sertifikayı görmesine neden olabilir. /etc/letsencrypt/renewal-hooks/deploy/ dizinine nginx -t && systemctl reload nginx komutunu çalıştıran bir script ekleyin; böylece her başarılı yenilemeden sonra komut tetiklenir.

certbot renew --dry-run yenileme işleminin çalışacağını kanıtlar mı?

Büyük oranda evet. Bu komut, gerçek challenge işlemini staging ortamına karşı çalıştırır; aynı firewall, aynı DNS ve aynı kod yolu kullanılır. Herhangi bir rate-limit maliyeti oluşturmaz ve diske hiçbir veri yazılmaz, bu nedenle işlemin başarılı olması ağ kısmının sorunsuz olduğunu gösterir. Ancak, deployment hook işleminin tetiklendiğini kesin olarak kanıtlamaz. Bunu ayrı olarak test edin: hook scriptini manuel olarak çalıştırın ve sudo grep renew_hook /etc/letsencrypt/renewal/example.com.conf çıktısını kontrol edin.