SSD Nodes Learn
Mga Gabay Matt ConnorNi Matt Connor · Na-update 2026-07-24

Paano i-install ang Certbot sa Ubuntu 24.04

Alamin ang tamang paraan ng pag-install ng Certbot gamit ang apt o snap sa Ubuntu 24.04 para sa nginx at iwasan ang error sa port 80 renewal timeout.

I-install ang Certbot: apt o snap

Sa Ubuntu 24.04, ang sudo apt install certbot python3-certbot-nginx ay nagbibigay ng gumaganang Certbot na naglalabas ng mga totoong Let's Encrypt certificates na trusted ng publiko. Iminumungkahi ng upstream docs ng Certbot ang paggamit ng snap; maliit lang ang pagkakaiba — ang snap ay sumusunod sa mga upstream release, habang ang archive package ay sumusunod sa kung ano ang kasama sa LTS at tumatanggap ng mga security fix.

Pumili ng isa. Ang pagkakaroon ng dalawang kopya ng Certbot ay nangangahulugang dalawang renewal timer na nakatutok sa iisang /etc/letsencrypt tree, at ang kopya na nakalimutan mo ang magdudulot ng problema.

Ang apt path:

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

I-install nito ang /usr/bin/certbot, ang nginx plugin, isang certbot.service + certbot.timer pair, at isang /etc/cron.d/certbot entry na walang ginagawa sa ilalim ng systemd.

Ang snap path:

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

Ang snap ay may kasamang sariling timer, ang snap.certbot.renew.timer. I-uninstall ang apt package bago i-install ang snap.

Pareho ang magiging gawi ng dalawang install pagkatapos nito. Ang Certbot 2.x ay naka-default sa ECDSA (P-256) keys — gamitin lamang ang --key-type rsa para sa mga client na hindi kayang gumamit ng ECDSA. Ang lahat ng state ay nasa ilalim ng /etc/letsencrypt: ang archive/ ay naglalaman ng mga totoong key at certificate files, ang live/ ay mga symlink sa mga kasalukuyang files, ang renewal/ ay may isang config file bawat certificate, at ang accounts/ ay ang iyong ACME account key.

Ano ang ginagawa ng HTTP-01, at bakit hindi optional ang port 80

Ang HTTP-01 challenge ay isang callback. Humihingi ka ng certificate para sa example.com sa Let's Encrypt; i-re-resolve nito ang pangalan sa public DNS, bubuksan ang connection sa port 80 sa address na nahanap nito, at hihilingin ang http://example.com/.well-known/acme-challenge/<token>. Sasagot ang server mo gamit ang eksaktong token content na isinulat lang ng Certbot sa disk. Iyan ang buong mekanismo. May tatlong epekto nito, at ito ang sanhi ng karamihan sa mga failed issuance.

  • Dapat reachable ang port 80 mula sa public internet, hindi lang mula sa laptop mo. Ang isang ufw rule, cloud-provider security group, o VPS-console firewall na nagbubukas lang ng 443 ay magpapabigo sa issuance at sa lahat ng susunod na renewal.
  • Dapat nakaturo na ang DNS sa server na ito. Ang validation server ay gumagawa ng sariling lookup mula sa labas; walang halaga sa kanya ang iyong mga /etc/hosts entry at browser cache.
  • Kung nag-publish ka ng AAAA record, IPv6 ang unang susubukan. Mag-re-retry ang Let's Encrypt sa IPv4 kapag biglang nag-fail ang IPv6 connection — pero ang isang stale AAAA na nakaturo sa host na tumatanggap ng connection pero iba ang sineserve ay magreresulta sa hard failure.

Pinapayagan ang mga redirect: ang validation ay susunod sa HTTP redirect patungong HTTPS at hindi mahalaga kung ang certificate sa kabilang dulo ay missing, expired, o self-signed. Ang hindi nito gagawin ay magsimula sa kahit anong port maliban sa port 80. Walang TLS-ALPN-01 implementation ang Certbot, kaya ang "gamitin lang ang 443" ay hindi isang escape hatch.

