NixOSでDNSサーバの構築

前回の記事では、システムやアプリケーション等のログを収集、処理、転送するためのログ管理ツールであるrsyslogをNixOSに導入し、家庭内LANにてSyslogサーバが稼働しているDebian GNU/Linuxにログがリアルタイムに転送される事を確認した。
今回は、当ブログの著者の家庭内で以前稼働していたDNSサーバを再び稼働させるべく、NixOSにBINDを導入し簡単な動作確認を行った。
2025/4/11追記 NixOSネタの記事の一覧は、当記事内最下部の「NixOS関連の記事」欄内を参照。
 


DNSサーバについて
DNSサーバとは「Domain Name Systemサーバ」の事で、インターネット上で使われる「名前(ドメイン名)」と「IPアドレス」を変換する役割を持つ。
コンピュータ(クライアント)は接続先をIPアドレスで認識する為、接続する際はDNSサーバに対し、接続先のドメイン名に対するIPアドレスを問い合わせる。DNSサーバはルートサーバや他のDNSサーバに問い合わせを行い、返答内容(接続先のIPアドレス)をクライアントに返す。コンピュータはこのIPアドレスを使って接続先に接続する。
当記事にて扱うBIND(Berkeley Internet Name Domain)は、現在インターネットにて最も利用されているDNSサーバである。



当方の環境
ホスト機:macOS 15.4 / MacBook Pro 2020 / RAM: 16GB / CPU: Intel Core i5 2.0GHz
仮想化環境:Oracle VirtualBox 7.1.4 r165100
ゲストOS:NixOS 24.11 (Vicuna)
DNSサーバ:BIND 9.18.33
BINDでDNSサーバを構築した後、動作確認用のサーバ(Debian GNU/Linux 12.10)にて、resolv.confの中に記載されているIPアドレスをBINDが稼働しているNixOSのIPアドレスに変更し、BINDの操作確認を実施した。
 


今回の要件
NixOSがDNSサーバ、Debian GNU/Linuxがクライアントとする。
DNSサーバ用にNixOSを新規に立ち上げてBINDを導入。Debian GNU/LinuxからNixOS(DNSサーバ)に対し正引き・逆引きで名前解決の確認とgoogle.co.jpのNSレコードを確認する。
機能てんこ盛りなシステムは嫌なので、前回の記事作成まで稼働してきたNixOSではなく、DNSサーバ用にNixOSを新規に立ち上げてBINDのインストールや設定や動作確認を行った。NixOSのインストールおよび初期設定は以下の内容を実施した。
https://debslink.hatenadiary.jp/entry/20250311/1741649715 NixOSの沼に片足を突っ込んだ
https://debslink.hatenadiary.jp/entry/20250320/1742459549 NixOSの環境構築(今回はneofetch未導入)
 
ざっくりとした要件は以下のとおり。
・IPv4の通信のみListenする、IPv6の通信はListenしない。
・名前解決の問い合わせを受け付ける(localhost、自分が所属するネットワーク、172.16.0.0/12、10.0.0.0/8)
・DNSサーバが稼働しているNixOSにて名前解決出来ない問い合わせは、GoogleのDNSに投げる。
・BINDの設定は/etc/nixos/configuration.nixファイルの中に追記するのではなく、/etc/nixos/named.nixファイルを新規作成しその中に記載する。
・正引き・逆引きのゾーンファイルは別途作成せず、/etc/nixos/named.nix内にまとめて記載する。
 
設定に取り掛かる前に、今の動作環境を出力。

[testsv99:~ ]# uname -a
Linux testsv99 6.6.82 #1-NixOS SMP PREEMPT_DYNAMIC Sun Mar  9 08:55:04 UTC 2025 x86_64 GNU/Linux
[testsv99:~ ]# 
[testsv99:~ ]# zsh --version
zsh 5.9 (x86_64-pc-linux-gnu)
[testsv99:~ ]# 

 


BINDのインストールと設定

