跳到主內容

BIND9 安裝記錄

  BUBU 在專案需求中需要使用 BIND9 來架設 DNS 服務。過去 BUBU 主要採用 PowerDNS 進行部署,但由於 BIND9 作為歷史悠久且廣泛應用的 DNS 伺服器軟體,具備穩定性與完整功能,因此本篇將記錄 BIND 的安裝與設定流程,以供後續參考與維護之用。

2025.11.26 修正有啟動 DNSSEC 服務

運行環境


  環境都是在 「Proxmox VE 」 虛擬系統上架設,都是以 「 LXC 」模式為主,除非有特殊狀況會告知使用 「 VM 」 模式

  • 系統環境: Ubuntu 24.04
  • 套件版本: BIND 9.18

安裝過程


  • 安裝必要套件
apt install bind9 bind9utils bind9-doc -y
  • 編輯設定檔 vim /etc/bind/named.conf.options
// 定義一個 存取控制清單 (ACL),名稱為 internal-network。
acl internal-network {192.168.1.0/24;};
options {        
              // BIND 工作目錄(快取、zone、DNSSEC 都放這裡)
              directory "/var/cache/bind";
              // 誰可以向這台 DNS 查詢紀錄。
              allow-query { localhost; internal-network; };
              // 誰可以用這台做遞迴查詢
              allow-recursion { localhost; internal-network; };
              // 定義 誰可以做 zone transfer (區檔複製),未來如果有 Slave 的話這裡要新增加 Slave 來源。
              allow-transfer { localhost; };
              // 指定上游 DNS 服務。
              forwarders { 8.8.8.8; };
              // 啟用 遞迴查詢,允許這台伺服器代替客戶端向其他 DNS 查詢結果。
              recursion yes;
              // 啟用 DNSSEC 驗證,自動使用系統內建的信任錨(trust anchor)。
              dnssec-validation auto;
              // 指定 BIND 在 IPv6 上監聽所有介面。
              listen-on-v6 { none; };
}; 
  • 設定 DNS 區域 (zones) 定義出來,讓 BIND9 知道要管理哪些網域名稱和對應的反解。 vim /etc/bind/named.conf.local
// ------------------------------------------------------------
// 正向區域設定 (Forward Zone):abc.local
// 這個區負責解析 abc.local 底下所有 A / MX / CNAME 等紀錄
// ------------------------------------------------------------
zone "abc.local" IN {
    // 本機為 Master(主 DNS)
    type master;

    // 未簽署(Unsigned)原始 zone 檔案位置
    // 注意:檔案必須放在 BIND 可寫目錄 (directory "/var/cache/bind")
    file "forward.abc.local";

    // 不允許外部動態更新 (如 nsupdate)
    allow-update { none; };

    // 指定 Slave(192.168.1.56)可以接收 zone transfer
    // 並且允許 localhost(系統自己)取 zone
    allow-transfer { localhost; 192.168.1.56; };

    // 在 zone 更新發生時自動通知 Slave
    also-notify { 192.168.1.56; };

    // 啟用 notify 機制(更新後立即同步給 Slave)
    notify yes;

    // 啟用 inline-signing (由 BIND 自動生成 *.signed 檔)
    // 用來產生 DNSSEC RRSIG / DNSKEY / NSEC / NSEC3 等紀錄
    inline-signing yes;

    // 啟用 DNSSEC Policy "default"
    // 會自動:生成 key、發布 key、簽署 zone、金鑰輪替
    dnssec-policy "default";
};


// ------------------------------------------------------------
// 反向區域設定 (Reverse Zone):192.168.1.0/24
// 用於將 IP → 主機名稱,例如:192.168.1.20 → www.abc.local
// ------------------------------------------------------------
zone "1.168.192.in-addr.arpa" IN {
    // 這台主機是該反向區的 Master
    type master;

    // 未簽署(Unsigned)反向區檔案
    file "reverse.abc.local";

    // 禁止外部動態更新(避免不受控的 PTR 新增/修改)
    allow-update { none; };

    // Slave(192.168.1.56)允許 AXFR/IXFR 區域同步
    allow-transfer { localhost; 192.168.1.56; };

    // 每當反向區更新,立即通知 Slave 過來取新的 zone
    also-notify { 192.168.1.56; };

    // 啟用自動通知 Slave
    notify yes;

    // 啟用 DNSSEC inline signing
    // BIND 會自動產生 reverse zone 的簽章檔 *.signed
    inline-signing yes;

    // 啟用 DNSSEC Policy "default"
    // 自動處理 key 產生、發布、簽署、金鑰更新
    dnssec-policy "default";
};

  • 設定 正向解析 vim /etc/bind/forward.abc.local
$TTL    86400
@       IN      SOA     ns1.abc.local. admin.abc.local. (
                        2025092201      ; Serial (版本號, 每次修改要遞增)
                        3600            ; Refresh (1 小時, Slave 多久檢查一次)
                        1800            ; Retry (30 分鐘, 檢查失敗多久後重試)
                        1209600         ; Expire (14 天, 若失聯多久後捨棄 zone)
                        86400 )         ; Minimum TTL (快取 1 天)

