RHEL9で作る自宅サーバ:dnsサーバの構築 その1

dnsサーバRHEL9パソコン自宅サーバ

dnsサーバを立ててみましょう。最近のdnsサーバはいろんな機能があるので、1回では済みそうにありません。以下のように分けて書いておこうと思います。

  • 基本的な設定で構築し動作確認
  • サーバ証明書取得機能追加
  • 迷惑 (なりすまし) メール対応機能追加
  • 権威dnsサーバのdnssec対応

基本的な設定で構築

インストールするソフトウェアは一般的なbindを使います。

また、パッケージによるchroot構成もできますが、今回は使いません。理由はSELinuxと同じで、使いにくい割に効果は今ひとつだからです。

bindは権限のないnamedユーザで起動するので、万が一bindがクラックされて侵入されたとしてもnamedユーザ権限の範囲でしかシステムをいじることができないでしょう。

[root@ace ~]# dnf install bind bind-utils
サブスクリプション管理リポジトリーを更新しています。
メタデータの期限切れの最終確認: 3:04:51 前の 2024年02月04日 17時26分53秒 に実施 しました。
依存関係が解決しました。
================================================================================
 パッケージ   Arch   バージョン          リポジトリー                     サイズ
================================================================================
インストール:
 bind         x86_64 32:9.16.23-14.el9_3 rhel-9-for-x86_64-appstream-rpms 506 k
 bind-utils   x86_64 32:9.16.23-14.el9_3 rhel-9-for-x86_64-appstream-rpms 211 k
依存関係のインストール:
 bind-dnssec-doc
              noarch 32:9.16.23-14.el9_3 rhel-9-for-x86_64-appstream-rpms  48 k
 bind-libs    x86_64 32:9.16.23-14.el9_3 rhel-9-for-x86_64-appstream-rpms 1.2 M
 bind-license noarch 32:9.16.23-14.el9_3 rhel-9-for-x86_64-appstream-rpms  13 k
 fstrm        x86_64 0.6.1-3.el9         rhel-9-for-x86_64-appstream-rpms  30 k
 libmaxminddb x86_64 1.5.2-3.el9         rhel-9-for-x86_64-appstream-rpms  36 k
 libuv        x86_64 1:1.42.0-1.el9      rhel-9-for-x86_64-appstream-rpms 153 k
 protobuf-c   x86_64 1.3.3-13.el9        rhel-9-for-x86_64-baseos-rpms     37 k
 python3-bind noarch 32:9.16.23-14.el9_3 rhel-9-for-x86_64-appstream-rpms  71 k
 python3-ply  noarch 3.11-14.el9         rhel-9-for-x86_64-appstream-rpms 111 k
弱い依存関係のインストール:
 bind-dnssec-utils
              x86_64 32:9.16.23-14.el9_3 rhel-9-for-x86_64-appstream-rpms 119 k

トランザクションの概要
================================================================================
インストール  12 パッケージ
:
省略
:
インストール済み:
  bind-32:9.16.23-14.el9_3.x86_64
  bind-dnssec-doc-32:9.16.23-14.el9_3.noarch
  bind-dnssec-utils-32:9.16.23-14.el9_3.x86_64
  bind-libs-32:9.16.23-14.el9_3.x86_64
  bind-license-32:9.16.23-14.el9_3.noarch
  bind-utils-32:9.16.23-14.el9_3.x86_64
  fstrm-0.6.1-3.el9.x86_64
  libmaxminddb-1.5.2-3.el9.x86_64
  libuv-1:1.42.0-1.el9.x86_64
  protobuf-c-1.3.3-13.el9.x86_64
  python3-bind-32:9.16.23-14.el9_3.noarch
  python3-ply-3.11-14.el9.noarch

完了しました!
[root@ace ~]#

dnfコマンドでbindとbind-utilsのパッケージをインストールします。bind-utilsにはdns関連のコマンドが入っていたんじゃないかな。

さっそく、設定ファイルの編集です。

