Cara Pasang Certbot Nginx di Ubuntu 24.04
Ketahui cara pasang Certbot di Ubuntu 24.04 menggunakan apt atau snap. Panduan ini merangkumi arahan sudo apt install python3-certbot-nginx serta penyelesaian masalah port 80.
Pasang Certbot: apt atau snap
Pada Ubuntu 24.04, sudo apt install certbot python3-certbot-nginx memberikan anda Certbot yang berfungsi untuk mengeluarkan sijil Let's Encrypt yang sah dan dipercayai secara umum. Dokumentasi huluan (upstream) Certbot mengesyorkan penggunaan snap; perbezaannya kecil, iaitu snap menjejaki keluaran huluan, manakala pakej arkib menjejaki apa sahaja yang disertakan bersama LTS dan menerima tampalan keselamatan.
Pilih salah satu. Mempunyai dua salinan Certbot bermakna dua pemasa pembaharuan (renewal timers) yang menyasarkan pepohon /etc/letsencrypt yang sama, dan salinan yang anda terlupa itulah yang akan menimbulkan masalah.
Laluan apt:
sudo apt update
sudo apt install certbot python3-certbot-nginxIni memasang /usr/bin/certbot, pemalam nginx, pasangan certbot.service + certbot.timer, dan entri /etc/cron.d/certbot yang tidak melakukan apa-apa di bawah systemd.
Laluan snap:
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/certbotSnap menyertakan pemasanya sendiri, snap.certbot.renew.timer. Buang pakej apt sebelum memasang snap.
Kedua-dua pemasangan berkelakuan sama selepas itu. Certbot 2.x menggunakan kunci ECDSA (P-256) secara lalai, gunakan --key-type rsa hanya untuk klien yang tidak menyokong ECDSA. Semua keadaan (state) disimpan di bawah /etc/letsencrypt: archive/ menyimpan fail kunci dan sijil sebenar, live/ menyimpan pautan simbolik (symlink) kepada fail semasa, renewal/ menyimpan satu fail konfigurasi bagi setiap sijil, accounts/ menyimpan kunci akaun ACME anda.
Apakah fungsi sebenar HTTP-01, dan mengapa port 80 tidak boleh diabaikan
Cabaran HTTP-01 ialah satu bentuk panggil balik (callback). Anda meminta sijil daripada Let's Encrypt untuk melindungi example.com; ia menyelesaikan nama tersebut dalam DNS awam, membuka sambungan ke port 80 pada alamat yang ditemui, dan meminta http://example.com/.well-known/acme-challenge/<token>. Pelayan anda menjawab dengan kandungan token tepat yang baru sahaja ditulis oleh Certbot ke dalam cakera. Itulah keseluruhan mekanismenya. Tiga akibat terhasil daripada proses ini, dan ia menjadi punca kepada kebanyakan kegagalan pengeluaran sijil.
- Port 80 mesti boleh dicapai daripada internet awam, bukan sekadar daripada komputer riba anda. Peraturan
ufw, kumpulan keselamatan penyedia awan, atau firewall konsol VPS yang hanya membuka port 443 akan menggagalkan pengeluaran sijil serta setiap pembaharuan pada masa hadapan. - DNS mesti sudah menghala ke pelayan ini. Pelayan pengesahan melakukan carian sendiri dari luar; entri
/etc/hostsdan cache pelayar anda tidak memberi kesan kepadanya. - Jika anda menerbitkan rekod AAAA, IPv6 akan dicuba terlebih dahulu. Let's Encrypt akan mencuba semula melalui IPv4 apabila sambungan IPv6 gagal sepenuhnya, tetapi rekod AAAA yang lapuk dan menghala ke hos yang menerima sambungan tersebut namun menghidangkan kandungan lain akan menyebabkan kegagalan serta-merta.
Redirect dibenarkan: pengesahan akan mengikuti redirect HTTP ke HTTPS dan tidak mempedulikan sama ada sijil di hujung sana tiada, tamat tempoh, atau ditandatangani sendiri (self-signed). Apa yang ia tidak akan lakukan ialah bermula di mana-mana port selain port 80. Certbot tidak mempunyai implementasi TLS-ALPN-01, jadi "gunakan sahaja port 443" bukanlah jalan keluar.
Memilih pengesah: --nginx, --webroot, --standalone
--nginx ialah pilihan lalai yang tepat apabila nginx sudah berjalan dan sedang melayani domain tersebut. Certbot akan menghurai konfigurasi anda, menyuntik lokasi cabaran sementara, memuat semula nginx, melakukan pengesahan, kemudian menulis arahan TLS ke dalam blok pelayan anda. Tiada waktu henti (downtime).
sudo certbot --nginx -d example.com -d www.example.comSkrip, untuk pelayan baharu:
sudo certbot --nginx \
-d example.com -d www.example.com \
--agree-tos -m ops@example.com --no-eff-email \
--redirect --non-interactive--webroot adalah tepat apabila anda tidak mahu Certbot menyentuh konfigurasi nginx anda, contohnya jika anda menjana konfigurasi daripada templat, menyimpannya dalam git, atau menolaknya (push) menggunakan Ansible. Certbot hanya menulis fail cabaran ke dalam direktori yang sedang anda layani.
sudo certbot certonly --webroot -w /var/www/example.com \
-d example.com -d www.example.com \
--deploy-hook "systemctl reload nginx"--standalone adalah tepat apabila tiada apa-apa yang mendengar pada port 80: pelayan mel, API yang hanya menggunakan port 443, atau skrip but pertama yang dijalankan sebelum nginx wujud. Certbot akan mengikat (bind) port 80 sendiri untuk beberapa saat. Jika nginx sedang berjalan, proses ini akan gagal; hentikan nginx sebelum menjalankan arahan:
sudo certbot certonly --standalone -d mail.example.com \
--pre-hook "systemctl stop nginx" \
--post-hook "systemctl start nginx"Cangkuk (hook) tersebut direkodkan dalam konfigurasi pembaharuan sijil, jadi proses henti/mula yang sama akan berlaku secara automatik semasa pembaharuan.
Blok pelayan yang berfungsi sebelum dan selepas sijil wujud
Masalah ayam dan telur: nginx enggan bermula dengan ssl_certificate yang menghala ke fail yang tidak wujud, dan Certbot tidak dapat melakukan pengesahan semasa nginx tidak aktif. Hidupkan tapak pada port 80 terlebih dahulu.
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;
}
}Jalankan sudo nginx -t && sudo systemctl reload nginx, sahkan curl -I http://example.com/ memberi respons dari luar kotak, kemudian keluarkan sijil. Selepas itu:
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;
}
}Awalan ^~ pada lokasi ACME sangat berguna: ia menghalang blok return 301 daripada mengambil alih permintaan cabaran (challenge request). Mengekalkan lokasi tersebut pada port 80 bermakna pembaharuan akan terus berfungsi selepas seluruh tapak ditukar kepada HTTPS sahaja.
Kedua-dua blok di atas menghidangkan fail dari cakera; jika nginx sebaliknya menjadi hadapan kepada aplikasi, location / menjadi blok proxy_pass dan blok pelayan reverse proxy, baris demi baris merangkumi pengepala (headers) yang diperlukan oleh aplikasi tersebut, manakala lokasi ACME dan arahan TLS kekal seperti sedia ada.
Sintaks HTTP/2 bergantung pada versi nginx anda, dan mencampurkan kedua-dua bentuk tersebut akan menghasilkan ralat semasa permulaan. Ubuntu 24.04 membekalkan nginx 1.24, yang memerlukannya diletakkan sebaris, listen 443 ssl http2;. Debian 13 membekalkan nginx yang lebih baharu, yang memerlukan arahan http2 on; yang berasingan. Semak nginx -v terlebih dahulu.
Halakan nginx ke live/, jangan sekali-kali ke archive/. Pautan simbolik live/ akan dihalakan semula pada setiap pembaharuan; laluan tetap ke archive/ akan mengunci anda pada sijil yang akan tamat tempoh tanpa pengetahuan anda.
Wildcard bermaksud DNS-01, dan DNS-01 bermaksud pemalam
Sijil wildcard (*.example.com) tidak boleh disahkan melalui HTTP-01, kerana tiada satu hostname tunggal untuk mengambil fail. DNS-01 adalah satu-satunya laluan: anda membuktikan kawalan dengan menerbitkan rekod TXT _acme-challenge.example.com. Certbot memerlukan kelayakan API untuk penyedia DNS anda bagi melakukan perkara tersebut tanpa pengawasan, itulah sebabnya pemalam penyedia wujud. Panduan lengkap sijil wildcard merangkumi mekanik rekod TXT dan perangkap pembaharuan dalam mod manual; versi ringkas Cloudflare adalah seperti berikut.
sudo snap set certbot trust-plugin-with-root=ok
sudo snap install certbot-dns-cloudflarePada laluan apt, ia adalah sudo apt install python3-certbot-dns-cloudflare sebaliknya. Kelayakan diletakkan dalam fail yang hanya boleh diakses oleh root:
# /root/.secrets/cloudflare.ini
# then: sudo chmod 600 /root/.secrets/cloudflare.ini
dns_cloudflare_api_token = your_scoped_token_hereHadkan token kepada hak DNS-edit pada zon tersebut sahaja. Ia adalah kunci kepada DNS anda; kendalikannya seperti kunci.
sudo certbot certonly \
--dns-cloudflare \
--dns-cloudflare-credentials /root/.secrets/cloudflare.ini \
-d example.com -d '*.example.com'Gunakan tanda petikan untuk wildcard supaya shell anda tidak melakukan globbing terhadapnya. DNS-01 juga menyelesaikan perkara yang tidak boleh dilakukan oleh HTTP-01: sijil untuk hos yang tidak mempunyai port 80 awam, servis dalaman, kotak yang hanya boleh dicapai melalui VPN WireGuard yang dihoskan sendiri pada VPS, atau panel admin pada antara muka peribadi.
Pembaharuan: tempoh 90 hari, pemasa, dan deploy hook
Sijil Let’s Encrypt sah selama 90 hari. Certbot melakukan pembaharuan apabila tempoh yang tinggal kurang daripada 30 hari, memberikan anda ruang selama 30 hari di mana kegagalan pembaharuan hanyalah gangguan kecil yang boleh dibaiki dan bukannya gangguan perkhidmatan. Let’s Encrypt tidak lagi menghantar e-mel amaran tamat tempoh, tiada sesiapa yang akan mengingatkan anda, jadi pemantauan kini menjadi tanggungjawab anda.
Semak pemasa yang disertakan dalam pemasangan anda:
systemctl list-timers 'certbot*' 'snap.certbot*'
sudo certbot certificatescertbot renew menyemak setiap konfigurasi dalam /etc/letsencrypt/renewal/, melangkau mana-mana sijil yang berada di luar tempoh 30 hari, dan memperbaharui sijil selebihnya menggunakan tepat dengan flag yang digunakan semasa pelaksanaan asal. Itulah sebabnya pelaksanaan pertama sangat penting: ia adalah konfigurasi yang akan direkodkan.
Memperbaharui fail pada cakera tidak mengubah apa-apa dengan sendirinya, nginx akan terus menghidangkan sijil lama daripada memori sehingga ada sesuatu yang mengarahkannya untuk memuat semula (reload). Sediakan deploy hook sekali sahaja:
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.shApa-apa sahaja yang boleh dilaksanakan dalam renewal-hooks/deploy/ akan berjalan selepas setiap pembaharuan yang berjaya. Flag --deploy-hook melakukan tugas yang sama untuk satu sijil, menyimpan renew_hook = ... dalam konfigurasi pembaharuannya. certbot --nginx memuat semula untuk anda; persediaan --webroot dan --standalone tidak melakukannya secara automatik. Hook yang tiada adalah punca tepat mengapa sesebuah laman web menghidangkan sijil yang telah tamat tempoh walaupun certbot certificates melaporkan sijil baharu dengan gembira. Apa-apa perisian lain yang membaca sijil semasa permulaan memerlukan hook yang sama, aplikasi dalam kontena seperti pemasangan Nextcloud VPS dengan Docker, TLS dan sandaran memerlukan langkah restart atau reload sendiri yang ditetapkan di sini juga.
Menguji pembaharuan sebenar
sudo certbot renew --dry-runPerintah tersebut menjalankan cabaran penuh terhadap persekitaran staging Let's Encrypt: laluan kod yang sama, firewall yang sama, DNS yang sama, tiada kos had kadar (rate-limit), dan tiada data ditulis ke cakera. Jika ujian ini berjaya hari ini, pembaharuan automatik dalam tempoh 60 hari juga akan berjaya, dengan andaian tiada perubahan pada pelayan di bawahnya.
Ujian dry run tidak membuktikan bahawa reload hook anda berfungsi; kelakuan tersebut berbeza mengikut versi Certbot. Uji bahagian tersebut secara manual: jalankan skrip hook secara terus, sahkan systemctl reload nginx berjaya, dan semak sudo grep renew_hook /etc/letsencrypt/renewal/example.com.conf.
Ralat yang akan anda temui
Could not bind to IPv4 or IPv6., --standalone berlaku semasa nginx sudah menggunakan port 80. Gunakan --nginx atau --webroot, atau hentikan nginx semasa proses dijalankan. Sahkan pemegang port dengan sudo ss -lntp | grep ':80'.
Timeout during connect (likely firewall problem), Let's Encrypt tidak dapat mencapai port 80. Periksa dari luar: sudo ufw status (buka port dengan sudo ufw allow 'Nginx Full'), kemudian firewall penyedia VPS, dan seterusnya DNS. Uji dari lokasi selain pelayan anda: curl -sSv http://example.com/.well-known/acme-challenge/test. Rekod AAAA yang lapuk menghasilkan mesej yang sama.
unauthorized :: Invalid response from http://example.com/.well-known/acme-challenge/xyz: 404, port 80 boleh dicapai, tetapi token tidak dihidangkan. Permintaan sampai ke blok pelayan yang salah (semak blok mana yang memiliki default_server), atau direktori yang diberikan kepada -w bukan direktori yang dihidangkan oleh nginx. Letakkan fail di /var/www/example.com/.well-known/acme-challenge/test dan cuba akses dari luar; jika ralat 404 muncul, sijil bukanlah puncanya.
DNS problem: NXDOMAIN looking up A for example.com, nama tersebut tidak dapat diselesaikan secara awam. Ini berlaku jika rekod baharu belum disebarkan, atau rekod berada dalam zon yang tidak dihoskan oleh pendaftar domain anda.
too many certificates already issued for: example.com, had kadar (rate limit), ralat yang sering ditemui semasa menyahpepijat secara berulang. Let's Encrypt mengehadkan sijil pendua, iaitu set nama yang sama tepat, kepada lima setiap minggu, dan secara berasingan membenarkan 50 sijil baharu bagi setiap domain berdaftar setiap minggu; tiada cara untuk memintas had ini selain menunggu masa berlalu. Gunakan --dry-run untuk menyahpepijat menggunakan persekitaran staging.
nginx: [emerg] cannot load certificate "/etc/letsencrypt/live/example.com/fullchain.pem": No such file or directory, nginx dikonfigurasikan untuk sijil yang tidak pernah dikeluarkan, atau sijil yang telah dibuang dengan certbot delete. Komenkan blok pelayan TLS, mulakan nginx, keluarkan sijil, kemudian pulihkan blok tersebut.
open() "/etc/letsencrypt/options-ssl-nginx.conf" failed, fail tersebut disertakan bersama pakej pemalam nginx. Pada sistem certonly tanpa python3-certbot-nginx, sama ada tambah pemalam tersebut atau gantikan baris include dengan tetapan ssl_protocols dan ssl_ciphers anda sendiri.
Menguruskan ini pada skala besar
Satu sijil boleh membawa sehingga 100 nama, dan satu certbot --nginx -d a.example.com -d b.example.com ... memang menggoda, sehinggalah satu rekod DNS yang lapuk gagal dalam pengesahan dan menyebabkan semua nama lain pada sijil tersebut turut terjejas. Sijil berasingan bagi setiap tapak akan gagal secara bebas, yang merupakan keadaan ideal bagi pelayan yang menempatkan lebih daripada beberapa perkara. Apabila melebihi segelintir tapak, penggunaan front door yang peka-ACME adalah berbaloi: satu reverse proxy Traefik yang menjalankan berbilang aplikasi di bawah Docker Compose akan meminta dan memperbaharui sijil itu sendiri, dan Certbot tidak lagi diperlukan. Proxy mana yang sesuai di front door tersebut adalah keputusan anda sendiri, dan membandingkan Nginx dengan Caddy dan Traefik kebanyakannya bergantung kepada sejauh mana anda mahu proxy tersebut menguruskan kerja konfigurasi sijil dan setiap aplikasi bagi pihak anda.
Sandarkan /etc/letsencrypt secara keseluruhan, sudo tar -czf letsencrypt-$(date +%F).tar.gz -C /etc letsencrypt, dengan symlink dikekalkan. Pepohon direktori tersebut menyimpan accounts/, kunci akaun ACME anda, yang tidak boleh dijana semula secara identik. Berpindah ke VPS baharu kemudiannya menjadi mudah: rsync pepohon tersebut dengan -a, pasang Certbot, halakan semula DNS, dan jalankan certbot renew --dry-run sebelum anda melakukan pertukaran.
Bina semula pelayan atau beralih ke LTS baharu dan pemasa pembaharuan tidak akan mengikut anda. Selepas sebarang migrasi, pemulihan snapshot, atau naik taraf distro, jalankan systemctl list-timers 'certbot*' dan satu --dry-run. Mengabaikan langkah ini adalah punca tapak menjadi gelap 89 hari kemudian, pada pukul 3 pagi, dengan sijil yang semua orang sangka memperbaharui dirinya sendiri.
Semua ini mengandaikan mesin yang anda kawal, dengan IP awam dan port 80 terbuka kepada dunia, dalam erti kata lain, sebuah VPS. Mekanik di atas adalah identik pada mana-mana VPS tersebut.
Langkah sijil yang sama terpakai pada Apache dan bukannya nginx, dan apabila sijil awam bukan satu pilihan, sijil yang ditandatangani sendiri pada Ubuntu meliputi servis dalaman.
FAQ
Adakah saya perlu membuka port 80 jika tapak saya hanya menyediakan HTTPS?
Ya, untuk cabaran HTTP-01. Let's Encrypt sentiasa memulakan permintaan pengesahan pada port 80, dan Certbot tidak mempunyai implementasi TLS-ALPN-01. Oleh itu, firewall yang hanya membuka port 443 akan menyekat pengeluaran sijil pertama dan setiap pembaharuan automatik selepas itu. Redirect daripada port 80 ke HTTPS adalah dibenarkan kerana pengesahan akan mengikutinya. Satu-satunya cara untuk melangkau port 80 sepenuhnya adalah dengan menggunakan DNS-01 melalui plugin pembekal.
apt atau snap, yang mana satu Certbot perlu saya pasang untuk nginx pada Ubuntu 24.04?
Gunakan apt. sudo apt install certbot python3-certbot-nginx memberikan anda Certbot 2.9.0 pada Ubuntu 24.04, yang cukup terkini untuk semua perkara dalam panduan ini, menerima tampalan keselamatan melalui unattended-upgrades, dan tidak memerlukan snapd. Pilih snap hanya jika anda memerlukan keluaran terbaharu dengan segera atau plugin DNS yang diedarkan secara eksklusif sebagai snap. Walau apa pun, pilih satu sahaja: dua pemasangan bermakna dua pemasa pembaharuan yang menghala ke pokok /etc/letsencrypt yang sama, dan pemasangan yang terlupa itulah yang akan menyebabkan masalah kepada anda.
Bolehkah Certbot mengeluarkan sijil wildcard untuk nginx?
Hanya melalui DNS-01. Wildcard seperti *.example.com tidak mempunyai nama hos tunggal untuk mengambil fail cabaran, jadi --nginx, --webroot dan --standalone semuanya tidak boleh digunakan. Pasang plugin untuk pembekal DNS anda, letakkan token API bersekop dalam fail kelayakan yang hanya boleh diakses oleh root, dan jalankan certbot certonly --dns-cloudflare -d example.com -d '*.example.com', dengan meletakkan wildcard dalam tanda petikan untuk menghalang shell daripada melakukan globbing.
Mengapa nginx masih menyediakan sijil lama selepas pembaharuan berjaya?
nginx menyimpan sijil dalam memori dan tidak mengesan fail baharu pada cakera sehingga ia dimuatkan semula (reload). certbot --nginx melakukan muat semula untuk anda, tetapi --webroot dan --standalone tidak, jadi pembaharuan boleh berjaya sementara pelayar masih melihat sijil yang hampir tamat tempoh. Letakkan skrip boleh laksana ke dalam /etc/letsencrypt/renewal-hooks/deploy/ yang menjalankan nginx -t && systemctl reload nginx, dan ia akan berfungsi selepas setiap pembaharuan yang berjaya.
Adakah certbot renew --dry-run membuktikan pembaharuan akan berfungsi?
Kebanyakannya ya. Ia menjalankan cabaran sebenar terhadap persekitaran staging, menggunakan firewall yang sama, DNS yang sama, dan laluan kod yang sama, tanpa kos had kadar (rate-limit) dan tiada apa-apa yang ditulis ke cakera. Jadi, jika ia lulus, bermakna bahagian rangkaian adalah stabil. Walau bagaimanapun, ia tidak membuktikan secara mutlak bahawa deploy hook anda akan berfungsi. Uji perkara itu secara berasingan: jalankan skrip hook secara manual dan semak sudo grep renew_hook /etc/letsencrypt/renewal/example.com.conf.