Operations 17 min read

Deploy BIND9 with chroot, ACL, and Views on CentOS 8

This guide walks through setting up BIND9 in a chroot environment, configuring ACLs and views for intelligent DNS routing, creating master and slave zones, and testing resolution on CentOS 8, providing a practical solution for secure and segmented DNS services.

Ops Development Stories
Ops Development Stories
Ops Development Stories
Deploy BIND9 with chroot, ACL, and Views on CentOS 8

Introduction

With the rapid development of the cloud‑native era, many companies require at least one year of Kubernetes experience, causing older technologies to be overlooked. This article records how to use BIND9 with chroot and ACL+view to achieve intelligent DNS.

Environment

OS: CentOS Linux release 8.4.2105

BIND version: 9.11.26

Network: 172.16.128.0/17, BIND master/slave segment: 172.16.0.0/24

Hosts: named‑srv1 (172.16.0.55, master), named‑srv2 (172.16.0.56, slave)

Deploy BIND9 Master with chroot

<code>/bin/chattr -i /etc/fstab /etc/passwd /etc/group /etc/shadow /etc/sudoers /etc/services

dnf -y install bind-chroot bind-utils

# Enable chroot and change named directory to /data/named/chroot
mkdir -p /data/named
cp -ar /var/named/* /data/named/

# Create log directory
mkdir -p /data/named/chroot/data/log/named/

# Create required files inside chroot
touch /data/named/chroot/var/named/data/cache_dump.db
touch /data/named/chroot/var/named/data/named_stats.txt
touch /data/named/chroot/var/named/data/named_mem_stats.txt
touch /data/named/chroot/var/named/data/named.run
mkdir /data/named/chroot/var/named/dynamic
touch /data/named/chroot/var/named/dynamic/managed-keys.bind

# Set ownership
cd /data
chown named.named -R named</code>

Edit named.conf on master

<code># cat /data/named/chroot/etc/named.conf
acl telecom { 172.17.10.0/24; };
acl unicom { 172.17.20.0/24; };
acl mobile { 172.17.30.0/24; };
options {
    listen-on port 53 { 127.0.0.1; 172.16.0.55; };
    directory "/var/named";
    dump-file "/data/named/data/cache_dump.db";
    statistics-file "/data/named/data/named_stats.txt";
    memstatistics-file "/data/named/data/named_mem_stats.txt";
    allow-query { any; };
    allow-query-cache { any; };
    forwarders { 223.5.5.5; 223.6.6.6; };
    recursive-clients 200000;
    check-names master warn;
    max-cache-ttl 60;
    max-ncache-ttl 0;
    pid-file "/run/named/named.pid";
};
logging {
    channel query_log {
        file "/data/log/named/query.log" versions 10 size 300m;
        severity info;
        print-category yes;
        print-time yes;
        print-severity yes;
    };
    channel client_log {
        file "/data/log/named/client.log" versions 3 size 200m;
        severity info;
        print-category yes;
        print-time yes;
        print-severity yes;
    };
    channel config {
        file "/data/log/named/config.log" versions 3 size 100m;
        severity info;
        print-category yes;
        print-time yes;
        print-severity yes;
    };
    channel default_log {
        file "/data/log/named/default.log" versions 3 size 100m;
        severity debug;
        print-category yes;
        print-time yes;
        print-severity yes;
    };
    channel general_log {
        file "/data/log/named/general.log" versions 3 size 200m;
        severity debug;
        print-category yes;
        print-time yes;
        print-severity yes;
    };
    category queries { query_log; };
    category client { client_log; };
    category general { general_log; };
    category config { config; };
    category default { default_log; };
};
view telecom_view {
    match-clients { telecom; };
    match-destinations { any; };
    recursion yes;
    include "/etc/named-telcome.zones";
};
view unicom_view {
    match-clients { unicom; };
    match-destinations { any; };
    recursion yes;
    include "/etc/named-unicome.zones";
};
view mobile_view {
    match-clients { any; };
    match-destinations { any; };
    recursion yes;
    include "/etc/named-mobile.zones";
};</code>

Create zone files

<code># vi /var/named/chroot/etc/named-telcome.zones
zone "ayunw.cn" IN {
    type master;
    file "ayunw.cn.zone";
    allow-update { none; };
    masterfile-format text;
    allow-transfer { 172.16.0.56; };
};
# vi /var/named/chroot/etc/named-unicom.zones
zone "iyunw.cn" IN {
    type master;
    file "iyunw.cn.zone";
    allow-update { none; };
    masterfile-format text;
    allow-transfer { 172.16.0.56; };
};
# vi /var/named/chroot/etc/named-mobile.zones
zone "allenjol.cn" IN {
    type master;
    file "allenjol.cn.zone";
    allow-update { none; };
    masterfile-format text;
    allow-transfer { 172.16.0.56; };
};</code>

Zone data files

<code># ayunw.cn.zone
$TTL 86400
@   IN  SOA ayunw.cn. root.iyunw.cn. (
        202111011 ; serial
        1H        ; refresh
        15M       ; retry
        1W        ; expiry
        1D )      ; minimum
    IN  NS  ns1.ayunw.cn.
    IN  NS  ns2.ayunw.cn.
ns1 IN  A   172.16.0.55
ns2 IN  A   172.16.0.56
www IN  A   172.16.0.58

# iyunw.cn.zone (similar structure, www -> web)
# allenjol.cn.zone (similar structure, www -> allen)</code>

Start and enable master service

<code>/usr/libexec/setup-named-chroot.sh /var/named/chroot on
systemctl stop named
systemctl disable named
systemctl start named-chroot
systemctl enable named-chroot</code>

Deploy BIND9 Slave

<code>/bin/chattr -i /etc/fstab /etc/passwd /etc/group /etc/shadow /etc/sudoers /etc/services

dnf -y install bind-chroot bind-utils

# Copy files to /data/named
mkdir -p /data/named
cp -ar /var/named/* /data/named/

# Create log directory
mkdir -p /data/named/chroot/data/log/named/

# Create required files
touch /data/named/chroot/var/named/data/cache_dump.db
touch /data/named/chroot/var/named/data/named_stats.txt
touch /data/named/chroot/var/named/data/named_mem_stats.txt
touch /data/named/chroot/var/named/data/named.run
mkdir /data/named/chroot/var/named/dynamic
touch /data/named/chroot/var/named/dynamic/managed-keys.bind

cd /data
chown named.named -R named</code>

Edit named.conf on slave (same as master)

<code># (same content as master configuration)</code>

Test resolution

<code>$ dig -t A www.ayunw.cn
... answer shows 172.16.0.58 ...

$ dig -t A web.iyunw.cn
... answer shows 172.16.0.59 ...

$ dig -t A allen.allenjol.cn
... answer shows 172.16.0.60 ...</code>

Clients outside the defined ACL subnets (172.16.10.0/24, 172.16.20.0/24, 172.16.30.0/24) receive no A record, demonstrating the intelligent DNS behavior achieved with ACL and view.

DNSSystem AdministrationBIND9ACLCentOSViewschroot
Ops Development Stories
Written by

Ops Development Stories

Maintained by a like‑minded team, covering both operations and development. Topics span Linux ops, DevOps toolchain, Kubernetes containerization, monitoring, log collection, network security, and Python or Go development. Team members: Qiao Ke, wanger, Dong Ge, Su Xin, Hua Zai, Zheng Ge, Teacher Xia.

0 followers
Reader feedback

How this landed with the community

login Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.