[root@ace ~]# vi /etc/named.conf
[root@ace ~]# cat /etc/named.conf
//
// named.conf
//
// Provided by Red Hat bind package to configure the ISC BIND named(8) DNS
// server as a caching only nameserver (as a localhost DNS resolver only).
//
// See /usr/share/doc/bind*/sample/ for example named configuration files.
//

options {
        listen-on port 53 {  any; };
        listen-on-v6 port 53 {  any; };
        directory       "/var/named";
        dump-file       "/var/named/data/cache_dump.db";
        statistics-file "/var/named/data/named_stats.txt";
        memstatistics-file "/var/named/data/named_mem_stats.txt";
        secroots-file   "/var/named/data/named.secroots";
        recursing-file  "/var/named/data/named.recursing";
        allow-query     {  any; };

        /*
         - If you are building an AUTHORITATIVE DNS server, do NOT enable recursion.
         - If you are building a RECURSIVE (caching) DNS server, you need to enable
           recursion.
         - If your recursive DNS server has a public IP address, you MUST enable access
           control to limit queries to your legitimate users. Failing to do so will
           cause your server to become part of large scale DNS amplification
           attacks. Implementing BCP38 within your network would greatly
           reduce such attack surface
        */
        recursion no;
        notify no;

        dnssec-validation yes;

        managed-keys-directory "/var/named/dynamic";
        geoip-directory "/usr/share/GeoIP";

        pid-file "/run/named/named.pid";
        session-keyfile "/run/named/session.key";

        /* https://fedoraproject.org/wiki/Changes/CryptoPolicy */
        include "/etc/crypto-policies/back-ends/bind.config";
};

logging {
        channel default_debug {
                file "data/named.run";
                severity dynamic;
        };
        channel query-log {
                file "/var/log/named/query.log";
                severity dynamic;
                print-time yes;
        };
        channel update-log {
                file "/var/log/named/update.log";
                severity dynamic;
                print-time yes;
        };
        channel dnssec-log {
                file "/var/log/named/dnssec.log";
                severity dynamic;
                print-time yes;
        };
        channel security-log {
                file "/var/log/named/security.log";
                severity dynamic;
                print-time yes;
        };
        channel default-log {
                file "/var/log/named/named.log";
                severity dynamic;
                print-category yes;
                print-severity yes;
                print-time yes;
        };
        category queries { query-log; };
        category update { update-log; };
        category dnssec { dnssec-log; };
        category security { security-log; };
        category lame-servers { null; };
        category query-errors { null; };
        category default { default-log; };
};

include "/etc/named.root.key";



view "internal" {

        match-clients     { localhost; localnets; };
        allow-query       { localhost; localnets; };
        allow-recursion   { localhost; localnets; };
        allow-query-cache { localhost; localnets; };
        allow-transfer    { localhost; localnets; };
        recursion yes;

        zone "." IN {
                type hint;
                file "named.ca";
        };

        zone "zeke.ne.jp" {
                type master;
                file "internal/zeke.ne.jp.zone";
        };
:
略
:
        zone "0.0.a.c.3.0.d.c.0.c.2.0.1.0.0.2.ip6.arpa" {
                type master;
                file "internal/zeke.ne.jp.rev6";
        };

        zone "1.168.192.in-addr.arpa" {
                type master;
                file "internal/zeke.ne.jp.rev";
        };

        include "/etc/named.rfc1912.zones";
};

view "external" {
        match-clients     { any; };
        allow-query       { any; };
        allow-recursion   { none; };
        allow-query-cache { none; };
        allow-transfer    { none; };
        recursion no;

        zone "." IN {
                type hint;
                file "named.ca";
        };

        zone "zeke.ne.jp" {
                type master;
                file "external/zeke.ne.jp.zone";
        };
:
略
:
};

[root@ace ~]#

optionsステートメントでは「listen-on port 53 { any; };」「listen-on-v6 port 53 { any; };」「allow-query { any; };」を変更してます。誰からでの問い合わせを受ける!

