LoginSignup
0
1

Dockerで代替DNSの動きを確認してみた

Last updated at Posted at 2023-08-07

目次

  • 経緯・確認したいこと
  • 環境
  • ネットワーク構成
  • ディレクトリ(プロジェクト)
  • Dockerfile
  • Docker Compose
  • BINDの設定
  • 検証
  • まとめ
  • お片付け

経緯・確認したいこと

先日、参加しているオンラインコミュニティで 「どのような事象だったら代替DNSにクエリー(問い合わせ)されるのか?」 という質問をいただいた。
ケースとしては二つ考えられる。

  1. 優先DNSサーバが障害でDNS応答不可
  2. 優先DNSサーバ応答ありだけど名前解決不可

Dockerのコンテナを活用して動きを確認してみることにした。

環境

  • OS: Windows 11 Pro 22H2 WSL2
  • WSL2: Ubuntu 22.04.2 LTS
  • Docker Engine:
    • Client: 24.0.4
    • Server: 24.0.4

ネットワーク構成

BINDでDNSサーバーを2台、Ubuntuのクライアントマシンを1台設置する。
Dockerfileでbind、Ubuntuのベースとなるコンテナイメージを作成し、Docker Composeでネットワークを明示的に指定する。
image.png

ディレクトリ(プロジェクト)

BINDとUbuntuごとにDockerfileを用意した。

project-bind
├── Dockerfile_bind
├── Dockerfile_ubuntu
└── docker-compose.yml

Dockerfile

Dockerfile_bind
FROM ubuntu/bind9:latest

RUN apt-get update -y
RUN apt-get install vim iputils-ping -y

BINDの設定ファイルを変更できるようにvim、ネットワーク疎通確認用にpingをインストールした。

Dockerfile_ubuntu
FROM ubuntu:latest

RUN apt-get update -y
RUN apt-get install vim iputils-ping dnsutils -y

同様にvim、ping そして名前解決確認できるようにdigも追加インストールした。

Docker Compose

docker-compose.yml
version: '3'
services:

  # BIND build
  bind-base:
    build:
      context: .
      dockerfile: Dockerfile_bind
    image: bind-base
    profiles:
      - extra

  # Ubuntu build
  ubuntu-base:
    build:
      context: .
      dockerfile: Dockerfile_ubuntu
    image: ubuntu-base
    profiles:
      - extra

  # DNSServer1(bind)
  bind01:
    image: bind-base:latest
    networks:
      fixed_compose_network:
        ipv4_address: 10.0.0.11

  # DNSServer2(bind)
  bind02:
    image: bind-base:latest
    networks:
      fixed_compose_network:
        ipv4_address: 10.0.0.12

  # Client
  Client01:
    image: ubuntu-base:latest
    tty: true
    networks:
      fixed_compose_network:
        ipv4_address: 10.0.0.20

ベースイメージはビルドのみで使用したい。そのためdocker compose up -d でコンテナ起動しないように profiles を設定した。

build

ベースイメージをビルドするコマンド。

$ docker compose --profile extra build

イメージができていることを確認する。

$ docker images
REPOSITORY    TAG       IMAGE ID       CREATED      SIZE
ubuntu-base   latest    f5752fc36de3   6 days ago   227MB
bind-base     latest    0c7378c82095   7 days ago   237MB

コンテナ起動

コンテナを起動するコマンド。

$ docker compose up -d
[+] Running 4/4
 ✔ Network bind_fixed_compose_network  Created          0.1s
 ✔ Container bind-bind01-1             Started          0.8s
 ✔ Container bind-Client01-1           Started          0.9s
 ✔ Container bind-bind02-1             Started

docker ps で3つのコンテナが実行中であることを確認する。

BINDの設定

2つのBINDにゾーンファイルを作成していく。

bind01

まずは以下コマンドでBINDコンテナにアクセスする。

docker exec -it "bind01のコンテナID" /bin/bash

vimで named.conf.default-zones を編集する。
このファイルに解決するドメインとゾーンファイルを登録する。

vim /etc/bind/named.conf.default-zones
named.conf.default-zones
zone "." {
        type hint;
        file "/usr/share/dns/root.hints";
};

// be authoritative for the localhost forward and reverse zones, and for
// broadcast zones as per RFC 1912

zone "localhost" {
        type master;
        file "/etc/bind/db.local";
};

zone "127.in-addr.arpa" {
        type master;
        file "/etc/bind/db.127";
};

zone "0.in-addr.arpa" {
        type master;
        file "/etc/bind/db.0";
};

zone "255.in-addr.arpa" {
        type master;
        file "/etc/bind/db.255";
};
// add test.pizza zone file
zone "test.pizza" {
        type master;
        file "/etc/bind/db.test.pizza";
};

