のぴぴのメモ

自分用のLinuxとかの技術メモ

AWS環境のRHEL7/8にDNSキャッシュ(dnsmasq)を設定してみた

はじめに

AWS環境にRHEL8とRHEL7にdnsmasqを利用したDNSキャッシュを設定した時の手順メモです。ネットワーク設定にDHCPを利用している環境の場合、DHCPとの整合性を合わせる部分が鍵となります。

dnsmasqとは

Dnsmasqは軽量で比較的容易に設定できるDNSサーバのフォワーダとDHCPサーバをもつソフトウェアです(wikipediaより)。
これは私見ですが、個々のサーバでのDNSキャッシュを実現する場合、BIND9では高機能すぎるのでdnsmasqが利用されるケースが多いのではないかと思います。
詳しくは以下を参照してください。

作成する構成

RHEL8/7とも、この記事の手順を実行するとDNS解決は以下の図のような構成になります。 dnsmasqは、127.0.0.1の53番ポートでListenしており、アプリケーションがDNSゾルバ参照するときは、この127.0.0.1にアクセスするようになります。dnsmasqは、この後のRHEL7の手順でdnsmasqを構築した時のファイル名になります。RHEL8ではNetworkManagerからdbus経由で設定がdnsmasqに流し込まれるため、設定ファイルはありません。*1

f:id:nopipi:20201117015314p:plain
dnsmasqによるDNSキャッシュサーバ構成概要

RHEL8とRHEL7の違い

RHEL8とRHEL7の違いですが、RHEL8はNetworkManagerがよろしくやってくれるのでNetworkManagerの設定を一部変更するだけでdnsmasqの設定を行う必要はありませんが、RHEL7ではdnsmasqやdhcp設定を個別に設定する必要がある点が異なる点です。

RHEL8にdnsmasqを設定する

実行環境

今回は以下の環境で手順を検証しました。

  • AWSのRHEL8のインスタンスを利用
  • AMI
    • AMI ID: ami-0dc185deadd3ac449
    • AMI Name: RHEL-8.3.0_HVM-20201031-x86_64-0-Hourly2-GP2
    • Region: Tokyo(ap-northeast-1)

設定手順

dnsmasqインストールと実行ユーザ設定

dnsmasqパッケージをインストールします。

sudo yum -y install dnsmasq
NetworkManagerの設定変更

NetworkManagerの設定ファイル/etc/NetworkManager/NetworkManager.conf[main]セッションに、dns=dnsmasqを追加します。

sudo vi /etc/NetworkManager/NetworkManager.conf
  • /etc/NetworkManager/NetworkManager.conf
中略
[main]
plugins = ifcfg-rh,
#plugins=ifcfg-rh

dns=dnsmasq  #この行を追加

[logging]
以下略
再起動
sudo reboot
動作確認

digを利用してDNS参照して動作確認を行います。

(a) digコマンドのインストール
RHEL8にdigコマンドがインストールされていない場合は、bind-utilsパッケージをインストールします。

sudo yum -y install bind-utils

(b) 動作テスト
ANSWER SECTION:で問い合わせたFQDN名のDNSが解決できていること、および末尾のSERVER:で参照先のDNSゾルバが127.0.0.1であることを確認します。

dig aws.amazon.com

; <<>> DiG 9.11.20-RedHat-9.11.20-5.el8 <<>> aws.amazon.com
<中略>
;; ANSWER SECTION:
aws.amazon.com.		48	IN	CNAME	tp.8e49140c2-frontier.amazon.com.
tp.8e49140c2-frontier.amazon.com. 48 IN	CNAME	dr49lng3n1n2s.cloudfront.net.
dr49lng3n1n2s.cloudfront.net. 14 IN	A	143.204.75.74

;; Query time: 2 msec
;; SERVER: 127.0.0.1#53(127.0.0.1)
;; WHEN: Sun Nov 22 10:42:32 UTC 2020
;; MSG SIZE  rcvd: 137

RHEL7にdnsmasqを設定する

基本的には下記のAWSの記事を元にしていますが、一部手順とdnsmasq設定の見直しをしています。