また「recursion no;」として、再帰問い合わせを行わないにしてます。yesだと自分で管理していないドメインに対してもIPアドレスを調べてくれるようになります。

セカンダリDNSにzone情報を素早く同期するためにnotifyの仕組みがありますが、ここではセカンダリDNSはないため「notify no;」とし余計な通知は出さないようにしています。
セカンダリDNSがあったとしても必要なzoneだけ「notify yes;」にするのが良いと思います。

loggingステートメントではログをいっぱい出すように変更しました。chrootをかけてると/var/logにログをはけないと思います。また、後でインストールするfail2banのためにsecurity.logの出力を合わせています。のちに不正アクセスっぽい通信を遮断する予定です。

viewステートメントで、内部向けと外部向けの定義を分けています。これは内部向けにはプライベートIPアドレスを外部向けにはグローバルIPアドレスを返答するためです。IPv6みたいにみんなグローバルアドレスだったら分ける必要がないのに。面倒ですよね。

また、各viewにhintファイルが必要みたいです。external viewにはhintファイルは必要ないのですが、定義しないと内部で持っているhintファイルが使われるようで、

14-Feb-2024 21:50:59.249 general: warning: checkhints: view external: b.root-servers.net/A (170.247.170.2) missing from hints
14-Feb-2024 21:50:59.249 general: warning: checkhints: view external: b.root-servers.net/A (199.9.14.201) extra record in hints
14-Feb-2024 21:50:59.249 general: warning: checkhints: view external: b.root-servers.net/AAAA (2801:1b8:10::b) missing from hints
14-Feb-2024 21:50:59.249 general: warning: checkhints: view external: b.root-servers.net/AAAA (2001:500:200::b) extra record in hints

のような警告メッセージが出ます。

内部向けは「match-clients { localhost; localnets; };」で内部ネットワーク限定にして、「recursion yes;」再帰問い合わせ有り、「allow-query」「allow-recursion」「allow-query-cache」も許可にしてます。

また、各ゾーンファイルは以下の通り

[root@ace ~]# cat /var/named/internal/zeke.ne.jp.zone
$TTL    3600
@       IN      SOA     ns.zeke.ne.jp. root.ns.zeke.ne.jp. (
                        2021121401      ; Serial
                        3600            ; Refresh after 1 hour
                        600             ; Retry after 10 minute
                        1209600         ; Expire after 2 weeks
                        3600    )       ; Minimum TTL of 1 hour
;
        86400   IN      NS      ns.zeke.ne.jp.
        86400   IN      NS      joeker.zeke.ne.jp.
;
        IN      A       192.168.1.4
        IN      AAAA    2001:2c0:cd03:ca00::4
        IN      MX      10      mail.zeke.ne.jp.
;
ns      IN      A       192.168.1.4
        IN      AAAA    2001:2c0:cd03:ca00::4
        IN      MX      10      mail.zeke.ne.jp.
;
joeker  IN      A       192.168.1.4
        IN      AAAA    2001:2c0:cd03:ca00::4
        IN      MX      10      mail.zeke.ne.jp.
;
mail    IN      A       192.168.1.4
        IN      MX      10      mail.zeke.ne.jp.
;
www     IN      CNAME   ns
irc     IN      CNAME   ns
ftp     IN      CNAME   ns
redh    IN      CNAME   ns
shoot   IN      CNAME   ns
blog    IN      CNAME   ns
matomo  IN      CNAME   ns
info    IN      CNAME   ns
*.info  IN      CNAME   ns
;
myhome  IN      A       192.168.1.4
        IN      AAAA    2001:2c0:cd03:ca00::4
;
ace     IN      A       192.168.1.1
        IN      AAAA    2001:2c0:cd03:ca00::ace
[root@ace ~]# cat /var/named/internal/zeke.ne.jp.rev
$TTL    86400
@       IN      SOA     ns.zeke.ne.jp. root.ns.zeke.ne.jp. (
                                2021120901      ; Serial
                                3600            ; Refresh after 1 hour
                                600             ; Retry after 1 minute
                                1209600         ; Expire after 1 weeks
                                86400 )         ; Minimum TTL of 1 day
        IN      NS      ns.zeke.ne.jp.
        IN      NS      joeker.zeke.ne.jp.