1. BINDをインストールする為の設定
BINDパッケージの導入設定とBINDの設定を済ませる。
/etc/nixos/configuration.nixファイル内の上の方に有るimportsの項目にて、BINDの設定ファイル/etc/nixos/named.nixを読み込ませる設定を追記する。
ただし、/etc/nixos/named.nixファイルを作成せず/etc/nixos/configuration.nixファイル内にBINDの設定を書く場合は、/etc/nixos/configuration.nixファイルに./named.nixを追記する必要は無い。

[testsv99:~ ]# sudo nvim /etc/nixos/configuration.nix

{ config, pkgs, ... }:

{
  imports =
    [ # Include the results of the hardware scan.
      ./hardware-configuration.nix
      ./ssh.nix
      ./zsh.nix
      ./nvim.nix
      ./chrony.nix
      ./named.nix  ◻️◻️この行を追記
    ];
:
省略
:


続いて、/etc/nixos/configuration.nixファイル内に、以下のようにBINDパッケージのインストールの設定を追記する。

:
省略
:
  # List packages installed in system profile. To search, run:
  # $ nix search wget
  environment.systemPackages = with pkgs; [
  #  vim # Do not forget to add an editor to edit configuration.nix! The Nano editor is also installed by default.
    zsh
    neovim
    curl
    chrony
    bind  ◻️◻️この行を追記
  ];
:
省略
:

 

2. BINDの設定
sudo nixos-rebuild switchコマンドを叩いてBINDをインストールする前に、BINDの設定を済ませる。
他のLinuxディストリビューションで言う/etc/named.conf的な、以下の/etc/nixos/named.nixファイルを作成する。
以下の設定を/etc/nixos/configuration.nixファイル内に書く事は可能だが、当記事では/etc/nixos/named.nixファイル内に書く方を採用する。
 
NixOSにてBINDの設定をする際の注意事項は、以下のとおり。
① /etc/nixos/named.nixに正引き・逆引き設定を書いた場合、named-checkconfコマンドで設定ファイルの内容のチェックが出来ない。
② 自分の環境だけだろうか、正引き設定と逆引き設定は、IN NSやIN MXで始まる行は行頭を1文字分だけ空けて、それ以外の行は全てエディタの左端から書かないと設定が読み込まれなかった。
③ services.bind.cacheNetworks = [ "any" ];の設定が無い状態でクライアント側にてdigコマンドを叩くと、ANSWER SECTION:が無い状態で結果が返ってくる。その状態でDNSサーバ側でsudo systemctl status bind.serviceを叩くと、/A/IN' denied (allow-query-cache did not match) のログが出力される。

※以下の設定例は行数多めにつき、Webブラウザによって全て表示しきれない事があります。その場合は黒塗りの箇所をスクロールする事で終わりまで表示する事が出来ます。

[testsv99:~ ]# sudo nvim /etc/nixos/named.nix   
{ pkgs, ... }:
{
  services.bind.enable = true;
  services.bind.listenOn = [ "any" ];
  services.bind.ipv4Only = true;
  services.bind.forwarders = [ "8.8.8.8" "192.168.3.1" ];
  services.bind.cacheNetworks = [ "any" ];
  services.bind.extraConfig = ''
      acl internal-network {
      192.168.0.0/16;
      172.16.0.0/12;
      10.0.0.0/8;
      localhost;
    };
  '';
  services.bind.extraOptions = ''
      recursion yes;
  '';
  services.bind.zones = {
    "testsv99.local" = {
      allowQuery = [ "internal-network" "any" ];
      master = true;
    };
    "3.168.192.in-addr.arpa" = {
      allowQuery = [ "internal-network" "any" ];
      master = true;
    };
  };
services.bind.zones."testsv99.local".file = pkgs.writeText "testsv99.local" ''
$TTL 86400
@ IN SOA testsv99.local. root.testsv99.local. (
2025041101 ;Serial
3600 ;Refresh
1800 ;Retry
604800 ;Expire
86400 ;Minimum TTL
);
 IN NS testsv99.local.
 IN A 192.168.3.247
testsv99 IN A 192.168.3.247
bind IN A 192.168.3.247
'';
services.bind.zones."3.168.192.in-addr.arpa".file = pkgs.writeText "testsv99.rev" ''
$TTL 86400
@ IN SOA testsv99.local. root.testsv99.local. (
2024122001 ;Serial
3600 ;Refresh
1800 ;Retry
604800 ;Expire
86400 ;Minimum TTL
);
 IN NS testsv99.local.
247 IN PTR testsv99.
}
[testsv99:~ ]# 

 
NixOSはSSHやSambaやrsyslog等はポート開放の設定を投入しなくても、それぞれ通信は可能である。
しかしBINDはポートを開けないと、DNSの通信が出来ない。
ファイアウォール機能を有効にしTCP/53とUDP/53を開ける設定を入れるついでに、SSHやNTPなどで使用されるポートも開ける設定を投入した。

sudo nvim /etc/nixos/configuration.nix
:
省略
:
  # Open ports in the firewall.
  # networking.firewall.allowedTCPPorts = [ ... ];
  # networking.firewall.allowedUDPPorts = [ ... ];
  # Or disable the firewall altogether.
  networking.firewall.enable = true;  ◻️◻️コメントアウトを外し、falseをtrueに修正
  networking.firewall.allowPing = true;  ◻️◻️この行を含め下3行を追加
  networking.firewall.interfaces."enp0s3".allowedTCPPorts = [ 22 53 123 ];
  networking.firewall.interfaces."enp0s3".allowedUDPPorts = [ 53 123 ];
:
省略
:

 
以上をもってインストールの準備とBINDの設定が出来た。
ここで一旦sudo nixos-rebuild switchを実行し、NixOSにBINDをインストール。

[testsv99:~ ]# sudo nixos-rebuild switch           
building Nix...
building the system configuration...
:
省略
:
[testsv99:~ ]#

 
sudo nixos-rebuild switchコマンドがエラーを吐かず正常に完了したら、名前解決の問い合わせ先をNixOS自身(DNSサーバ)に設定する。
以下の内容では元々あった8.8.8.8を削除しているが、削除せず並記しても良い。

[testsv99:~ ]# sudo nvim /etc/nixos/configuration.nix
:
省略
:
  networking.interfaces.enp0s3.ipv4.addresses = [{
    address = "192.168.3.247";
    prefixLength = 24;
  }];
  networking.defaultGateway = "192.168.3.1";
  networking.nameservers = [ "192.168.3.247" ]; ◻️◻️8.8.8.8から変更

  networking.hosts = {
    "127.0.0.1" = [ "localhost" "localhost.localdomain" ]; 
    "192.168.3.247" = [ "testsv99" "testsv99.local" ]; 
  }; 
:
省略
:

 
再度sudo nixos-rebuild switchを実行し、上記の設定をシステムに反映させる。

[testsv99:~ ]# sudo nixos-rebuild switch           
building Nix...
building the system configuration...
:
省略
:
[testsv99:~ ]#

 
sudo nixos-rebuild switchコマンドがエラーを吐かず、正常に完了したら、systemctlコマンドでBINDサービスを再起動させ、BINDの設定内容を再読み込ませる。
続いて、BINDサービスが正常に立ち上がっているか確認する。
Active: の行が active (running) になっている事と、ログの中にエラー等が出力されていない事を確認する。
問題無ければ、NixOS側(DNSサーバ側)の設定は完了。

[testsv99:~ ]# sudo systemctl restart bind.service
[testsv99:~ ]# 
[testsv99:~ ]# 
[testsv99:~ ]# sudo systemctl status bind.service
● bind.service - BIND Domain Name Server
     Loaded: loaded (/etc/systemd/system/bind.service; enabled; preset: ignored)
     Active: active (running) since Thu 2025-04-10 23:29:53 JST; 10s ago
 Invocation: 0ab9a93662ec4d3381b5a1c921573031
       Docs: man:named(8)
    Process: 2174 ExecStartPre=/nix/store/k7xa5h1pwv7hlc4s2n10lk4p305kq0a6-unit-script-bind-pre-start/bin/bind-pre-start (code=>
    Process: 2180 ExecStart=/nix/store/cx9bax06pm55f9srbm3ib3nr50zk8iqh-bind-9.18.33/sbin/named -u named -4 -c /nix/store/y32q7>
   Main PID: 2182 (named)
         IP: 4.5K in, 1K out
         IO: 0B read, 0B written
      Tasks: 10 (limit: 4662)
     Memory: 6.5M (peak: 7M)
        CPU: 64ms
     CGroup: /system.slice/bind.service
             └─2182 /nix/store/cx9bax06pm55f9srbm3ib3nr50zk8iqh-bind-9.18.33/sbin/named -u named -4 -c /nix/store/y32q7cz6x45h3>

Apr 10 23:29:53 testsv99 named[2182]: automatic empty zone: RESOLVER.ARPA
Apr 10 23:29:53 testsv99 named[2182]: command channel listening on 127.0.0.1#953
Apr 10 23:29:53 testsv99 named[2182]: managed-keys-zone: loaded serial 3
Apr 10 23:29:53 testsv99 named[2182]: zone test.local.zone/IN: loaded serial 2025041101
Apr 10 23:29:53 testsv99 named[2182]: zone 3.168.192.in-addr.arpa/IN: loaded serial 2024122001
Apr 10 23:29:53 testsv99 named[2182]: all zones loaded
Apr 10 23:29:53 testsv99 named[2182]: running
Apr 10 23:29:53 testsv99 systemd[1]: Started BIND Domain Name Server.
Apr 10 23:29:53 testsv99 named[2182]: managed-keys-zone: Key 20326 for zone . is now trusted (acceptance timer complete)
Apr 10 23:29:53 testsv99 named[2182]: managed-keys-zone: Key 38696 for zone . is now trusted (acceptance timer complete)
[testsv99:~ ]# 

 

3. クライアント側の設定
クライアント側であるDebian GNU/Linuxにて、DNSサーバの設定変更。
8.8.8.8から当記事にて構築したNixOSのDNSサーバのIPアドレス、192.168.3.247に変更する。

[hogehoge@jpmtkvmsv99 ~]$ su -
[root@jpmtkvmsv99 ~]#
[root@jpmtkvmsv99 ~]# vi /etc/network/interfaces
# This file describes the network interfaces available on your system
# and how to activate them. For more information, see interfaces(5).

source /etc/network/interfaces.d/*

# The loopback network interface
auto lo
iface lo inet loopback

# The primary network interface
allow-hotplug enp0s3
#iface enp0s3 inet dhcp
iface enp0s3 inet static
address 192.168.3.251
network 192.168.3.0
netmask 255.255.255.0
gateway 192.168.3.1
dns-nameservers 192.168.3.247 ◻️◻️8.8.8.8から変更

# This is an autoconfigured IPv6 interface
#iface enp0s3 inet6 auto
[root@jpmtkvmsv99 ~]# 

 
上記の設定変更の後、設定内容をシステムに反映させる為networkingサービスを再起動させる。

[root@jpmtkvmsv99 ~]# service networking restart
[root@jpmtkvmsv99 ~]# 

 


DNSサーバの動作確認
お疲れ様でした。
DNSサーバの構築およびクライアント側で設定変更を終えたところで、DNSサーバによる名前解決の動作確認を実施する。クライアント側にてdigコマンドをDNSサーバのホスト名を付けて叩き、上記で設定したDNSサーバの名前解決が正常に出来ているか確認する。
ANSWER SECTION: の出力内容のとおり、正常に名前解決が出来ている事が分かる。

[hogehoge@jpmtkvmsv99 ~]$ dig testsv99.local

; <<>> DiG 9.18.33-1~deb12u2-Debian <<>> testsv99.local
;; global options: +cmd
;; Got answer:
;; WARNING: .local is reserved for Multicast DNS
;; You are currently testing what happens when an mDNS query is leaked to DNS
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 33564
;; flags: qr aa rd ra; QUERY: 1, ANSWER: 1, AUTHORITY: 0, ADDITIONAL: 1

;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags:; udp: 1232
; COOKIE: 26d66c4c9adbad690100000067fb9c9eeb11da5f8890c45a (good)
;; QUESTION SECTION:
;testsv99.local.		IN	A

;; ANSWER SECTION:
testsv99.local.	86400	IN	A	192.168.3.247

;; Query time: 19 msec
;; SERVER: 192.168.3.247#53(192.168.3.247) (UDP)
;; WHEN: Thu Apr 11 00:04:18 JST 2025
;; MSG SIZE  rcvd: 140

[hogehoge@jpmtkvmsv99 ~]$ 

 
続いて、digコマンドを-xのオプションを付けて叩き、上記で設定したDNSサーバの逆引きの名前解決を確認する。
ANSWER SECTION: の出力内容のとおり、正常に逆引きで名前解決が出来ている事が分かる。

[hogehoge@jpmtkvmsv99 ~]$ dig -x 192.168.3.247 

; <<>> DiG 9.18.33-1~deb12u2-Debian <<>> -x 192.168.3.247
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 1718
;; flags: qr aa rd ra; QUERY: 1, ANSWER: 1, AUTHORITY: 0, ADDITIONAL: 1

;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags:; udp: 1232
; COOKIE: a00cf3ebf55430df0100000067f72da20f331e9d2b53812d (good)
;; QUESTION SECTION:
;247.3.168.192.in-addr.arpa.	IN	PTR

;; ANSWER SECTION:
247.3.168.192.in-addr.arpa. 86400 IN	PTR	testsv99.

;; Query time: 7 msec
;; SERVER: 192.168.3.247#53(192.168.3.247) (UDP)
;; WHEN: Thu Apr 11 00:06:02 JST 2025
;; MSG SIZE  rcvd: 105

[hogehoge@jpmtkvmsv99 ~]$ 

 
最後に、digコマンドをgoogle.co.jpを付けて叩いて、名前解決を確認する。
ANSWER SECTION: の出力内容のとおり、正常に名前解決が出来ている事が分かる。

[hogehoge@jpmtkvmsv99 ~]$ dig google.co.jp

; <<>> DiG 9.18.33-1~deb12u2-Debian <<>> google.co.jp
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 1496
;; flags: qr rd ra; QUERY: 1, ANSWER: 1, AUTHORITY: 0, ADDITIONAL: 1

;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags:; udp: 1232
; COOKIE: fb040422e01044740100000067f72dd48adf9b4a5b3b1398 (good)
;; QUESTION SECTION:
;google.co.jp.			IN	A

;; ANSWER SECTION:
google.co.jp.		79	IN	A	142.250.207.3

;; Query time: 27 msec
;; SERVER: 192.168.3.247#53(192.168.3.247) (UDP)
;; WHEN: Thu Apr 11 00:06:52 JST 2025
;; MSG SIZE  rcvd: 85

[hogehoge@jpmtkvmsv99 ~]$ 

  

今回はここまで。
NixOSにおけるBINDの設定のみならず、設定ファイル.nixファイルの先頭行に記述されている関数{ pkgs, ... }:の意味について分かった事が大きな収穫となった。これに気が付かないままだったら、正引き・逆引きのゾーンファイルの内容を/etc/nixos/named.nixの中に書かず、/run/named/test.local.zoneと/run/named/test.local.revファイルを作成していただろう。/run/namedディレクトリ内に作成すると、NixOSが再起動した際に中のファイルが消えてしまう。設定を永続的に残したい為、/etc/nixos/named.nixの中にまとめて書いた。
ようやく設定が完了し動作確認を終え、気が付いたら日を跨ぎ4月11日になっていた。本日で50歳、NixOSと戯れる誕生日。
 


振り返り
当記事ではBINDのインストールと設定から接続確認までさらっと書いているのだが、実は名前解決確認が成功するまで5日間ほど要した。
以前稼働させていたBINDの設定を流用するだけでは名前解決が正常に行われず、正引きと逆引きの設定内容を左端に揃えたり、いくつか設定内容の変更や追加をする事で、正常稼働にまで辿り着く事が出来た。
設定内容の見直しをするにあたり、BINDやDNSに関するいくつかの有用なサイトが非常に参考になった。ここ暫くの間はBINDやDNSサーバに触れる機会が少なく忘れかけていただけに、いい勉強になった。
 


 


参照サイト
https://nixos.org/ Nix & NixOS Declarative builds and deployments
https://nixos.org/manual/nixos/stable/ NixOS Manual
https://search.nixos.org/packages NixOS Search Packages
https://search.nixos.org/options? NixOS Search Options
https://www.isc.org/bind/ BIND9
https://wiki.nixos.org/wiki/Bind Bind - NixOS Wiki
https://tech.synapse.jp/entry/2020/07/15/130000 BINDの大切な設定の話 シナプス技術者ブログ
https://www.dnsops.jp/event/20140626/dns-beginners-guide2014-mizuno.pdf 初心者のためのDNS運用入門 - トラブル事例とその解決のポイント -
https://qiita.com/leomaro7/items/d6907d0a2aee890fe52b DNSサーバー、BINDについて学ぶ
https://zenn.dev/asa1984/articles/nixos-is-the-best NixOSで最強のLinuxデスクトップを作ろう
 

NixOS関連の記事
https://debslink.hatenadiary.jp/entry/20250311/1741649715 NixOSの沼に片足を突っ込んだ
https://debslink.hatenadiary.jp/entry/20250316/1742128054 NixOSにFlakeを導入した
https://debslink.hatenadiary.jp/entry/20250320/1742459549 NixOSの環境構築
https://debslink.hatenadiary.jp/entry/20250323/1742731080 NixOSでSFTPサーバの設定
https://debslink.hatenadiary.jp/entry/20250328/1743167901 NixOSでSambaによるファイルサーバの構築
https://debslink.hatenadiary.jp/entry/20250405/1743844940 NixOSでrsyslogの設定
https://debslink.hatenadiary.jp/entry/20250411/1744300480 NixOSでDNSサーバの構築
https://debslink.hatenadiary.jp/entry/20250413/1744551596 NixOSのシステムの再現性の検証
https://debslink.hatenadiary.jp/entry/20250418/1744924524 NixOSでPostfixとDovecotによるメールサーバの構築
https://debslink.hatenadiary.jp/entry/20250419/1745062553 NixOSでPostfixとDovecotによるメールサーバの構築 - SASL認証編
https://debslink.hatenadiary.jp/entry/20250421/1745236668 NixOSのパッケージやOSのアップデートに関するメモ
https://debslink.hatenadiary.jp/entry/20250428/1745795434 NixOSをCLIでインストールした
https://debslink.hatenadiary.jp/entry/20250503/1746235454 NixOSでnginxによるWebサーバの構築
https://debslink.hatenadiary.jp/entry/20250508/1746706416 NixOSでPrometheusとGrafanaによる監視基盤の構築
https://debslink.hatenadiary.jp/entry/20250510/1746884897 NixOSの導入にあたり参考になったサイト
https://debslink.hatenadiary.jp/entry/20250524/1748072722 NixOSを24.11から25.05にアップデートした
https://debslink.hatenadiary.jp/entry/20251214/1765688458 NixOSを25.05から25.11にアップデートした
https://debslink.hatenadiary.jp/entry/20260117/1768615582 Raspberry Pi 4BにNixOSを導入しファイルサーバを構築した
https://debslink.hatenadiary.jp/entry/20260503/1777775392 NixOSで構築したサーバの運用について