Sertifikat SSL Situsku Kadaluarsa Diam-Diam, dan Aku Baru Tahu dari Screenshot Pelanggan

Jumat malam, jam sembilan lewat, masuk email dari salah satu pelanggan berbayarku: satu baris kalimat, "situsnya kenapa ya, browser saya nolak buka," dengan lampiran tangkapan layar. Aku buka lampirannya sambil masih di meja makan, dan yang muncul adalah halaman peringatan merah khas Chrome — "Koneksi Anda tidak privat" — dengan detail di bawahnya yang langsung bikin perutku mules: sertifikat sudah kadaluarsa sejak dua hari lalu.

Seseorang memegang smartphone
Seseorang memegang smartphone

Automasi yang Kupercaya Begitu Saja

Setup-nya sebenarnya sudah kupasang lebih dari setahun lalu dan tidak pernah kusentuh lagi sejak itu: certbot jalan lewat cron setiap tengah malam, mencoba renew sertifikat Let's Encrypt kalau usianya sudah lewat 60 hari dari total masa berlaku 90 hari, pakai metode DNS-01 challenge lewat API penyedia DNS tempat domainku terdaftar. Selama setahun itu prosesnya selalu mulus — token API dibuat sekali di awal, dimasukkan ke file konfigurasi, dan certbot beres-beres sendiri tanpa pernah butuh campur tangan manual. Karena selalu jalan tanpa masalah, aku berhenti memikirkannya sama sekali. Tidak ada yang kucek berkala, tidak ada pengingat kalender, tidak ada yang membaca log cron itu selain sistemnya sendiri.

Justru di situ masalahnya lahir: sesuatu yang "selalu berhasil" pelan-pelan berubah jadi sesuatu yang "pasti berhasil" di kepalaku, padahal dua hal itu tidak sama.

Yang Sebenarnya Terjadi di Balik Layar

Sekitar enam minggu sebelum malam itu, penyedia DNS-ku mengirim email soal migrasi sistem otentikasi API mereka — token lama akan tetap berfungsi untuk permintaan baca, tapi permintaan tulis (yang dibutuhkan certbot untuk membuat record TXT verifikasi) butuh token baru dengan skema scope yang berbeda. Aku ingat sempat membaca judul emailnya, menganggapnya bacaan teknis rutin dari penyedia layanan yang memang sering kirim pengumuman semacam itu, dan mengarsipkannya tanpa membuka detailnya.

Renewal pertama setelah migrasi itu gagal, karena token lama tidak lagi punya izin membuat record baru. Tapi gagalnya diam-diam: script wrapper yang memanggil certbot dari cron ditulis dengan pola certbot renew ... || true, sisa kebiasaan lama supaya cron tidak mengirim email error setiap kali certbot memutuskan belum waktunya renew (perilaku normal certbot kalau sertifikat masih jauh dari kadaluarsa). Pola yang tadinya untuk meredam noise itu justru menelan exit code kegagalan sungguhan, dan log-nya cuma tersimpan di file lokal yang tidak pernah kubuka lagi. Karena masa berlaku sertifikat masih 90 hari, butuh berminggu-minggu sebelum tanggal kadaluarsa itu benar-benar tiba dan berubah jadi masalah yang terlihat dari luar.

Kenapa Monitoring-ku Sendiri Tidak Menangkapnya

Yang paling bikin malu justru bukan renewal yang gagal — itu bisa terjadi ke siapa saja saat penyedia pihak ketiga mengubah sesuatu tanpa pemberitahuan yang cukup jelas. Yang bikin malu adalah aku sudah punya layanan uptime monitoring terpasang di situs ini, mengecek endpoint utama setiap lima menit, dan selama itu status-nya selalu hijau. Ternyata konfigurasi monitoring-nya cuma mengecek apakah request HTTP berhasil dan mengembalikan status 200 — dan banyak library HTTP client, termasuk yang dipakai layanan monitoring itu, punya opsi verifikasi sertifikat yang longgar atau bahkan mengizinkan koneksi tetap jalan meski sertifikatnya sudah tidak valid, sepanjang server di baliknya tetap merespons.

Dengan kata lain, aku memantau proxy dari hal yang sebenarnya kupedulikan — "apakah situs bisa diakses" — bukan hal itu sendiri, yaitu "apakah pengunjung normal di browser biasa bisa mengaksesnya tanpa peringatan." Dua hal itu biasanya berkorelasi kuat, sampai satu hari mereka berpisah jalan, dan monitoring-ku tidak dirancang untuk menangkap perpisahan itu.

Baris-baris kode HTML di layar
Baris-baris kode HTML di layar

Yang Kuubah Malam Itu Juga

Perbaikan mendesaknya cepat: generate token API baru sesuai skema yang diminta penyedia DNS, jalankan certbot renew manual, sertifikat baru terbit dalam hitungan menit, situs normal lagi sebelum tengah malam. Tapi perbaikan yang menurutku lebih penting justru dua hal lain yang kukerjakan besoknya. Pertama, membuang pola || true dari wrapper cron dan menggantinya dengan pengecekan exit code eksplisit — kalau certbot gagal karena alasan selain "belum waktunya," script sekarang mengirim notifikasi ke telepon lewat webhook sederhana, bukan menelan errornya diam-diam. Kedua, menambah pemeriksaan terpisah yang khusus mengecek tanggal kadaluarsa sertifikat lewat openssl setiap hari dan memberi peringatan kalau sisa masa berlakunya di bawah 20 hari — bukan cuma mengandalkan renewal berhasil, tapi memverifikasi hasil akhirnya secara independen dari proses yang menghasilkannya.

Satu kebiasaan kecil yang juga kutambahkan: setiap kali penyedia layanan pihak ketiga mengirim email soal "migrasi" atau "perubahan otentikasi API," sekarang aku benar-benar buka dan baca isinya sampai habis, bukan cuma judulnya, terutama kalau layanan itu dipakai oleh sesuatu yang jalan otomatis tanpa pengawasan manual.

Takeaway

Automasi yang sudah lama berjalan mulus punya cara halus untuk membuat kita berhenti mengawasinya, dan justru di situ risikonya paling besar — bukan saat baru dipasang dan masih dicurigai, tapi setelah bertahun-tahun dipercaya begitu saja. Kalau ada satu perubahan yang paling berharga dari kejadian ini, itu bukan sekadar "jangan pakai || true," tapi kebiasaan memverifikasi hasil akhir yang sebenarnya kupedulikan secara langsung, bukan lewat proxy yang kebetulan biasanya berkorelasi dengannya. Monitoring yang mengecek "server merespons" tidak sama dengan monitoring yang mengecek "hal yang membuat server itu berguna bagi pengunjung" — dan bedanya baru terasa persis di saat yang paling tidak diinginkan.

Sumber gambar: Glenn Carstens-Peters di Unsplash Sumber gambar: Rodion Kutsaiev di Unsplash Sumber gambar: Florian Olivo di Unsplash

The conversation 0

No comments yet. Start the conversation.

Comments are reviewed before appearing. Links are masked.