AlmaLinux9でdhcpとbindを連携させ家庭内DDNS

DNSサーバーもDHCPサーバーも1台で兼任させるが、冗長化のためゾーン転送を利用して2台分を設定する。

・ AlmaLinux: 9.4
・ bind: 9.16.23
・ dhcp-server: 4.4.2
・ プライマリIPアドレス: 192.168.1.11
・ セカンダリIPアドレス: 192.168.1.12

プライマリサーバーの設定

パッケージをインストールする。

# dnf install bind dhcp-server

DNSサーバーの設定ファイルを変更または追記する。

options {
    listen-on port 53 { any; };
    listen-on-v6 { none; };
    directory "/var/named/";
    …
    // LAN内からの問い合わせを許可
    allow-query {
        localhost;
        192.168.1.0/24;
    };
    …
    // ゾーン転送を許可するIPを設定
    allow-transfer {
        192.168.1.12;
    };
    // 自分で名前解決できないときの丸投げ先
    forwarders {
        192.168.1.254;
        8.8.8.8;
    };
};
…
zone "example.jp." {
    type master;
    file "example.jp.zone";
    // 自身からの変更を許可
    allow-update {
        localhost;
        192.168.1.12;
    };
};
…

さっき指定したzoneファイルを作成する。
※LAN内のDDNSに使用するため更新間隔を短く
※”admin.example.jp.”は”admin@example.jp”という管理者のE-mailという意味らしい

$TTL 86400
@    IN    SOA    sv1.example.jp.    admin.example.jp. (
           2024071501
           300
           60
           3600
           300
)

        IN    NS   sv1.example.jp.
        IN    NS   sv2.example.jp.
sv1     IN    A    192.168.1.11
sv2     IN    A    192.168.1.12

作成したらファイルの所有者をnamedに変更する。

# chown named:named /var/named/example.jp.zone

DHCPサーバーの設定ファイルに下記を追記する。

# DNSサーバーに更新要求を送信する設定
ddns-update-style interim;
# 普通のDHCPの設定
subnet 192.168.1.0 netmask 255.255.255.0 {
    range 192.168.1.101 192.168.1.120;
    option routers 192.168.1.254;
    option domain-name "example.jp";
    option domain-name-servers 192.168.1.11, 192.168.1.12;
    # 更新を通知するDNSサーバーを指定
    zone example.jp. {
        primary localhost;
    }
}

SELinuxとファイアウォールに例外を追加する。

# setsebool -P named_write_master_zones true
# firewall-cmd --add-service=dns --permanent
# firewall-cmd --add-service=dhcp --permanent
# firewall-cmd --reload

サービスを有効にして起動。

# systemctl enable --now named
# systemctl enable --now dhcpd

セカンダリサーバーの設定

パッケージをインストールする。

# dnf install bind dhcp-server

DNSサーバーの設定ファイルを変更または追記する。

options {
    listen-on port 53 { any; };
    listen-on-v6 { none; };
    directory "/var/named/";
    …
    allow-query {
        localhost;
        192.168.1.0/24;
    };
    …
    forwarders {
        192.168.1.254;
        8.8.8.8;
    };
};
…
zone "example.jp." {
    type slave;
    file "example.jp.zone";
    masters {
        192.168.1.11;
    };
};
…

DHCPサーバーの設定ファイルに下記を追記する。

ddns-update-style interim;
subnet 192.168.1.0 netmask 255.255.255.0 {
    range 192.168.1.121 192.168.1.140;
    option routers 192.168.1.254;
    option domain-name "example.jp";
    option domain-name-servers 192.168.1.11, 192.168.1.12;
    zone example.jp. {
        primary 192.168.1.11;
    }
}

SELinuxとファイアウォールに例外を追加する。

# firewall-cmd --add-service=dns --permanent
# firewall-cmd --add-service=dhcp --permanent
# firewall-cmd --reload

サービスを有効にして起動。

# systemctl enable --now named
# systemctl enable --now dhcpd

補足

ゾーンを再読み込みする

保持しているゾーンの情報をリロードする。mastersのシリアルが保持しているシリアルよりも大きければゾーン転送が行われる。

# rndc reload example.jp
現在のDNSレコードの確認

rndcでdumpして現在のDNSレコードを確認する。

# rndc dumpdb -zones
# less /var/named/data/cache_dump.db 
DNSレコードの更新テスト

nsupdateを使用してDNSサーバーを更新をテストするにはbind-utilsをインストールし、nsupdateコマンドを実行する。実行したら対話型コンソールになるので下記のような感じで入力する。何もエラーが出なければOK。
※INはインターネットの意味らしいが未指定でも問題ない

>server 127.0.0.1
>update add test.example.jp. 3600 IN A 192.168.1.222
>send
>server 127.0.0.1
>update delete test.example.jp. IN
>send
DNSレコードの削除

まれにDNSレコードのIPアドレスが一切更新されなくなるクライアントがある。nsupdateコマンドを実行して古いDNSレコードを削除するとそのうち直る。

>server 127.0.0.1
>update delete test.example.jp.
>send