Pagpili ng authenticator: --nginx, --webroot, --standalone

Ang --nginx ang tamang default kung tumatakbo na ang nginx at nagsisilbi na ang domain. Binabasa ng Certbot ang iyong config, naglalagay ng temporary challenge location, nire-reload ang nginx, nagve-validate, at isinusulat ang mga TLS directive sa iyong server block. Walang downtime.

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

Para sa scripted setup sa bagong box:

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

Ang --webroot ay tama kung ayaw mong pakialaman ng Certbot ang iyong nginx config — halimbawa ay config na galing sa template, nasa git, o ipinapadala via Ansible. Isinusulat lang ng Certbot ang challenge file sa isang directory na kasalukuyan mo nang isineserbisyo.

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

Ang --standalone ay tama kung walang nakikinig sa port 80: gaya ng mail server, isang API na 443 lang ang protocol, o isang first-boot script na tumatakbo bago pa mag-exist ang nginx. Ang Certbot mismo ang magba-bind sa port 80 sa loob ng ilang segundo. Kung tumatakbo ang nginx, mag-eerror ito — i-stop muna ito bago patakbuhin:

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

Ang mga hooks na ito ay nakatala sa renewal config ng certificate, kaya awtomatikong mangyayari ang parehong stop/start kapag nag-renew na.

Isang server block na gumagana bago at pagkatapos magkaroon ng certificate

Ang chicken-and-egg problem: hindi mag-uumpisa ang nginx dahil ang ssl_certificate ay nakaturo sa file na wala pa, at hindi makakapag-validate ang Certbot habang down ang nginx. I-on muna ang site sa port 80.

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;
    }
}

I-run ang sudo nginx -t && sudo systemctl reload nginx, i-confirm ang mga sagot mula sa curl -I http://example.com/ mula sa labas ng system, at pagkatapos ay mag-issue. Pagkatapos nito:

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;
    }
}

Mahalaga ang ^~ prefix sa ACME location: pinipigilan nito ang return 301 block na ma-absorb ang challenge request. Dahil ang location na ito ay nasa port 80, patuloy na gagana ang mga renewal kahit HTTPS-only na ang natitirang bahagi ng site.

Depende sa iyong nginx version ang HTTP/2 syntax, at ang paghahalo ng dalawang anyo nito ay magdudulot ng startup error. Ang Ubuntu 24.04 ay may nginx 1.24, na nangangailangan ng inline configuration — listen 443 ssl http2;. Ang Debian 13 ay may mas bagong nginx, na nangangailangan ng hiwalay na http2 on; directive. I-check muna ang nginx -v.

Ituro ang nginx sa live/, huwag sa archive/. Ang mga live/ symlink ay binabago sa bawat renewal; ang paggamit ng hard path sa archive/ ay magkakabit sa iyo sa isang certificate na mag-eexpire.

Ang Wildcards ay nangangahulugang DNS-01, at ang DNS-01 ay nangangahulugang isang plugin

Hindi maaaring i-validate ang wildcard certificate (*.example.com) gamit ang HTTP-01 — walang iisang hostname para i-fetch ang file. DNS-01 lamang ang tanging paraan: patunayan ang kontrol sa pamamagitan ng pag-publish ng _acme-challenge.example.com TXT record. Kailangan ng Certbot ng API credentials para sa iyong DNS provider upang magawa ito nang unattended; ito ang dahilan kung bakit may mga provider plugin. Ang kumpletong walkthrough para sa wildcard certificate ay sumasaklaw sa mechanics ng TXT record at sa renewal trap sa manual mode; kasunod nito ang maikling bersyon para sa Cloudflare.

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

Sa apt path, ito ay sudo apt install python3-certbot-dns-cloudflare sa halip. Ang credentials ay dapat ilagay sa isang file na para sa root lamang:

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

