
Pertengahan 2026 lalu, klien freelance gue minta satu hal yang kedengarannya sederhana: “domain internal perusahaan kami harus bisa resolve ke server lokal tanpa bergantung ke DNS publik.” Waktu itu gue baru saja migrasi ke Ubuntu 26.04 dan belum pernah sentuh BIND9 sama sekali. Dua jam kemudian, gue sudah terjebak di labirin config file yang saling include satu sama lain, dan syslog penuh dengan pesan error yang terasa seperti server sedang memaki gue secara personal.
Dari situlah perjalanan panjang gue dengan BIND9 dimulai. Artikel ini gue tulis bukan untuk menggurui, tapi untuk memangkas jalur berliku yang gue lewati supaya kamu tidak perlu menghabiskan dua malam seperti gue hanya untuk membuat satu zone file jalan.
Apa Itu BIND9 dan Kenapa Kamu Perlu Ini?
BIND9 (Berkeley Internet Name Domain) adalah software DNS server paling banyak dipakai di dunia, bahkan sebagian besar resolver publik di internet menggunakannya di balik layar.
Anggap BIND9 seperti petugas sensus di kompleks perumahan besar. Setiap rumah punya nama (domain), dan dia yang pegang buku catatan lengkap tentang siapa tinggal di alamat nomor berapa (IP address). Tanpa dia, kamu harus hafal nomor rumah semua tetangga. Tidak ada yang mau melakukan itu.
Skenario nyata yang membuat BIND9 relevan: Bayangkan kamu deploy aplikasi Express.js di jaringan kantor dan mau semua komputer bisa akses lewat api.internal.company.com alih-alih mengetik IP 192.168.10.45 setiap saat. Di sinilah cara setup BIND9 DNS Server di Ubuntu masuk dan langsung terasa manfaatnya.
Apa Itu Ubuntu dan Kenapa Gue Pilih Ini?
Ubuntu bukan sekadar “Linux yang ramah pemula.” Kalau Linux adalah mesin diesel yang ganas tapi tidak punya kursi nyaman, Ubuntu adalah mesin yang sama tapi sudah dilengkapi dashboard, AC, dan petunjuk arah yang bisa dibaca manusia normal.
Gue pertama kali install Ubuntu 26.04 waktu mengerjakan sebuah freelance project di awal 2026. Sebelumnya gue pakai Debian murni untuk server, dan perbedaan performa yang gue rasakan cukup mengejutkan karena Ubuntu 26.04 jauh lebih optimal dalam hal kernel scheduling dan manajemen memori untuk workload modern.
Soal alternatif: Debian lebih minimal dan stabil untuk server long-term, Rocky Linux cocok untuk environment enterprise yang butuh kompatibilitas RHEL, tapi untuk developer yang baru mulai dan butuh dokumentasi melimpah beserta komunitas aktif, Ubuntu masih pilihan paling masuk akal. Ini bukan fanboy-ism, ini pragmatisme.
Prasyarat Sebelum Mulai
Sebelum gue kasih perintah pertama, pastikan dulu hal-hal ini ada:
- Server Ubuntu (22.04, 24.04, atau 26.04) dengan akses root atau sudo
- IP server statis, misal
192.168.10.10 - Domain internal yang mau dikelola, misal
internal.dev - Koneksi internet untuk download package
Langkah 1: Update Sistem dan Install BIND9
Selalu mulai dari update. Ini bukan formalitas. Package yang sudah outdated bisa menyebabkan dependency conflict yang susah di-debug, dan gue sudah pernah merasakan sendiri betapa menyakitkannya itu.
# Update list package dan upgrade sistem
sudo apt update && sudo apt upgrade -y
Perintah ini melakukan dua hal: menyinkronkan index repository lokal dengan server upstream (apt update), lalu menginstall versi terbaru semua package yang sudah terinstall (apt upgrade). Kenapa keduanya sekaligus? Karena BIND9 kadang butuh versi library tertentu yang baru tersedia setelah upgrade.
# Install BIND9, utilities, dan dokumentasi
sudo apt install bind9 bind9utils bind9-doc -y
bind9utils berisi tool seperti named-checkconf dan named-checkzone yang akan jadi sahabat terbaik kamu untuk validasi config sebelum restart service. bind9-doc sering dilupakan orang, tapi dokumentasi offline itu penyelamat waktu koneksi internet lagi lambat.
💡 Tips dari Pengalaman: Setelah install, langsung cek versi untuk konfirmasi instalasi berhasil:
named -v
Langkah 2: Pahami Struktur File Konfigurasi BIND9
Sebelum mengedit apapun, kenali dulu medan perangnya.
/etc/bind/
├── named.conf # File induk, include semua file di bawah
├── named.conf.options # Pengaturan global server (forwarder, ACL, dsb.)
├── named.conf.local # Definisi zone yang kamu kelola sendiri
├── named.conf.default-zones # Zone default (root, localhost, dsb.)
└── db.internal.dev # File zone yang kamu buat sendiri (nanti)
named.conf adalah pintu masuk utama. Dia tidak berisi banyak konfigurasi langsung, cukup baris include yang memanggil file lain. Memahami struktur ini adalah fondasi dari membangun BIND9 DNS Server di Ubuntu yang rapi dan mudah dimaintain.
Langkah 3: Konfigurasi named.conf.options
File ini mengatur perilaku global DNS server, termasuk siapa yang boleh query, ke mana forward kalau tidak tahu jawaban, dan berapa besar cache.
# Backup dulu sebelum edit, ini kebiasaan yang gue terapkan sejak lama
sudo cp /etc/bind/named.conf.options /etc/bind/named.conf.options.bak
sudo nano /etc/bind/named.conf.options
Hapus isi default dan ganti dengan konfigurasi berikut:
# Konfigurasi named.conf.options untuk jaringan internal
acl "trusted" {
192.168.10.0/24; # Subnet jaringan lokal kamu
localhost;
localnets;
};
options {
directory "/var/cache/bind";
# Hanya ijinkan query dari network yang trusted
allow-query { trusted; };
# Aktifkan rekursi untuk client internal
recursion yes;
allow-recursion { trusted; };
# Forwarder: kalau BIND9 tidak tahu jawabannya, tanya ke sini dulu
forwarders {
8.8.8.8; # Google DNS
1.1.1.1; # Cloudflare DNS
};
forward first;
# Sembunyikan versi BIND dari luar (security dasar)
version "DNS Server";
# DNSSEC untuk validasi response
dnssec-validation auto;
listen-on-v6 { none; }; # Matikan IPv6 kalau tidak dipakai
};
Kenapa ada ACL trusted? Tanpa ACL, server kamu bisa dijadikan amplifier serangan DNS DDoS. Siapapun di internet bisa kirim query kecil ke server kamu, dan server kamu balas dengan response besar ke target korban. Ini namanya DNS amplification attack, dan sudah banyak admin yang tidak tahu dijadikannya botnet.
⚠️ Perhatian: Ganti
192.168.10.0/24dengan subnet jaringan lokal kamu yang sebenarnya. Kalau salah mengisi range ini, client di jaringan kamu tidak bisa query sama sekali.
Langkah 4: Buat Zone di named.conf.local
Zone adalah “wilayah kekuasaan” BIND9. Kalau kamu deklarasikan zone internal.dev, artinya server kamu yang punya otoritas penuh untuk semua record di domain tersebut.
sudo nano /etc/bind/named.conf.local
# Forward zone: dari nama domain ke IP
zone "internal.dev" IN {
type primary;
file "/etc/bind/db.internal.dev";
allow-update { none; };
};
# Reverse zone: dari IP ke nama domain (untuk PTR record)
zone "10.168.192.in-addr.arpa" IN {
type primary;
file "/etc/bind/db.192.168.10";
allow-update { none; };
};
Kenapa butuh reverse zone? Banyak aplikasi enterprise dan tool monitoring melakukan reverse DNS lookup untuk memverifikasi identitas server. Tanpa reverse zone, kamu akan dapat banyak warning log yang membingungkan dan beberapa layanan mail server bisa tolak koneksi dari server kamu.
💡 Tips dari Pengalaman: Format penulisan reverse zone itu dibalik. Untuk subnet
192.168.10.0/24, reverse zone-nya ditulis10.168.192.in-addr.arpa. Gue pernah salah tulis ini dan menghabiskan satu jam debug sebelum sadar kesalahannya ada di sini.
Langkah 5: Buat File Zone
Sekarang waktunya membuat isi dari zone itu sendiri.
# Buat forward zone file
sudo nano /etc/bind/db.internal.dev
; Forward zone file untuk internal.dev
; Titik koma (;) adalah karakter komentar di zone file
$TTL 604800 ; Default TTL: 7 hari (dalam detik)
@ IN SOA ns1.internal.dev. admin.internal.dev. (
2026042801 ; Serial (format: YYYYMMDDNN — WAJIB update tiap edit)
3600 ; Refresh: seberapa sering secondary DNS cek update
1800 ; Retry: interval retry kalau refresh gagal
604800 ; Expire: berapa lama secondary masih valid tanpa kontak primary
86400 ) ; Negative TTL: berapa lama cache "tidak ada record" disimpan
; Name server
@ IN NS ns1.internal.dev.
; A Records
ns1 IN A 192.168.10.10
api IN A 192.168.10.20
db IN A 192.168.10.30
web IN A 192.168.10.40
; CNAME
www IN CNAME web.internal.dev.
# Buat reverse zone file
sudo nano /etc/bind/db.192.168.10
; Reverse zone file untuk subnet 192.168.10.0/24
$TTL 604800
@ IN SOA ns1.internal.dev. admin.internal.dev. (
2026042801
3600
1800
604800
86400 )
@ IN NS ns1.internal.dev.
; PTR Records (hanya oktet terakhir dari IP)
10 IN PTR ns1.internal.dev.
20 IN PTR api.internal.dev.
30 IN PTR db.internal.dev.
40 IN PTR web.internal.dev.
⚠️ Perhatian: Nomor serial di SOA record harus diincrement setiap kali kamu edit zone file. BIND9 dan secondary DNS server menggunakan nomor ini untuk mendeteksi perubahan. Kalau serial tidak naik, update zone kamu tidak akan propagasi. Waktu itu gue panik karena perubahan record tidak muncul setelah restart, dan ternyata penyebabnya cuma serial yang lupa di-update.
Langkah 6: Validasi Config dan Jalankan BIND9
Jangan pernah restart BIND9 tanpa validasi dulu. Kalau config ada syntax error dan service crash, kamu baru tahu kesalahannya setelah semua client kehilangan DNS resolution.
# Validasi syntax named.conf secara keseluruhan
sudo named-checkconf
# Validasi zone file forward
sudo named-checkzone internal.dev /etc/bind/db.internal.dev
# Validasi zone file reverse
sudo named-checkzone 10.168.192.in-addr.arpa /etc/bind/db.192.168.10
Kalau output named-checkzone menampilkan OK, berarti aman untuk lanjut.
# Start dan enable BIND9 agar auto-start saat boot
sudo systemctl start named
sudo systemctl enable named
# Cek status service
sudo systemctl status named
Bagaimana Cara Verifikasi BIND9 Sudah Berjalan dengan Benar?
Cara paling dasar adalah cek status service, tapi itu hanya bilang “service running”, bukan “DNS resolution benar-benar jalan.”
# Tes query DNS dasar
dig @192.168.10.10 api.internal.dev
# Tes reverse lookup (yang sering dilupakan tutorial lain)
dig @192.168.10.10 -x 192.168.10.20
# Tes dari sudut pandang client
nslookup api.internal.dev 192.168.10.10
Output dig yang benar akan menampilkan section ANSWER SECTION dengan IP yang sesuai zone file. Kalau muncul SERVFAIL atau NXDOMAIN, ada masalah di zone file atau konfigurasi.
💡 Tips dari Pengalaman: Cek juga bahwa BIND9 tidak menjawab query dari IP di luar subnet trusted:
# Harusnya ditolak kalau IP source kamu bukan di trusted ACL dig @IP_SERVER_KAMU google.comKalau ini berhasil dari IP luar trusted, konfigurasi ACL kamu ada yang salah.
Troubleshooting: 4 Masalah Nyata yang Pernah Gue Hadapi
1. Service Gagal Start: “named.conf:X: unknown option”
Gejala: systemctl status named menampilkan Active: failed dan di log ada pesan named.conf:12: unknown option 'X'.
Root cause: Syntax error di salah satu config file, biasanya tanda kurung kurawal yang tidak tertutup atau typo di nama directive.
Solusi:
sudo named-checkconf
# Perhatikan nomor baris yang disebutkan di output error
sudo journalctl -xe -u named | tail -30
Tip pencegahan: Jalankan named-checkconf sebelum setiap restart. Jadikan itu reflek.
2. Query Berhasil tapi Record Lama Masih Muncul
Gejala: Kamu sudah edit zone file dan restart BIND9, tapi dig masih kembalikan IP yang lama.
Root cause: DNS caching. Resolver di sisi client (atau BIND9 itu sendiri) masih menyimpan jawaban lama berdasarkan nilai TTL sebelumnya.
Solusi:
# Flush cache BIND9
sudo rndc flush
# Cek langsung ke server tanpa cache
dig +nocache @192.168.10.10 api.internal.dev
Tip pencegahan: Selama fase development dan testing, set TTL ke nilai rendah (misal 300 detik) supaya perubahan cepat propagasi.
3. Reverse Lookup Tidak Bekerja
Gejala: Forward query berjalan, tapi dig -x hanya mengembalikan NXDOMAIN.
Root cause: Reverse zone tidak terdaftar di named.conf.local atau PTR record ditulis dengan format yang salah.
Solusi:
# Pastikan reverse zone terdaftar
grep -A5 "in-addr.arpa" /etc/bind/named.conf.local
# Validasi zone file reverse
sudo named-checkzone 10.168.192.in-addr.arpa /etc/bind/db.192.168.10
4. Serial SOA Lebih Kecil dari Sebelumnya (Kesalahan yang Jarang Dibahas)
Gejala: Kamu edit zone file dan update record, tapi secondary DNS server tidak mengambil perubahan. Log di secondary menampilkan zone refresh: up to date.
Root cause: Kamu tidak sengaja memasukkan nomor serial yang lebih kecil dari serial sebelumnya (misalnya copy-paste dari template lama). BIND menggunakan serial number arithmetic, dan kalau serial baru lebih kecil, dianggap tidak ada update baru.
Solusi:
# Cek serial yang sedang aktif
dig @localhost SOA internal.dev
# Edit zone file, naikan serial lebih tinggi dari nilai yang terbaca
sudo nano /etc/bind/db.internal.dev
# Reload zone tanpa restart service penuh
sudo rndc reload internal.dev
Tip pencegahan: Gunakan format serial YYYYMMDDNN (tahun-bulan-hari-nomor urut). Format ini memastikan serial selalu naik selama kamu tidak mundur waktu ke masa lalu.
Perintah BIND9 Sehari-hari
| Perintah | Fungsi | Kapan Dipakai |
|---|---|---|
sudo systemctl restart named |
Restart service BIND9 | Setelah edit named.conf.options atau named.conf.local |
sudo rndc reload |
Reload semua zone tanpa restart | Setelah edit zone file, tanpa downtime |
sudo rndc reload internal.dev |
Reload satu zone spesifik | Kalau hanya satu zone yang berubah, lebih cepat |
sudo rndc flush |
Flush seluruh cache DNS | Setelah update record dan mau lihat hasil langsung |
sudo named-checkconf |
Validasi syntax config | Sebelum setiap restart atau reload |
sudo named-checkzone ZONE FILE |
Validasi zone file | Setelah edit zone file, sebelum reload |
dig @SERVER DOMAIN |
Query DNS langsung ke server | Debugging apakah record sudah benar |
sudo journalctl -u named -f |
Live log BIND9 | Monitoring real-time saat troubleshooting |
FAQ Singkat
Apakah BIND9 bisa dipakai sebagai DNS resolver publik?
Bisa secara teknis, tapi tidak disarankan tanpa konfigurasi rate-limiting dan keamanan tambahan yang serius. Untuk penggunaan internal jaringan lokal, konfigurasi di atas sudah cukup.
Berapa banyak RAM yang dibutuhkan BIND9?
Untuk deployment kecil dengan beberapa zone internal, 256MB RAM sudah lebih dari cukup. BIND9 menggunakan cache agresif, jadi semakin besar RAM yang tersedia, semakin banyak record yang bisa di-cache.
Apa perbedaan named dan bind9 dalam konteks Ubuntu?
bind9 adalah nama package di Ubuntu, sementara named adalah nama daemon (service) yang dijalankan. Jadi kamu install bind9, tapi manage service-nya lewat systemctl dengan nama named.
Apakah perlu konfigurasi firewall setelah install BIND9?
Ya. Pastikan port 53 (UDP dan TCP) dibuka untuk subnet yang kamu izinkan:
sudo ufw allow from 192.168.10.0/24 to any port 53
Setelah semua ini jalan, kamu sudah punya DNS server internal yang berfungsi penuh. Bukan sesuatu yang gue banggakan di awal perjalanan, tapi sekarang setiap kali ada klien yang minta setup jaringan internal, BIND9 selalu jadi pilihan pertama karena stabilitas dan fleksibilitasnya sudah terbukti. Kamu sudah lewati bagian yang paling susah; sisanya cuma soal menambahkan lebih banyak record sesuai kebutuhan.