実行環境

  • AWSのRHEL7のインスタンスを利用
  • AMI
    • AMI ID: ami-0e876007231767016
    • AMI Name: RHEL-7.8_HVM-20200803-x86_64-0-Hourly2-GP2
    • Region: Tokyo(ap-northeast-1)

設定手順

dnsmasqインストールと実行ユーザ設定

(a)dnsmasqのパッケージインストール
dnsmasqパッケージをインストールします。

sudo yum -y install dnsmasq

(b)dnsmasq実行ユーザ/グループ作成
この後のdnsmasq.confuser=group=で指定するdnsmasqの実行ユーザ&グループを作成します。

sudo groupadd -r dnsmasq
sudo useradd -r -g dnsmasq dnsmasq
dnsmasq設定ファイルの変更

(a) 設定ファイル(/etc/dnsmasq.conf)バックアップ

sudo mv /etc/dnsmasq.conf /tmp/dnsmasq.conf.orig

(b)設定ファイル(/etc/dnsmasq.conf)編集
テキストエディタ(viなど)で、設定ファイルを編集します。

sudo vi /etc/dnsmasq.conf

設定ファイルには以下の設定を行います。

# Server Configuration
listen-address=127.0.0.1   #local loop backでListenする
port=53
bind-interfaces    #listen-addressで指定したIPにbindを制限する
user=dnsmasq     #先ほど作成したdnsmasqの実行の専用ユーザを指定
group=dnsmasq  #先ほど作成したdnsmasq専用グループを指定
pid-file=/var/run/dnsmasq.pid

# Name resolution options
resolv-file=/etc/resolv.dnsmasq  #dnsmasqのDNSクエリー先のDNSサーバ指定
cache-size=500
domain-needed
bogus-priv

neg-ttl=60
#max-ttl=
#max-cache-ttl
#min-cache-ttl
  • dnsmasq設定のポイント
    • Listen先: listen-address=portで指定。かつbind-interfacesで指定したIPにbindを限定
    • 実行ユーザ/グループ: user=groupで指定
    • DNSクエリー先指定: resolv-file=DNSゾルバーを記載したファイルを指定。未設定の場合は/etc/resolv.confを参照。
    • キャッシュ保有期間/TTLに関する設定
      • 否定応答のキャッシュ時間指定: neg-ttl=で秒で指定。
      • 肯定応答のキャッシュ時間: 保持可能な最大時間をmax-cache-ttl=で秒で指定。(後述)
dnsmasqのDNS参照先設定(/etc/resolv.dnsmasq)

dnsmasqからのDNS参照先として、/etc/dnsmasq.confresolv-file=ファイル名で指定したファイルにdnsmasqが利用するDNSゾルバーを指定します。

DNSIP="$(awk -e '/^nameserver/{ print $2}' /etc/resolv.conf)"
echo $DNSIP

sudo bash -c "echo \"nameserver $DNSIP\" > /etc/resolv.dnsmasq"
dnsmasqサービスの有効化

(a)dnsmasqサービスの起動とOS起動時の自動起動設定

sudo systemctl restart dnsmasq.service
sudo systemctl enable dnsmasq.service

(b)dnsmasqの起動確認
プロセスが起動していること、ログにエラーがないことを確認します。

sudo systemctl status dnsmasq

● dnsmasq.service - DNS caching server.
   Loaded: loaded (/usr/lib/systemd/system/dnsmasq.service; enabled; vendor preset: disabled)
   Active: active (running) since Mon 2020-11-16 16:02:09 UTC; 8s ago
 Main PID: 13057 (dnsmasq)
    Tasks: 1 (limit: 100988)
   Memory: 792.0K
   CGroup: /system.slice/dnsmasq.service
           └─13057 /usr/sbin/dnsmasq -k

