SERVFAIL. Anehnya, domain yang sama resolve normal dari laptop atau dari server lain. Kalau resolver di VM itu melakukan validasi DNSSEC, misalnya Unbound, BIND, atau systemd-resolved dengan DNSSEC aktif, penyebab yang sering terlewat ada di jam sistem guest yang ikut mundur ke waktu snapshot. Record DNS-nya sendiri tidak bermasalah.
Artikel ini fokus ke cara membuktikannya lewat CLI, langkah demi langkah, sebelum dan sesudah jam diperbaiki.
Kenapa jam yang meleset bikin validasi DNSSEC gagal
SERVFAIL.
Karena banyak zona ditandatangani ulang secara berkala, makin jauh jam mundur, makin banyak domain yang ikut gagal. Itu sebabnya gejalanya terlihat seperti "DNS mati total" padahal yang salah cuma satu angka di guest.
Kapan jam guest ikut mundur setelah rollback
- chrony biasanya hanya melakukan step (lompat langsung ke jam yang benar) di awal service berjalan, sesuai directive
makestepdi konfigurasinya. Setelah itu ia melakukan slew, yaitu mempercepat atau memperlambat jam sedikit demi sedikit. Karena VM di-resume dan bukan di-boot, chrony menganggap dirinya sudah lama berjalan. Selisih besar lalu dikejar dengan slew yang bisa memakan waktu sangat lama. - Server NTP biasanya ditulis sebagai hostname. Untuk menghubunginya, guest harus resolve hostname itu lewat resolver lokal, padahal resolver lokal sedang menolak semua jawaban karena jamnya salah. Hasilnya buntu: jam tidak bisa diperbaiki karena DNS gagal, dan DNS gagal karena jam salah.
Langkah verifikasi: bandingkan jam, lalu bandingkan dengan RRSIG
BASH
# Di host Proxmox: jam host sebagai pembanding
date -u
# Di dalam guest: jam guest dan status sinkronisasi
date -u
timedatectl
# Query biasa ke resolver lokal (validasi aktif)
dig @127.0.0.1 example.com A
# Query yang sama dengan Checking Disabled (+cd): resolver tidak memvalidasi
dig @127.0.0.1 example.com A +cd
# Tampilkan RRSIG untuk melihat inception dan expiration
dig @127.0.0.1 example.com A +dnssec +cd +multilineexample.com dengan domain yang sedang gagal. Kalau query biasa membalas status: SERVFAIL tetapi query dengan +cd membalas status: NOERROR lengkap dengan jawaban, berarti resolver bisa menjangkau authoritative server dan menerima datanya, lalu menolaknya saat validasi. Konektivitas dan record-nya aman, masalahnya ada di validasi.
Opsi +cd di sini dipakai sebagai alat diagnosis saja. Jangan jadikan solusi dengan mematikan validasi, karena itu menghilangkan perlindungan terhadap cache poisoning dan spoofing.
Output +dnssec akan menampilkan baris RRSIG. Formatnya kurang lebih seperti ini (contoh format output, nilainya ilustratif):
TEXT
example.com. 300 IN RRSIG A 13 2 300 (
20261115000000 20261025000000 12345 example.com.
...signature... )YYYYMMDDHHmmSS dalam UTC. Pada contoh di atas, signature berlaku dari 25 Oktober 2026 sampai 15 November 2026. Bandingkan dengan hasil date -u di guest. Kalau jam guest lebih awal dari inception, atau lebih lambat dari expiration, kamu sudah menemukan penyebabnya. Jam host dipakai sebagai acuan bahwa yang benar memang host, bukan guest.
Urutan expiration lalu inception ini sering terbalik dibaca, jadi pastikan lagi sebelum menarik kesimpulan.
Membaca log resolver
journalctl -u unbound atau journalctl -u named (di Debian dan Ubuntu kadang bind9) adalah tempat pertama untuk dilihat.
Unbound secara default cukup pendiam soal alasan validasi gagal. Directive val-log-level: 2 di unbound.conf membuatnya mencatat alasan per query yang gagal, misalnya pesan seperti signature before inception date atau signature expired. BIND biasanya mencatat sesuatu seperti signature is in the future atau signature has expired. Teks persisnya bisa berbeda antarversi, jadi cari kata kunci inception, expired, atau future.
Untuk systemd-resolved, resolvectl query example.com biasanya menampilkan alasan kegagalan DNSSEC langsung di output-nya.
Kalau log menyebut signature belum berlaku, jam guest kemungkinan mundur. Kalau menyebut expired padahal domain itu valid dari luar, jam guest kemungkinan terlalu maju. Kalau keduanya tidak muncul dan yang terlihat justru masalah DS atau DNSKEY, berarti penyebabnya lain. Itu topik berbeda, misalnya seperti yang dibahas di artikel tentang RRSIG yang benar-benar kedaluwarsa setelah zona dipindah ke BIND.
Memperbaiki jam dan memastikan NTP benar-benar jalan
BASH
# Jika guest memakai chrony: lihat offset, lalu paksa step sekali
chronyc tracking
chronyc sources -v
sudo chronyc makestep
# Jika guest memakai systemd-timesyncd
timedatectl timesync-status
sudo systemctl restart systemd-timesyncd
# Setelah jam benar: buang cache jawaban bogus
sudo unbound-control flush_bogus # Unbound
sudo rndc flush # BIND
# Ulangi query tanpa +cd, harus kembali NOERROR
dig @127.0.0.1 example.com ASystem time di chronyc tracking, yang menunjukkan seberapa jauh jam sistem dari jam referensi. Kalau chronyc sources kosong atau semua source tidak terjangkau, kemungkinan besar kamu sedang kena masalah buntu tadi: hostname server NTP tidak bisa di-resolve. Jalan keluarnya, sementara arahkan guest ke resolver lain yang tidak bergantung pada jam guest. Bisa juga menyetel jam secara manual mendekati jam host lewat timedatectl set-time, tapi perintah ini hanya bisa dipakai kalau NTP dinonaktifkan dulu. Setelah itu biarkan NTP mengambil alih lagi.
Pembersihan cache perlu dilakukan karena resolver bisa menyimpan hasil validasi gagal untuk sementara waktu. Tanpa flush, query tetap SERVFAIL beberapa saat meskipun jam sudah benar, dan ini sering bikin orang mengira perbaikannya tidak berhasil. Perintah unbound-control hanya bekerja kalau remote-control Unbound aktif. Kalau tidak, restart service resolver juga mengosongkan cache.
Terakhir, pastikan sinkronisasi memang aktif dan bukan cuma kebetulan benar. Di output timedatectl, baris System clock synchronized harus yes dan NTP service harus active. Untuk chrony, cek apakah konfigurasinya punya directive makestep dan bagaimana batasnya. Isi default-nya berbeda per distro, dan itu menentukan apakah selisih besar setelah resume akan di-step atau hanya di-slew pelan-pelan.
Jadi, kalau VM habis di-rollback lalu DNS di dalamnya mendadak SERVFAIL, mulai dari dua perintah paling murah: date -u di host dan guest, lalu dig dengan dan tanpa +cd. Kalau +cd berhasil dan jam guest berada di luar rentang inception sampai expiration di RRSIG, perbaiki jamnya, flush cache bogus, dan pastikan NTP benar-benar tersinkron. Untuk ke depannya, biasakan cek jam setiap kali melakukan rollback snapshot yang menyertakan RAM.