Otomasi Pembaruan Sertifikat SSL dengan Certbot dan NGINX

Foto oleh Unsplash

Foto oleh Unsplash
Mengelola sertifikat SSL secara manual adalah salah satu tugas yang terasa mudah sampai sertifikat kedaluwarsa di produksi pukul 2 pagi hari Minggu. Let's Encrypt dan Certbot mengotomasi seluruh siklus hidup — penerbitan, validasi, instalasi, dan pembaruan — sehingga kedaluwarsa sertifikat SSL benar-benar tidak perlu lagi dikhawatirkan. Setelah menyiapkan ini di setiap DigitalOcean Droplet dan GCP Compute Engine instance yang kami kelola di Commsult Indonesia, saya tidak pernah memperbarui sertifikat secara manual selama lebih dari dua tahun. Panduan ini mencakup setup lengkap, konfigurasi NGINX untuk TLS yang kuat, dan pipeline pembaruan otomatis.
Let's Encrypt adalah Certificate Authority (CA) gratis yang menerbitkan sertifikat Domain Validation (DV) yang berlaku selama 90 hari. Masa berlaku singkat ini disengaja — memaksakan otomasi dan membatasi jendela kerusakan untuk sertifikat yang dikompromikan. Certbot adalah klien ACME resmi yang berkomunikasi dengan API Let's Encrypt. ACME (Automatic Certificate Management Environment) adalah protokol yang membuktikan Anda mengontrol domain sebelum CA menerbitkan sertifikat. Certbot mendukung dua jenis tantangan: HTTP-01 (membuat file sementara di /.well-known/acme-challenge/ di web server Anda) dan DNS-01 (membuat TXT record DNS sementara). HTTP-01 lebih sederhana dan berfungsi untuk sebagian besar setup.
Sertifikat Let's Encrypt berlaku 90 hari. Pendekatan pembaruan yang direkomendasikan Certbot adalah menjalankan `certbot renew` dua kali sehari (melalui systemd timer atau cron). Perintah ini memeriksa apakah sertifikat mana pun berada dalam 30 hari dari kedaluwarsa — jika tidak, ia tidak melakukan apa pun. Jika pembaruan diperlukan, perintah ini menjalankan ulang tantangan ACME, mendapatkan sertifikat baru, dan menjalankan deploy hook yang dikonfigurasi (seperti memuat ulang NGINX). Pendekatan ini berarti sertifikat biasanya diperbarui ketika tersisa 30 hari, memberi Anda buffer 30 hari bahkan jika proses pembaruan gagal selama beberapa hari.
Let's Encrypt memberlakukan batas rate untuk mencegah penyalahgunaan. Yang paling relevan untuk developer: 50 sertifikat per domain terdaftar per minggu, dan 5 percobaan validasi gagal per jam per akun per hostname. Batas ini penting selama setup awal saat Anda mungkin mengiterasi konfigurasi. Selalu gunakan flag `--dry-run` saat menguji perintah certbot — dry run menggunakan environment staging Let's Encrypt (batas rate terpisah) dan tidak menerbitkan sertifikat nyata. Hanya hapus `--dry-run` ketika Anda yakin konfigurasi sudah benar.
┌────────────────────────────────────────────────────────────────┐
│ Certbot Auto-Renewal Architecture │
│ │
│ systemd timer (twice daily) │
│ │ │
│ ▼ │
│ certbot renew │
│ │ │
│ ├── cert expiry > 30 days? → skip (no-op) │
│ │ │
│ └── cert expiry ≤ 30 days? │
│ │ │
│ ▼ │
│ ACME Challenge │
│ (HTTP-01 or DNS-01) │
│ │ │
│ ▼ │
│ Let's Encrypt CA ──► new cert issued │
│ │ │
│ ▼ │
│ Deploy hook: │
│ nginx -s reload │
│ │ │
│ ▼ │
│ cert valid for 90 days ✓ │
└────────────────────────────────────────────────────────────────┘Jika server Anda berada di belakang cloud firewall atau Droplet firewall DigitalOcean, pastikan port 80 (HTTP) terbuka selama tantangan HTTP-01 ACME. Plugin NGINX Certbot sementara melayani file tantangan di port 80. Setelah tantangan berhasil, Anda bisa membatasi port 80 hanya untuk redirect ke HTTPS. Certbot akan terus menangani pembaruan secara otomatis karena plugin NGINX mengelola eksposur port 80 sementara selama proses pembaruan.
Plugin NGINX untuk Certbot adalah pendekatan yang direkomendasikan — secara otomatis mengedit konfigurasi NGINX Anda untuk menambahkan path sertifikat, mengaktifkan HTTPS, dan menambahkan redirect HTTP ke HTTPS. Setelah menjalankan `certbot --nginx`, konfigurasi NGINX Anda akan memiliki direktif `ssl_certificate` dan `ssl_certificate_key` yang mengarah ke `/etc/letsencrypt/live/<domain>/`. Plugin juga menambahkan `include /etc/letsencrypt/options-ssl-nginx.conf` yang menyediakan konfigurasi cipher suite dan protokol default yang aman yang dikelola oleh Let's Encrypt.
Setelah Certbot memperbarui sertifikat, NGINX perlu memuat ulang untuk mengambil sertifikat baru. Tanpa deploy hook, sertifikat lama tetap dimuat di memori sampai NGINX dimulai ulang secara manual atau server reboot. Certbot menjalankan script di `/etc/letsencrypt/renewal-hooks/deploy/` setelah setiap pembaruan berhasil. Buat script yang menjalankan `nginx -t && systemctl reload nginx` — tes konfigurasi memastikan konfigurasi NGINX yang rusak tidak mematikan server Anda selama pembaruan otomatis.
# 1. Install Certbot with NGINX plugin (Ubuntu 22.04)
sudo apt update
sudo apt install -y certbot python3-certbot-nginx
# 2. Obtain and auto-configure NGINX certificate
sudo certbot --nginx -d example.com -d www.example.com --email your@email.com --agree-tos --no-eff-email --redirect
# 3. Verify auto-renewal timer is active
sudo systemctl status certbot.timer
# ● certbot.timer - Run certbot twice daily
# Active: active (waiting)
# 4. Dry run to confirm renewal works
sudo certbot renew --dry-run
# 5. Add a deploy hook to reload NGINX after renewal
sudo mkdir -p /etc/letsencrypt/renewal-hooks/deploy
cat > /etc/letsencrypt/renewal-hooks/deploy/reload-nginx.sh <<'EOF'
#!/bin/bash
nginx -t && systemctl reload nginx
echo "NGINX reloaded after cert renewal at $(date)" >> /var/log/certbot-deploy.log
EOF
sudo chmod +x /etc/letsencrypt/renewal-hooks/deploy/reload-nginx.sh
# 6. Harden NGINX TLS config (add to server block)
# ssl_protocols TLSv1.2 TLSv1.3;
# ssl_ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384;
# ssl_prefer_server_ciphers off;
# ssl_session_cache shared:SSL:10m;
# ssl_session_timeout 1d;
# add_header Strict-Transport-Security "max-age=63072000" always;
# 7. Check certificate expiry manually
sudo certbot certificatesKonfigurasi NGINX default Certbot aman tetapi tidak optimal untuk rating A+ di SSL Labs. Untuk mencapai skor keamanan maksimum: nonaktifkan TLS 1.0 dan 1.1 (pertahankan hanya TLSv1.2 dan TLSv1.3), konfigurasi cipher suite yang kuat yang memprioritaskan ECDHE dengan forward secrecy, aktifkan HSTS dengan max-age 2 tahun dan includeSubDomains, tambahkan OCSP stapling untuk mengurangi latensi pada TLS handshake, dan konfigurasi file parameter Diffie-Hellman (minimum 2048-bit, 4096-bit lebih disukai). Buat file DH params dengan `openssl dhparam -out /etc/nginx/dhparam.pem 2048` — ini membutuhkan 1-2 menit di VPS tipikal.
Kesalahan paling umum saat menyiapkan Certbot adalah menjalankan perintah `certbot certonly` atau `certbot --nginx` awal ketika port 80 diblokir. Tantangan HTTP-01 gagal secara diam-diam dari perspektif pengguna — Anda mendapat hit batas rate dan harus menunggu satu jam sebelum mencoba lagi. Periksa bahwa `curl http://domain-anda.com/.well-known/acme-challenge/test` mengembalikan sesuatu (bahkan 404 dari NGINX) sebelum menjalankan Certbot. Juga, jangan pernah menghapus `/etc/letsencrypt/` — direktori ini berisi kunci akun dan konfigurasi pembaruan sertifikat. Backup ke DigitalOcean Spaces atau GCP Cloud Storage.
Untuk lingkungan dengan beberapa subdomain (api.example.com, app.example.com, admin.example.com), wildcard certificate (`*.example.com`) lebih efisien daripada sertifikat individual per subdomain. Wildcard certificate membutuhkan tantangan DNS-01, yang membuktikan kepemilikan domain dengan membuat DNS TXT record daripada menyajikan file melalui HTTP. Untuk DNS DigitalOcean, install plugin `python3-certbot-dns-digitalocean` dan buat file kredensial dengan API token DigitalOcean Anda. Tantangan dan pembaruan kemudian sepenuhnya otomatis tanpa akses HTTP yang diperlukan.
Bahkan dengan pembaruan otomatis, Anda harus memonitor kedaluwarsa sertifikat sebagai jaring pengaman. Tambahkan probe Prometheus Blackbox Exporter yang memeriksa kedaluwarsa sertifikat TLS untuk setiap domain dan alert ketika kedaluwarsa kurang dari 21 hari. Alternatifnya, Let's Encrypt mengirim email pengingat kedaluwarsa ke alamat yang terdaftar dengan Certbot. Untuk pendekatan belt-and-suspenders, gunakan layanan seperti certificate.transparency.dev atau monitor uptime dengan pemeriksaan kedaluwarsa TLS (UptimeRobot tier gratis menyertakan fitur ini) sebagai saluran notifikasi sekunder di luar monitoring stack Anda.