登録したゾーンファイル db.test.pizza を作成する。
デフォルトで存在する db.local をコピーして作成する。

cp /etc/bind/db.local /etc/bind/db.test.pizza

コピー後はvimで編集する。

db.test.pizza
;
; BIND data file for local loopback interface
;
$TTL    604800
@       IN      SOA     ns1.test.pizza. postmaster.test.pizza. (
                              2         ; Serial
                         604800         ; Refresh
                          86400         ; Retry
                        2419200         ; Expire
                         604800 )       ; Negative Cache TTL
;
@       IN      NS      ns1.test.pizza.
ns1       IN      A       10.0.0.11
www       IN      A       10.0.0.100

BINDの設定を反映させるには named デーモンを再起動させる必要がある。
Dockerだとshell上でnamedデーモンを再起動させるとコンテナが停止しまうため
ここではshellからexitでいったん抜けて、コンテナ自体を再起動(restart)させる。

docker restart "bind01のコンテナID"

実際にDNSサーバーにクエリーを投げて名前解決できるか確認する。
クライアントのコンテナのBashにアクセスする。

docker exec -it "Clinet01のコンテナID" /bin/bash

Ubuntuの問い合わせ先DNSサーバーを指定する時は "/etc/resolv.conf"を編集する。

vim /etc/resolv.conf

nameserver に bind01のIPアドレスを指定する

/etc/resolv.conf
nameserver 10.0.0.11

設定できたら、nslookupwww.test.pizza を問い合わせをしてみる。

nslookup www.test.pizza

ゾーンファイルに登録したAレコードの結果(10.0.0.100)が表示されればクエリーの肯定応答となる。

nslookup www.test.pizza
Server:         10.0.0.11
Address:        10.0.0.11#53

Name:   www.test.pizza
Address: 10.0.0.100

bind02

bind01同様に設定していく。
今回代替DNSの動きを確認するため、Aレコードは以下のようにbind01と異なるものを登録する。

db.test.pizza
;
; BIND data file for local loopback interface
;
$TTL    604800
@       IN      SOA     ns1.test.pizza. postmaster.test.pizza. (
                              2         ; Serial
                         604800         ; Refresh
                          86400         ; Retry
                        2419200         ; Expire
                         604800 )       ; Negative Cache TTL
;
@       IN      NS      ns2.test.pizza.
ns2       IN      A       10.0.0.12
www       IN      A       10.0.0.100
www2       IN      A       10.0.0.101

クライアントにセカンダリ(代替)DNSの指定先として bind02(IP:10.0.0.12)を指定する。

resolv.conf
nameserver 10.0.0.11
nameserver 10.0.0.12

検証1: 優先DNSサーバが障害でDNS応答不可

優先DNSサーバー(bind01)の障害を見立てて、bind01コンテナを停止し、クライアントでwww.test.pizzaに問い合わせをしてみる。
bind01コンテナを停止するコマンド

docker stop "bind01のコンテナID"

クライアントで問い合わせた結果

root@client01:/# nslookup www.test.pizza
;; communications error to 10.0.0.11#53: timed out
;; communications error to 10.0.0.11#53: timed out
;; communications error to 10.0.0.11#53: timed out
Server:         10.0.0.12
Address:        10.0.0.12#53

Name:   www.test.pizza
Address: 10.0.0.100

優先DNSサーバーと通信できないためタイムアウトが表示されるが、そのあと代替えDNSに問い合わせし、肯定応答が返ってきた。
よって、優先DNSサーバーと通信(TCP/UDP53)できないときは代替DNSサーバーに問い合わせする動きを確認できた。

検証2: 優先DNSサーバ応答ありだけど名前解決不可

今度は 代替DNSサーバーだけに登録している www2.test.pizza を問い合わせして検証してみる。
停止していた優先DNSサーバー(bind01)を起動させる。

docker start "bind01のコンテナID"

クライアントで問い合わせた結果

root@client01:/# nslookup www2.test.pizza
Server:         10.0.0.11
Address:        10.0.0.11#53

** server can't find www2.test.pizza: NXDOMAIN

優先DNSサーバーにはwww2.test.pizzaのレコードがないため否定応答が返ってきて、代替DNSサーバーに再度問い合わせすることはなかった。

まとめ

  • 優先DNSサーバーが応答できない(通信できない)ときに代替DNSサーバーへ問い合わせする。
  • 優先DNSサーバーが否定応答だからといって、次のDNSサーバに問い合わせたりはしない。

お片付け

Dockerでの動きを確認できたら、検証でつかったコンテナ、イメージは以下コマンドで削除できます。

docker compose down --rmi all
0
1
1

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
1