;
1       IN      PTR     ace.zeke.ne.jp.
2       IN      PTR     vm.zeke.ne.jp.
3       IN      PTR     ara.zeke.ne.jp.
4       IN      PTR     myhome.zeke.ne.jp.
[root@ace ~]# cat /var/named/internal/zeke.ne.jp.rev6
$TTL    86400
$ORIGIN 0.0.a.c.3.0.d.c.0.c.2.0.1.0.0.2.ip6.arpa.
@       IN      SOA     ns.zeke.ne.jp. root.ns.zeke.ne.jp. (
                                2021120901      ; Serial
                                3600            ; Refresh after 1 hour
                                600             ; Retry after 1 minute
                                1209600         ; Expire after 1 weeks
                                86400 )         ; Minimum TTL of 1 day
        IN      NS      ns.zeke.ne.jp.
        IN      NS      joeker.zeke.ne.jp.
;
$ORIGIN 0.0.0.0.0.0.0.0.0.0.0.0.0.0.a.c.3.0.d.c.0.c.2.0.1.0.0.2.ip6.arpa.
;
e.c.a.0 IN      PTR     ace.zeke.ne.jp.
2.0.0.0 IN      PTR     vm.zeke.ne.jp.
3.0.0.0 IN      PTR     ara.zeke.ne.jp.
4.0.0.0 IN      PTR     myhome.zeke.ne.jp.

もっとたくさんホストは定義してありますが、省略です。ポイントとしてネームサーバとメールサーバはAレコードで明示的にIPアドレスを書いておかないといけなかったと思います。

内部向けは、ローカルな独自ドメインzeke.ne.jpに逆引きの設定も入れてます。

viewセクションで外部向けは「match-clients { any; };」でどこからの問い合わせもOK!、「recursion no;」で再帰問い合わせなし、「allow-query」は許可、「allow-recursion」「allow-query-cache」は不許可にしてます。

[root@ace ~]# cat /var/named/external/zeke.ne.jp.zone
$TTL    3600
@       IN      SOA     ns.zeke.ne.jp. root.mail.zeke.ne.jp. (
                        2021121401      ; Serial
                        3600            ; Refresh after 1 hour
                        600             ; Retry after 10 minute
                        1209600         ; Expire after 2 weeks
                        3600    )       ; Minimum TTL of 1 hour
;
        IN      NS      ns.zeke.ne.jp.
        IN      NS      joeker.zeke.ne.jp.
;
        IN      A       203.152.220.46
        IN      AAAA    2001:2c0:cd03:ca00:0:0:0:4
        IN      MX      10      mail.zeke.ne.jp.
;
ns      IN      A       203.152.220.46
        IN      AAAA    2001:2c0:cd03:ca00:0:0:0:4
        IN      MX      10      mail.zeke.ne.jp.
;
joeker  IN      A       203.152.220.46
        IN      AAAA    2001:2c0:cd03:ca00:0:0:0:4
        IN      MX      10      mail.zeke.ne.jp.
;
mail    IN      A       203.152.220.46
        IN      MX      10      mail.zeke.ne.jp.
;
www     IN      CNAME   ns
irc     IN      CNAME   ns
ftp     IN      CNAME   ns
redh    IN      CNAME   ns
shoot   IN      CNAME   ns
blog    IN      CNAME   ns
matomo  IN      CNAME   ns
info    IN      CNAME   ns
*.info  IN      CNAME   ns
;
myhome  IN      A       203.152.220.46
        IN      AAAA    2001:2c0:cd03:ca00:0:0:0:4
;
ace     IN      AAAA    2001:2c0:cd03:ca00:0:0:0:ace

再帰問い合わせなしなので、このゾーンの内容しか返答しません。