Limitahan ang scope ng token sa DNS-edit rights para sa zone na iyon lamang. Ito ay isang key para sa iyong DNS; ituring itong parang isang key.

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

I-quote ang wildcard upang hindi ito i-glob ng iyong shell. Nalulutas din ng DNS-01 ang hindi kaya ng HTTP-01: mga certificate para sa mga host na walang public port 80 — isang internal service, isang box na maaabot lamang via self-hosted WireGuard VPN sa isang VPS, o isang admin panel sa isang private interface.

Renewal: ang 90 days, ang timer, at ang deploy hook

Ang Let's Encrypt certificates ay valid sa loob ng 90 days. Nagre-renew ang Certbot kapag may kulang na lang na 30 days, kaya mayroon kang 30-day window para ayusin ang anumang error sa renewal bago pa magkaroon ng outage. Hindi na nagpapadala ang Let's Encrypt ng expiry-warning emails — walang magpapaalala sa iyo, kaya responsibilidad mo na ang monitoring.

I-check ang timer na kasama sa iyong install:

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

Sinisuri ng certbot renew ang bawat config sa /etc/letsencrypt/renewal/, ini-skip ang anumang wala sa 30-day window, at ni-re-renew ang iba gamit ang eksaktong flags mula sa orihinal na run. Ito ang dahilan kung bakit mahalaga ang unang run: ito ang nire-record ng system.

Ang pag-renew ng file sa disk ay walang binabago sa mismong running process — patuloy na iseserve ng nginx ang lumang certificate mula sa memory hanggang sa utusan itong mag-reload. Mag-set up ng isang deploy hook:

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

Anumang executable sa renewal-hooks/deploy/ ay tatakbo pagkatapos ng anumang matagumpay na renewal. Ginagawa rin ng --deploy-hook flag ang parehong trabaho para sa isang certificate, kung saan iniimbak ang renew_hook = ... sa renewal config nito. Ang certbot --nginx ay nagre-reload para sa iyo; ang --webroot at --standalone setups ay hindi. Ang kawalan ng hook ang dahilan kung bakit nagse-serve ang isang site ng expired na certificate habang ang certbot certificates ay nag-uulat na bago na ang certificate. Anumang ibang app na nagbabasa ng certificate sa startup ay nangangailangan din ng parehong hook — ang mga containerised app gaya ng Nextcloud VPS install na may Docker, TLS, at backups ay kailangan din ng sariling restart o reload step na naka-set up dito.

Testing renewal for real

sudo certbot renew --dry-run

Pinapatakbo nito ang buong challenge laban sa staging environment ng Let's Encrypt: parehong code path, parehong firewall, parehong DNS, walang rate-limit cost, at walang sinusulat sa disk. Kung papasa ito ngayon, papasa rin ang unattended renewal sa loob ng 60 days, basta't walang magbabago sa configuration ng server.

Ang dry run ay hindi nagpapatunay na gumagana ang iyong reload hook — nag-iiba ang behavior nito depende sa Certbot version. I-test ang bahaging iyon nang manual: i-execute ang hook script nang direkta, kumpirmahin na nagtagumpay ang systemctl reload nginx, at i-check ang sudo grep renew_hook /etc/letsencrypt/renewal/example.com.conf.

Ang mga error na maaari mong ma-encounter

Could not bind to IPv4 or IPv6.--standalone dahil gamit na ng nginx ang port 80. Gamitin ang --nginx o --webroot, o i-stop ang nginx bago i-run. I-verify ang gumagamit ng port gamit ang sudo ss -lntp | grep ':80'.

Timeout during connect (likely firewall problem) — Hindi maabot ng Let's Encrypt ang port 80. Suriin ang mga sumusunod: sudo ufw status (i-open ito gamit ang sudo ufw allow 'Nginx Full'), ang firewall ng VPS provider, at ang DNS. I-test mula sa ibang server: curl -sSv http://example.com/.well-known/acme-challenge/test. Nagdudulot din ang stale AAAA record ng ganitong error.

