Cara Install dan Konfigurasi BIND9 DNS Server di Ubuntu

Install dan Konfigurasi BIND9 DNS Server di Ubuntu

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/24 dengan 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 ditulis 10.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.com

Kalau 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.