; --- DNS 伺服器 ---
        IN      NS      ns1.abc.local.   ; 主要 DNS
        IN      NS      ns2.abc.local.   ; 次要 DNS (Slave)

; --- 主機紀錄 ---
ns1     IN      A       192.168.1.10
ns2     IN      A       192.168.1.11
www     IN      A       192.168.1.20
mail    IN      A       192.168.1.30

; --- 郵件紀錄 ---
@       IN      MX 10   mail.abc.local.
  • 設定 反向解析 vim /etc/bind/reverse.abc.local
$TTL    86400
@       IN      SOA     ns1.abc.local. admin.abc.local. (
                        2025092201      ; Serial (版本號, 要跟正向解析一致)
                        3600            ; Refresh (1 小時, Slave 多久檢查一次)
                        1800            ; Retry (30 分鐘, 檢查失敗多久後重試)
                        1209600         ; Expire (14 天, 若失聯多久後捨棄 zone)
                        86400 )         ; Minimum TTL (快取 1 天)

; --- DNS 伺服器 ---
        IN      NS      ns1.abc.local.
        IN      NS      ns2.abc.local.

; --- PTR (反向解析) ---
10      IN      PTR     ns1.abc.local.   ; 192.168.1.10 → ns1.abc.local
11      IN      PTR     ns2.abc.local.   ; 192.168.1.11 → ns2.abc.local
20      IN      PTR     www.abc.local.   ; 192.168.1.20 → www.abc.local
30      IN      PTR     mail.abc.local.  ; 192.168.1.30 → mail.abc.local
  • 設定 BIND9 只監聽 IPv4 vim /etc/default/named
# 修改前
IONS="-u bind"

# 修改後
IONS="-u bind -4"
  • 驗證主設定檔
named-checkconf /etc/bind/named.conf.local
  • 驗證正向解析設定檔
named-checkzone abc.local /etc/bind/forward.abc.local

  • 驗證反向解析設定檔
named-checkzone 10.168.192.in-addr.arpa /etc/bind/reverse.abc.local

  • 驗證所有設定檔
named-checkconf -z
  • 啟動服務
systemctl enable --now named
  • 驗證 DNSSEC
dig @192.168.1.55 abc.local DNSKEY +dnssec
dig @192.168.1.55 www.abc.local +dnssec
dig @192.168.1.55 -x 192.168.1.20 +dnssec

Slave設定

  • 編輯設定檔 vim /etc/bind/named.conf.options
// 定義一個 存取控制清單 (ACL),名稱為 internal-network。
acl internal-network {192.168.1.0/24;};
options {        
              // 指定 BIND9 快取存放位置
              directory "/var/cache/bind";
              // 誰可以向這台 DNS 查詢紀錄。
              allow-query { localhost; internal-network; };
              // 誰可以用這台做遞迴查詢
              allow-recursion { localhost; internal-network; };
              // Slave 端「不主動提供」zone transfer 給其他人
              allow-transfer { none; };
              // 指定上游 DNS 服務。
              forwarders { 8.8.8.8; };
              // 啟用 遞迴查詢,允許這台伺服器代替客戶端向其他 DNS 查詢結果。
              recursion yes;
              // 啟用 DNSSEC 驗證,自動使用系統內建的信任錨(trust anchor)。
              dnssec-validation auto;
              // 指定 BIND 在 IPv6 上監聽所有介面。
              listen-on-v6 { none; };
}; 
  • 設定 DNS 區域 (zones) 定義出來,讓 BIND9 知道要管理哪些網域名稱和對應的反解。 vim /etc/bind/named.conf.local
// 正向解析 (Forward Lookup Zone) 的定義
// 要管理的網域
zone "abc.local" IN {
              // 設定這台是 slave
              type slave;
              // Slave 區檔,BIND 自動寫入(會收到 signed zone)
              file "forward.abc.local";
              // 指定這個 zone 的 Master DNS 伺服器來源。
              masters { 192.168.1.1; };
              // 需要更嚴謹可加:
              // allow-notify { 192.168.1.55; };
};

// 反向解析 (Reverse Lookup Zone) 的定義
// 管理的反向區域是 192.168.1.0/24
zone "1.168.192.in-addr.arpa" IN {
                // 設定這台是 slave
                type slave;
                // 指定反向解析的區檔存放位置。
                file "reverse.abc.local";
                // 指定這個 zone 的 Master DNS 伺服器來源。
                masters { 192.168.1.1; };
                // 需要更嚴謹可加:
                // allow-notify { 192.168.1.55; };
};
  • 檢查語法
named-checkconf
named-checkzone abc.local /var/cache/bind/forward.abc.local
named-checkzone 1.168.192.in-addr.arpa /var/cache/bind/reverse.abc.local

記錄檔

  • 新增 logs 設定檔 vim /etc/bind/named.conf.logging 將以下設定貼上
