お金をかけずにサーバーの勉強をしよう

名前解決(DNSではないところ)

2023年10月19日

メニューへ戻る

サーバー名から IPアドレスへの変換を名前解決と言います。

ちょっとネットワークに踏み込んだ話ではありますが、サーバー名から IPアドレスに変換する仕組みについての理解はサーバーエンジニアの必須科目です。

名前解決というと、まず最初に出てくるのは DNS(Domain Nmae Service/Server)ですけど、ここではそれではなくて、Linux環境でどういう仕組みで名前解決をしているかについて触れてみようかと。

そんなに難しいものではないので「他のサーバーに通信できない!」という障害のケースで、この辺りを探ってみてはいかがか?という話です。


まず名前解決それ自体について。

例えば私がここでよく使う Ubuntu Server 22.04の仮想OSには、

零号機UbuntuServer2204
初号機UbuntuServer2204-1
弐号機UbuntuServer2204-2

なんてマシン名にしています。

また、このホームページは [https://subro.mokuren.ne.jp] って URLになっています。
このうち [subro.mokuren.ne.jp] が FQDN(Fully Qualified Domain Name)となっています。

[mokuren.ne.jp] ドメインに所属している [subro]サーバーということになりますね。
(実際はさくらインターネットの Apacheあたりに定義された仮想サーバーですが)

これらと実際に通信するにあたっては、OSの裏の方ではこのような名前ではなく IPアドレスを使ってやってるんですが、それ故にどこかしらで個々の名前と IPアドレスを紐付けておく必要があります。
この紐付けられた情報(データベース)にアクセスするのが名前解決のアクションと言って良いと思います。

Ubuntu 22.04での仕組みについて書きますが、RHEL系・その他の Linux OSでもそんなに変わらないはずです。


1.アプリケーションが名前解決をスタートする

分かりやすい所では WEBブラウザがそうですが、黒い画面のコマンドなんかも同じです。

但し全てのアプリやコマンドがこれに沿っている訳ではないので注意が必要ですが、沿っていないのは特殊なケースと捉えておいて良いと思います。


2.共通ライブラリが [/etc/nsswitch.conf] を見る

C言語の話になっちゃいますが、OSの一部と言っても良い glibcという共有ライブラリの関数が使われて、[/etc/nsswitch.conf]ファイルが参照されます。

このファイルには、名前解決その他の情報取得先のファイル名やサービス名が書いてあります。

これは Lubuntu 22.04.3の [/etc/nsswitch.conf]ファイルです。

# /etc/nsswitch.conf
#
# Example configuration of GNU Name Service Switch functionality.
# If you have the `glibc-doc-reference' and `info' packages installed, try:
# `info libc "Name Service Switch"' for information about this file.

passwd:         files systemd
group:          files systemd
shadow:         files
gshadow:        files

hosts:          files mdns4_minimal [NOTFOUND=return] dns
networks:       files

protocols:      db files
services:       db files
ethers:         db files
rpc:            db files

netgroup:       nis

[hots:] で始まるピンク行が名前解決のための行です。
参照対象を順序を含めて羅列しています。(左が優先)

これらが対象で、上から順に参照し、対象のホスト名のIPアドレスが見つかったら終わりです。

files[/etc/hosts]ファイル
mdns4_minimalMulticast DNS(IPv4のみアドレス解決 + 対象絞り込み)
[NOTFOUND=return] で見つからない場合は次の方法に行く
dnsDNSサーバーを使う



3.[files] は [/etc/hosts]ファイルを見る

一番最初に参照されるのが [files] で、具体的には [/etc/hosts]ファイルを見に行きます。

これは私の Lubuntu 22.04.3の [/etc/hosts]ファイルです。

# Host addresses
127.0.0.1  localhost
127.0.1.1  Lubuntu2204

192.168.1.101 Rocky-1 Rocky-1.local
192.168.1.102 localstack
192.168.1.103 selenium
192.168.1.105 UbuntuServer2204-1
192.168.1.200 raspberrypi

::1        localhost ip6-localhost ip6-loopback
ff02::1    ip6-allnodes
ff02::2    ip6-allrouters

左に IPアドレス、間にスペースかタブ、右にホスト名かFQDNをスペース区切りで羅列できます。

実際のホスト名と違っていても動きます。
(あくまでアプリケーション利用者がどういう名前で相手のサーバーを呼んでいるか、ということです。)

ここに対象のマシン名があれば、紐付いた IPアドレスをアプリケーションに返して終わります。

※「127.0.1.1 Lubuntu2204」って自分のマシン名のIPアドレスが [127.0.1.1]になっているんですが、これには特に意味は無くて、インストール時に何かしら割り当てないといけないからこれになってるんだそうな。
やる必要は無さげですが、IPアドレスを本来のものに変えておいた方が良いのかも知れません。


4.[mdns4_minimal] は MACの文化

mDNS(multicast DNS)は、もともと MACで使われていたものだそうです。

PCが相手を探すためにネットワーク内に一斉発信して、該当の PCが呼応するというもので、DNSサーバーを立てなくても名前解決ができちゃいます。

この一斉発信が「multicast」です。

Ubuntu 22.04では avahi-deamon(The Avahi mDNS/DNS-SD daemon)という常駐プログラムがこの役割を担っています。

subro@Lubuntu2204:~$ ps -ef | grep avahi
avahi        736       1  0 11:30 ?        00:00:05 avahi-daemon: running [Lubuntu2204.local]
avahi        790     736  0 11:30 ?        00:00:00 avahi-daemon: chroot helper
subro       5448    3619  0 13:03 pts/0    00:00:00 grep --color=auto avahi

これで対象のマシンが呼応して IPアドレスを返してくれれば終わります。


5.[dns] は DNSサーバーに問い合わせに行く

これは特に説明がいらないと思います。

ネットワークインターフェイスに IPアドレスの設定をした時に DNSサーバーの IPアドレスを入れたと思いますので、その IPアドレス宛に名前解決を依頼する形になります。

DHCPで自動設定している場合は、DHCPサーバーが渡してくれた DNSサーバーの IPアドレスに行きます。

resolvectl(Resolve domain names, IPV4 and IPv6 addresses, DNS resource records, and services; introspect and reconfigure the DNS resolver )コマンドで、現在の DNS周りの設定を見ることができます。

subro@Lubuntu2204:~$ resolvectl status
Global
       Protocols: -LLMNR -mDNS -DNSOverTLS DNSSEC=no/unsupported
resolv.conf mode: stub

Link 2 (ens33)
    Current Scopes: DNS
         Protocols: +DefaultRoute +LLMNR -mDNS -DNSOverTLS DNSSEC=no/unsupported
Current DNS Server: 192.168.1.1
       DNS Servers: 192.168.1.1 xxxx:xxxx:xxxx:xxxx:xxxx:xxxx:xxxx:xxxx
        DNS Domain: xxxxxxx.jp xxxxx.jp

systemd-resolved(Network Name Resolution manager)という常駐プログラムがこの役割を担っています。

subro@Lubuntu2204:~$ ps -ef | grep systemd-resolved
systemd+     678       1  0 11:30 ?        00:00:01 /lib/systemd/systemd-resolved
subro       5658    3619  0 13:19 pts/0    00:00:00 grep --color=auto systemd-resolved

systemd-resolvedはそんなに新しいものではないですが、デフォ使われるようになったのは最近の Linux OSからで、以前は [/etc/resolv.conf]ファイルを参照していました。

systemd-resolvedはスタブリゾルバ(DNSクライアント)と呼ばれていて、[127.0.0.53/udp][127.0.0.53/tcp]という、PC内部でだけ参照できる IPアドレスを使っていますので、アプリケーションから DNSでの名前解決を依頼された OSがこのアドレスにアクセスするんでしょう。

subro@Lubuntu2204:~$ ss -atup | egrep "Netid|domain"
Netid State     Recv-Q Send-Q                    Local Address:Port            Peer Address:Port  Process
udp   UNCONN    0      0                         127.0.0.53%lo:domain               0.0.0.0:*
tcp   LISTEN    0      4096                      127.0.0.53%lo:domain               0.0.0.0:*


==========
駆け足になってしまいましたが、私も少しお勉強しながら書きました。

特に最後の systemd-resolvedについては、知識のアップデートが必要だなぁと思いましたね。

新しい名前解決の方法に対応したものだそうですので、DNSだけではなく他の新技術にも対応しているのでしょう。

サーバーエンジニアには日々のお勉強が大切だなぁ…と思いましたです。


systemdを全面に出した本はこれ以来みた事がありません。
2015年刊ですので、随分古くなってしまいました。
(今でも十分使えますが)