ディレクトリ、ファイルの権限変更

chrootを使わないので、各ファイルの権限はちゃんとチェックしておきましょう。

[root@ace ~]# ls -l /etc/named.conf
-rw-r----- 1 root named 3728  2月  4 21:11 /etc/named.conf
[root@ace ~]# 
[root@ace ~]# ls -alR /var/named/internal/
/var/named/internal/:
合計 28
drwxr-x--- 2 root named  146  2月  4 21:20 .
drwxrwx--T 7 root named  159  2月  4 21:29 ..
-rw-r----- 1 root named 3057  2月  4 21:20 zeke.ne.jp.rev
-rw-r----- 1 root named  907  2月  4 21:20 zeke.ne.jp.rev6
-rw-r----- 1 root named 5297  2月  4 21:20 zeke.ne.jp.zone
:
[root@ace ~]#
[root@ace ~]# ls -alR /var/named/external/
/var/named/external/:
合計 16
drwxr-x--- 2 root named  101  2月  4 21:33 .
drwxrwx--T 7 root named  159  2月  4 21:29 ..
-rw-r----- 1 root named 2778  2月  4 21:33 zeke.ne.jp.zone
:
[root@ace ~]#
[root@ace ~]# mkdir /var/log/named/
[root@ace ~]# chown named:named /var/log/named/
[root@ace ~]# ls -alR /var/log/named/
/var/log/named/:
合計 4
drwxr-xr-x  2 named named    6  2月  4 21:56 .
drwxr-xr-x 10 root  root  4096  2月  4 21:56 ..
:
[root@ace ~]#

「/etc/named.conf」は秘密情報が入るので、rootは読み書きnamedユーザ読むだけにしています。ゾーンファイルやそのディレクトリは、公開情報しか書かれていませんが、同様にrootは読み書きnamedユーザ読むだけです。

ログディレクトリは、namedユーザで書き込めるようにしておきましょう。

動作確認

[root@ace ~]# named-checkconf /etc/named.conf
[root@ace ~]#
[root@ace ~]# named-checkzone "zeke.ne.jp" /var/named/internal/zeke.ne.jp.zone
zone zeke.ne.jp/IN: loaded serial 2021121401
OK
[root@ace ~]# named-checkzone "0.0.a.c.3.0.d.c.0.c.2.0.1.0.0.2.IP6.ARPA" /var/named/internal/zeke.ne.jp.rev6
zone 0.0.a.c.3.0.d.c.0.c.2.0.1.0.0.2.IP6.ARPA/IN: loaded serial 2021120901
OK
[root@ace ~]# named-checkzone "0.0.a.c.3.0.d.c.0.c.2.0.1.0.0.2.IP6.ARPA" /var/named/internal/zeke.ne.jp.rev6
zone 0.0.a.c.3.0.d.c.0.c.2.0.1.0.0.2.IP6.ARPA/IN: loaded serial 2021120901
OK
[root@ace ~]# named-checkzone "zeke.ne.jp" /var/named/external/zeke.ne.jp.zone
zone zeke.ne.jp/IN: loaded serial 2021121401
OK
[root@ace ~]#

まずは、「/etc/named.conf」とゾーンファイルのチェックです。ほとんど現行からのコピーなので問題ありませんね。