logging {

    // ----------------------------------------------------
    // 1. 查詢紀錄(Query Log)
    // ----------------------------------------------------
    channel query_log {
        file "/var/log/bind/query.log" versions 7 size 50m;
        severity info;
        print-time yes;
        print-category yes;
        print-severity yes;
    };

    category queries { query_log; };


    // ----------------------------------------------------
    // 2. DNSSEC 記錄
    // ----------------------------------------------------
    channel dnssec_log {
        file "/var/log/bind/dnssec.log" versions 3 size 10m;
        severity info;
        print-time yes;
        print-category yes;
        print-severity yes;
    };

    category dnssec    { dnssec_log; };
    category lame-servers  { dnssec_log; };
    category security      { dnssec_log; };


    // ----------------------------------------------------
    // 3. Zone 與 AXFR/IXFR 相關紀錄
    // ----------------------------------------------------
    channel xfer_log {
        file "/var/log/bind/xfer.log" versions 7 size 20m;
        severity info;
        print-time yes;
        print-category yes;
        print-severity yes;
    };

    category xfer-in     { xfer_log; };
    category xfer-out    { xfer_log; };
    category notify      { xfer_log; };
    category update      { xfer_log; };
    category update-security { xfer_log; };


    // ----------------------------------------------------
    // 4. 一般 BIND 運作(啟動、錯誤、警告)
    // ----------------------------------------------------
    channel default_log {
        file "/var/log/bind/default.log" versions 7 size 20m;
        severity info;
        print-time yes;
        print-category yes;
        print-severity yes;
    };

    category default    { default_log; };
    category general    { default_log; };
    category config     { default_log; };
    category database   { default_log; };
    category dispatch   { default_log; };
};
  • 載入設定檔 vim /etc/bind/named.conf
include "/etc/bind/named.conf.logging";
  • 建立 log 目錄並給權限
sudo mkdir -p /var/log/bind
sudo chown bind:bind /var/log/bind
sudo chmod 755 /var/log/bind
  • 重啟服務
systemctl restart bind9
  • 自動分割日誌 vim /etc/logrotate.d/bind
/var/log/bind/*.log {
    daily                  # 每天輪替一次 log 檔案
    rotate 14              # 保留 14 份歷史 log(約兩週)
    missingok              # 若該 log 檔不存在則忽略,不顯示錯誤
    compress               # 使用 gzip 壓縮舊 log,例如 query.log.1.gz
    delaycompress          # 延後一天再壓縮(避免 .1 當天還需要讀)
    notifempty             # 若 log 檔是空的,就不要輪替

    create 640 bind bind   # 新 log 檔案建立後權限為 640,擁有者 bind:bind
                           # 讓 named 程式可以正常寫入

    sharedscripts          # postrotate 指令只執行一次(不是每個檔案跑一次)

    postrotate
        # 每次 log 轉檔後重新載入 named
        # 讓 BIND 重新打開新的 log 檔案,避免寫入已被輪替的舊檔案
        /usr/sbin/rndc reload > /dev/null 2>&1 || true
    endscript
}

DNSSEC 的 KSK 固定不動

  • BUBU 因專案遇到是教育單位,但 KSK 金鑰是無法去更新,只能更新 ZSK 金鑰以下是記錄設定檔做為參考

  • 新設設定檔 vim /etc/bind/named.conf.policies

//
// DNSSEC Policy:KSK 固定不動、ZSK 自動輪替
//

dnssec-policy "gov-stable-ksk" {

    // 使用 NSEC3(政府單位常用)
    nsec3param iterations 10 salt-length 16;

    // 設定金鑰行為
    keys {
        // -----------------------
        // 固定 KSK(不輪替)
        // -----------------------
        ksk lifetime unlimited;          // 永不變動
        ksk algorithm ecdsap256sha256;   // 推薦:較安全、較快
        ksk size 256;

        // -----------------------
        // 自動 ZSK 輪替:例如 60 天
        // -----------------------
        zsk lifetime 60d;                // 建議 30~90 天
        zsk algorithm ecdsap256sha256;
        zsk size 256;
    };
};
  • 載入設定檔 vim /etc/bind/named.conf
include "/etc/bind/named.conf.options";
include "/etc/bind/named.conf.policies";   // ← 在 options 之後,local 之前
include "/etc/bind/named.conf.local";
include "/etc/bind/named.conf.default-zones";
  • Zone 區塊引用 Policy(Master)vim /etc/bind/named.conf.local
# 正向
zone "abc.local" IN {
    type master;

    // 原始 unsigned zone(不可放 DNSSEC 記錄)
    file "forward.abc.local";

    allow-update { none; };
    allow-transfer { localhost; 192.168.1.56; };

    also-notify { 192.168.1.56; };
    notify yes;

    // 啟用 DNSSEC
    inline-signing yes;

    // <<< 這裡引用剛剛的 policy!
    dnssec-policy "gov-stable-ksk";
};

# 反向
zone "1.168.192.in-addr.arpa" IN {
    type master;
    file "reverse.abc.local";

    allow-update { none; };
    allow-transfer { localhost; 192.168.1.56; };

    also-notify { 192.168.1.56; };
    notify yes;

    inline-signing yes;

    // <<< 一樣引用 policy
    dnssec-policy "gov-stable-ksk";
};
  • 重啟服務
sudo systemctl restart bind9
  • 確認
rndc dnssec -status abc.local

補充說明


備註





參考相關網頁