unauthorized :: Invalid response from http://example.com/.well-known/acme-challenge/xyz: 404 — reachable ang port 80, pero hindi naibibigay ang token. Ang request ay napunta sa ibang server block (i-check kung alin ang may-ari ng default_server), o ang directory na ibinigay sa -w ay hindi ang sineserve ng nginx. Maglagay ng file sa /var/www/example.com/.well-known/acme-challenge/test at i-access ito mula sa labas; kung mag-404 ito, hindi ang certificate ang problema.

DNS problem: NXDOMAIN looking up A for example.com — hindi nag-re-resolve ang pangalan sa publiko. Maaaring hindi pa propagated ang mga bagong record, o ang record ay nasa zone na hindi sineserve ng iyong registrar.

too many certificates already issued for: example.com — ito ay rate limit, karaniwang nararanasan kapag nagde-debug nang paulit-ulit. May limit ang Let's Encrypt sa duplicate certificates — ang eksaktong parehong set ng mga pangalan — na lima kada linggo, at hiwalay na pinapayagan ang 50 bagong certificates bawat registered domain kada linggo; walang paraan para ma-bypass ito kundi ang maghintay. Mag-debug gamit ang staging sa pamamagitan ng --dry-run.

nginx: [emerg] cannot load certificate "/etc/letsencrypt/live/example.com/fullchain.pem": No such file or directory — naka-configure ang nginx para sa certificate na hindi pa na-i-issue, o isa na tinanggal gamit ang certbot delete. I-comment out ang TLS server block, i-start ang nginx, i-issue ang certificate, at i-restore ang block.

**open() "/etc/letsencrypt/options-ssl-nginx.conf" failed — Ang file na ito ay kasama sa nginx plugin package. Sa isang certonly box na walang python3-certbot-nginx, i-install ang plugin o palitan ang include line ng sarili mong ssl_protocols at ssl_ciphers settings.

Pag-manage nito sa scale

Ang isang certificate ay maaaring maglaman ng hanggang 100 na pangalan. Nakakaakit gumamit ng iisang certbot --nginx -d a.example.com -d b.example.com ... — hanggang sa magkaroon ng error sa validation dahil sa isang stale DNS record, na magpapabagsak sa lahat ng iba pang pangalan sa certificate na iyon. Kapag hiwalay ang mga certificate bawat site, hindi sila sabay-sabay na mag-eerror. Ito ang kailangan sa isang server na nagho-host ng maraming serbisyo. Kapag marami na ang sites, mas mainam ang isang ACME-aware front door: ang isang Traefik reverse proxy na tumatakbo sa Docker Compose ang humihiling at nagre-renew ng mga certificate, kaya hindi na kailangan ang Certbot.

I-back up ang buong /etc/letsencrypt — kasama ang mga sudo tar -czf letsencrypt-$(date +%F).tar.gz -C /etc letsencrypt — at panatilihing intact ang mga symlink. Ang directory tree na ito ay naglalaman ng accounts/, ang iyong ACME account key, na hindi mo maaaring i-regenerate nang eksaktong pareho. Kapag lumipat sa bagong VPS, ang kailangan lang gawin ay: i-rsync ang tree gamit ang -a, i-install ang Certbot, i-update ang DNS, at i-run ang certbot renew --dry-run bago ang cut over.

Hindi kasama sa renewal timer ang paglipat sa bagong LTS o ang pag-rebuild ng server. Pagkatapos ng anumang migration, snapshot restore, o distro upgrade, i-run ang systemctl list-timers 'certbot*' at isang --dry-run. Ang hindi paggawa nito ang dahilan kung bakit nawawalan ng access ang isang site pagkalipas ng 89 na araw, sa ganap na 3am, dahil sa certificate na akala ng lahat ay kusang nagre-renew.