[root@ace ~]# systemctl is-enabled named
disabled
[root@ace ~]# systemctl enable named
Created symlink /etc/systemd/system/multi-user.target.wants/named.service → /usr/lib/systemd/system/named.service.
[root@ace ~]# systemctl start named
[root@ace ~]# systemctl status named
● named.service - Berkeley Internet Name Domain (DNS)
     Loaded: loaded (/usr/lib/systemd/system/named.service; enabled; preset: di>
     Active: active (running) since Sun 2024-02-04 22:03:03 JST; 7s ago
    Process: 2914 ExecStartPre=/bin/bash -c if [ ! "$DISABLE_ZONE_CHECKING" == >
    Process: 2916 ExecStart=/usr/sbin/named -u named -c ${NAMEDCONF} $OPTIONS (>
   Main PID: 2917 (named)
      Tasks: 6 (limit: 23114)
     Memory: 32.4M
        CPU: 96ms
     CGroup: /system.slice/named.service
             mq2917 /usr/sbin/named -u named -c /etc/named.conf

 2月 04 22:03:03 ace.zeke.ne.jp named[2917]: automatic empty zone: view interna>
 2月 04 22:03:03 ace.zeke.ne.jp named[2917]: automatic empty zone: view interna>
 2月 04 22:03:03 ace.zeke.ne.jp named[2917]: automatic empty zone: view interna>
 2月 04 22:03:03 ace.zeke.ne.jp named[2917]: automatic empty zone: view interna>
 2月 04 22:03:03 ace.zeke.ne.jp named[2917]: set up managed keys zone for view >
 2月 04 22:03:03 ace.zeke.ne.jp named[2917]: configuring command channel from '>
 2月 04 22:03:03 ace.zeke.ne.jp named[2917]: command channel listening on 127.0>
 2月 04 22:03:03 ace.zeke.ne.jp named[2917]: configuring command channel from '>
 2月 04 22:03:03 ace.zeke.ne.jp named[2917]: command channel listening on ::1#9>
 2月 04 22:03:03 ace.zeke.ne.jp systemd[1]: Started Berkeley Internet Name Doma>
[root@ace ~]#

「systemctl is-enabled named」コマンドで、自動起動が無効になっていることを確認したので、「systemctl enable named」コマンドで有効にしておきます。

「systemctl start named」コマンドでbindを起動、「systemctl status named」コマンドでステータスを確認。「active (running)」とあるので、無事起動しています。

[root@ace ~]# nslookup
> server 127.0.0.1
Default server: 127.0.0.1
Address: 127.0.0.1#53
> ns.zeke.ne.jp
Server:         127.0.0.1
Address:        127.0.0.1#53

Name:   ns.zeke.ne.jp
Address: 192.168.1.4
Name:   ns.zeke.ne.jp
Address: 2001:2c0:cd03:ca00::4
> server ::1
Default server: ::1
Address: ::1#53
> ns.zeke.ne.jp
Server:         ::1
Address:        ::1#53

Name:   ns.zeke.ne.jp
Address: 192.168.1.4
Name:   ns.zeke.ne.jp
Address: 2001:2c0:cd03:ca00::4
> google.com
Server:         ::1
Address:        ::1#53

Non-authoritative answer:
Name:   google.com
Address: 142.250.207.14
Name:   google.com
Address: 2404:6800:4004:820::200e
> exit

[root@ace ~]#

「nslookup」コマンドで、ns.zeke.ne.jpのホスト名からIPアドレスが引けるかを確認します。IPv4&IPv6ともに大丈夫なようですね。

外部のドメイン google.comも引けるので、再帰問い合わせが有効であることも確認できました。

Firewallの設定変更

[root@ace ~]# firewall-cmd --list-all
public (active)
  target: default
  icmp-block-inversion: no
  interfaces: enp0s3
  sources:
  services: ssh
  ports:
  protocols:
  forward: yes
  masquerade: no
  forward-ports:
  source-ports:
  icmp-blocks:
  rich rules:
[root@ace ~]# firewall-cmd --permanent --add-service=dns
success
[root@ace ~]# firewall-cmd --reload
success
[root@ace ~]# firewall-cmd --list-all
public (active)
  target: default
  icmp-block-inversion: no
  interfaces: enp0s3
  sources:
  services: dns ssh
  ports:
  protocols:
  forward: yes
  masquerade: no
  forward-ports:
  source-ports:
  icmp-blocks:
  rich rules:
[root@ace ~]#

「firewall-cmd –permanent –add-service=dns」コマンドで、ファイヤーウォールにdnsサービスが疎通できるように穴を開けときます。ただし、まだルータの設定を変更していないので、外部からの問い合わせには答えられませんが。

お勧めのKindle本です!

コメント