Nov 16 16:02:09 ip-10-1-64-32.ap-northeast-1.compute.internal systemd[1]: Started DNS caching server..
Nov 16 16:02:09 ip-10-1-64-32.ap-northeast-1.compute.internal dnsmasq[13057]: listening on lo(#1): 127.0.0.1
Nov 16 16:02:09 ip-10-1-64-32.ap-northeast-1.compute.internal dnsmasq[13057]: started, version 2.79 cachesize 500
Nov 16 16:02:09 ip-10-1-64-32.ap-northeast-1.compute.internal dnsmasq[13057]: compile time options: IPv6 GNU-getopt DBus no-i18n IDN2 DHCP DHCPv6 no-Lua TFTP no-conntrack ipset auth DNS>
Nov 16 16:02:09 ip-10-1-64-32.ap-northeast-1.compute.internal dnsmasq[13057]: reading /etc/resolv.dnsmasq
Nov 16 16:02:09 ip-10-1-64-32.ap-northeast-1.compute.internal dnsmasq[13057]: using nameserver 10.1.0.2#53
Nov 16 16:02:09 ip-10-1-64-32.ap-northeast-1.compute.internal dnsmasq[13057]: read /etc/hosts - 2 addresses
DHCPDNSゾルバー設定変更と反映

(a) DHCP設定ファイル更新(/etc/dhcp/dhclient.conf)
DHCPで変更するときに、dnsmasq DNS キャッシュをデフォルトの DNSゾルバーとするようして設定するよう、/etc/dhcp/dhclient.confを編集します。

sudo bash -c "echo 'supersede domain-name-servers 127.0.0.1, $DNSIP;' >> /etc/dhcp/dhclient.conf"

上記を実行すると、最初に127.0.0.1DHCPで取得し設定されていた元々のDNSゾルバーがエントリーされているはずです。

sudo cat /etc/dhcp/dhclient.conf
supersede domain-name-servers 127.0.0.1, 172.31.0.2;  <==2つのIPは環境によって変わります

(b)設定反映
dhclient コマンドを実行し、設定を反映します。(dhclientではなくrebootでも可能)

sudo dhclient
動作確認

digを利用してDNS参照して動作確認を行います。
(a) digコマンドのインストール
RHEL8にdigコマンドがインストールされていない場合は、bind-utilsパッケージをインストールします。

sudo yum -y install bind-utils

(b) 動作テスト
ANSWER SECTION:で問い合わせたFQDN名のDNSが解決できていること、および末尾のSERVER:で参照先のDNSゾルバが127.0.0.1であることを確認します。

dig aws.amazon.com

; <<>> DiG 9.11.20-RedHat-9.11.20-5.el8 <<>> aws.amazon.com
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 2564
;; flags: qr rd ra; QUERY: 1, ANSWER: 3, AUTHORITY: 0, ADDITIONAL: 1

;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags:; udp: 4096
;; QUESTION SECTION:
;aws.amazon.com.			IN	A

;; ANSWER SECTION:
aws.amazon.com.		35	IN	CNAME	tp.8e49140c2-frontier.amazon.com.
tp.8e49140c2-frontier.amazon.com. 35 IN	CNAME	dr49lng3n1n2s.cloudfront.net.
dr49lng3n1n2s.cloudfront.net. 21 IN	A	143.204.75.74

;; Query time: 3 msec
;; SERVER: 127.0.0.1#53(127.0.0.1)
;; WHEN: Mon Nov 16 16:15:02 UTC 2020
;; MSG SIZE  rcvd: 137

dnsmasqのキャッシュ保持期間

dnsmasqのキャッシュ保持期間は、dnsmasqの設定と各DNSレコードのTTL時間を評価して決定します。

  • dnsmasq設定のmax-cache-ttlとレコードのTTLいづれか小さい方の値がキャッシュ保持期間となる
  • ただし非推奨設定であるが、dnsmasq設定のmin-cache-ttlで0より大きい値を設定している場合、min-cache-ttlの設定値が最短の保持期間となる。(例えばmax-cache-ttlとレコードのTTLの評価でキャッシュ保持期間が5秒とされても、min-cache-ttl10秒であればキャシュ保持期間は10秒となる
  • max-ttl=はクライアントにレコードを渡す際にレコードに設定するTTLの最大値の設定。max-cache-ttlと同じ値を指定する。

*1: NetworkManagerから起動したdnsmasqの引数にenable-dbus=org.freedesktop.NetworkManager.dnsmasqというのがあり、これがdbus経由でdnsmasq設定が投入するためのオプションになります