Ang lahat ng ito ay para sa machine na kontrolado mo, may public IP, at bukas ang port 80 sa mundo — sa madaling salita, isang VPS. Ang mga mekanismo sa itaas ay pareho sa lahat ng ganitong setup.

Ang parehong mga hakbang para sa certificate ay applicable sa Apache sa halip na nginx, at kung hindi posible ang public certificate, ang self-signed certificate sa Ubuntu ay sapat na para sa mga internal na serbisyo.

FAQ

Kailangan ko bang i-open ang port 80 kung HTTPS lang ang gamit ng site ko?

Oo, para sa HTTP-01 challenge. Laging nagsisimula ang validation request ng Let's Encrypt sa port 80. Walang TLS-ALPN-01 implementation ang Certbot, kaya kung ang firewall ay port 443 lang ang bukas, mababara nito ang unang issuance at ang lahat ng susunod na unattended renewal. Ayos lang ang redirect mula port 80 patungong HTTPS dahil sinusundan ito ng validation. Ang tanging paraan para hindi na gamitin ang port 80 ay ang DNS-01 gamit ang provider plugin.

apt o snap — alin sa Certbot ang dapat kong i-install para sa nginx sa Ubuntu 24.04?

Gamitin ang apt. Ang sudo apt install certbot python3-certbot-nginx ay nagbibigay ng Certbot 2.9.0 sa Ubuntu 24.04, na sapat na para sa lahat ng nasa guide na ito. Nakakakuha ito ng security patches sa pamamagitan ng unattended-upgrades at hindi nangangailangan ng snapd. Gamitin lang ang snap kung kailangan mo agad ang pinakabagong release o kung ang DNS plugin ay available lang bilang snap. Sa alinmang paraan, pumili lang ng isa: ang dalawang install ay nangangahulugang dalawang renewal timers ang nakaturo sa iisang /etc/letsencrypt tree, at ang nakalimutang isa ang magdudulot ng error.

Kayang mag-issue ng Certbot ng wildcard certificate para sa nginx?

Sa DNS-01 lamang. Ang wildcard na gaya ng *.example.com ay walang iisang hostname para i-fetch ang challenge file, kaya hindi pwede ang --nginx, --webroot at --standalone. I-install ang plugin para sa iyong DNS provider, maglagay ng scoped API token sa isang root-only credentials file, at i-run ang certbot certonly --dns-cloudflare -d example.com -d '*.example.com', gamit ang quotes sa wildcard para maiwasan ang shell globbing.

Bakit nginx pa rin ang nagse-serve ng lumang certificate kahit successful na ang renewal?

Nananatili ang certificate sa memory ng nginx at hindi nito napapansin ang bagong file sa disk hangga't hindi nagre-reload. Ginagawa ng certbot --nginx ang reload para sa iyo, pero ang --webroot at --standalone ay hindi, kaya maaaring maging successful ang renewal habang ang nakikita pa rin sa browser ay ang expiring na certificate. Maglagay ng executable script sa /etc/letsencrypt/renewal-hooks/deploy/ na nagpapatakbo ng nginx -t && systemctl reload nginx, para mag-trigger ito pagkatapos ng bawat successful renewal.

Nagpapatunay ba ang certbot renew --dry-run na gagana ang renewal?

Halos lahat. Pinapatakbo nito ang totoong challenge laban sa staging environment — parehong firewall, parehong DNS, at parehong code path — nang walang rate-limit cost at walang sinusulat sa disk, kaya ang pagpasa ay nangangahulugang maayos ang network side. Ngunit hindi nito mapapatunayan nang sigurado kung gagana ang iyong deploy hook. I-test ito nang hiwalay: i-run ang hook script nang manual at i-check ang sudo grep renew_hook /etc/letsencrypt/renewal/example.com.conf.