localhostと127.0.0.1の差異があんまりわからないので、川口が気になる点を調査してみた
まずは検証して、最後は結論をまとめていこうかと思う。
検証部分を飛ばして、最後の結論だけみてもOK
気になる点:
■ localhostと127.0.0.1がDNSで正引き、逆引きできるのか
■ DNSサーバを指定しない場合、digできるのか
■ DNSサーバを指定しないままで、pingとるのか
■ localhostと127.0.0.1への通信がnicを経由するのか
■「/etc/resolv.conf」と「/etc/hosts」両方設定されている場合、pingがどっちを参照する
localhostと127.0.0.1がDNSで正引き、逆引きできるのか
■DNSサーバを皆さんが大好きな「8.8.8.8」にして、digしてみよう
結果
正引き:NG
逆引き:NG
[root@test9-1 ~]# nmcli c mod ens34 ipv4.dns 8.8.8.8
[root@test9-1 ~]# nmcli c u ens34
[root@test9-1 ~]# cat /etc/resolv.conf
# Generated by NetworkManager
nameserver 8.8.8.8
正引き:NG
[root@test9-1 ~]# dig localgost
; <<>> DiG 9.16.23-RH <<>> localgost
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NXDOMAIN, id: 43303
;; flags: qr rd ra ad; QUERY: 1, ANSWER: 0, AUTHORITY: 1, ADDITIONAL: 1
;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags:; udp: 512
;; QUESTION SECTION:
;localgost. IN A
;; AUTHORITY SECTION:
. 86399 IN SOA a.root-servers.net. nstld.verisign-grs.com. 2024020703 1800 900 604800 86400
;; Query time: 7 msec
;; SERVER: 8.8.8.8#53(8.8.8.8)
;; WHEN: Thu Feb 08 11:12:38 JST 2024
;; MSG SIZE rcvd: 113
逆引き:NG
[root@test9-1 ~]# dig -x 127.0.0.1
; <<>> DiG 9.16.23-RH <<>> -x 127.0.0.1
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NXDOMAIN, id: 27902
;; flags: qr rd ra ad; QUERY: 1, ANSWER: 0, AUTHORITY: 1, ADDITIONAL: 1
;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags:; udp: 512
;; QUESTION SECTION:
;1.0.0.127.in-addr.arpa. IN PTR
;; AUTHORITY SECTION:
in-addr.arpa. 1506 IN SOA b.in-addr-servers.arpa. nstld.iana.org. 2022093272 1800 900 604800 3600
;; Query time: 4 msec
;; SERVER: 8.8.8.8#53(8.8.8.8)
;; WHEN: Thu Feb 08 11:16:08 JST 2024
;; MSG SIZE rcvd: 119
■DNSサーバをISPのにする場合
結果
正引き:OK
逆引き:OK
DNSサーバを「192.168.1.1」にする
[root@test9-1 ~]# nmcli c mod ens34 ipv4.dns 192.168.1.1
[root@test9-1 ~]# nmcli c u ens34
接続が正常にアクティベートされました (D-Bus アクティブパス: /org/freedesktop/NetworkManager/ActiveConnection/4)
[root@test9-1 ~]#
[root@test9-1 ~]#
[root@test9-1 ~]#
[root@test9-1 ~]#
[root@test9-1 ~]# cat /etc/resolv.conf
# Generated by NetworkManager
nameserver 192.168.1.1
正引き:OK
[root@test9-1 ~]# dig localhost
; <<>> DiG 9.16.23-RH <<>> localhost
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 38627
;; flags: qr aa rd ra ad; QUERY: 1, ANSWER: 1, AUTHORITY: 0, ADDITIONAL: 0
;; QUESTION SECTION:
;localhost. IN A
;; ANSWER SECTION:
localhost. 0 IN A 127.0.0.1
;; Query time: 1 msec
;; SERVER: 192.168.1.1#53(192.168.1.1)
;; WHEN: Thu Feb 08 11:13:10 JST 2024
;; MSG SIZE rcvd: 43
逆引き:OK
[root@test9-1 ~]# dig -x 127.0.0.1
; <<>> DiG 9.16.23-RH <<>> -x 127.0.0.1
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 36283
;; flags: qr aa rd ra ad; QUERY: 1, ANSWER: 1, AUTHORITY: 0, ADDITIONAL: 0
;; QUESTION SECTION:
;1.0.0.127.in-addr.arpa. IN PTR
;; ANSWER SECTION:
1.0.0.127.in-addr.arpa. 0 IN PTR localhost.localdomain.
;; Query time: 0 msec
;; SERVER: 192.168.1.1#53(192.168.1.1)
;; WHEN: Thu Feb 08 11:15:33 JST 2024
;; MSG SIZE rcvd: 75
[root@test9-1 ~]#
DNSサーバを指定しない場合、digできるのか
結果:「connection timed out; no servers could be reached」になって、NG
DNSサーバを削除する
[root@test9-1 ~]# nmcli c mod ens34 ipv4.dns ""
[root@test9-1 ~]#
[root@test9-1 ~]#
[root@test9-1 ~]#
[root@test9-1 ~]# nmcli c u ens34
接続が正常にアクティベートされました (D-Bus アクティブパス: /org/freedesktop/NetworkManager/ActiveConnection/6)
[root@test9-1 ~]#
[root@test9-1 ~]#
[root@test9-1 ~]#
[root@test9-1 ~]# cat /etc/resolv.conf
# Generated by NetworkManager
正引き:NG
(逆引きの同じだと思われ、やってない)
[root@test9-1 ~]# dig localhost
; <<>> DiG 9.16.23-RH <<>> localhost
;; global options: +cmd
;; connection timed out; no servers could be reached
[root@test9-1 ~]#
DNSサーバを指定しないままで、pingとるのか
結果:OK
[root@test9-1 ~]# ping -c 1 localhost
PING localhost (127.0.0.1) 56(84) bytes of data.
64 バイト応答 送信元 localhost (127.0.0.1): icmp_seq=1 ttl=64 時間=0.018ミリ秒
--- localhost ping 統計 ---
送信パケット数 1, 受信パケット数 1, 0% packet loss, time 0ms
rtt min/avg/max/mdev = 0.018/0.018/0.018/0.000 ms
straceで見てみよう。
これで、pingは「/etc/hosts」を参照していることがわかった
抜粋
newfstatat(AT_FDCWD, "/etc/resolv.conf", {st_mode=S_IFREG|0644, st_size=30, ...}, 0) = 0
newfstatat(AT_FDCWD, "/etc/nsswitch.conf", {st_mode=S_IFREG|0644, st_size=2124, ...}, 0) = 0
openat(AT_FDCWD, "/etc/hosts", O_RDONLY|O_CLOEXEC) = 4
newfstatat(4, "", {st_mode=S_IFREG|0644, st_size=158, ...}, AT_EMPTY_PATH) = 0
lseek(4, 0, SEEK_SET) = 0
read(4, "127.0.0.1 localhost localhost."..., 4096) = 158
close(4) = 0
write(1, "64 \343\203\220\343\202\244\343\203\210\345\277\234\347\255\224 \351\200\201\344\277\241\345\205\203 loc"..., 9264 バイト応答 送信元 localhost (127.0.0.1): icmp_seq=1 ttl=64 時間=0.079ミリ秒
じゃあ、「/etc/hosts」のをコメントアウトされた場合は、どうなるのか
とったぞ
straceで確認してみると、別のファイルを参照せず、かえってきた
(pingの中で固定されているかも、ソースはみていない)
[root@test9-1 ~]# cat /etc/hosts
#127.0.0.1 localhost localhost.localdomain localhost4 localhost4.localdomain4
#::1 localhost localhost.localdomain localhost6 localhost6.localdomain6
[root@test9-1 ~]#
[root@test9-1 ~]# ping -c 1 localhost
PING localhost (127.0.0.1) 56(84) bytes of data.
64 バイト応答 送信元 localhost (127.0.0.1): icmp_seq=1 ttl=64 時間=0.015ミリ秒
--- localhost ping 統計 ---
送信パケット数 1, 受信パケット数 1, 0% packet loss, time 0ms
localhostと127.0.0.1への通信がnicを経由するのか
「lo」もnicなのか微妙かもしれないけど、ICMPのrequestとreplyはちゃんと出た
[root@test9-1 ~]# tcpdump -i lo icmp
11:48:36.798475 IP localhost > localhost: ICMP localhost udp port domain unreachable, length 63
11:48:36.798482 IP localhost > localhost: ICMP localhost udp port domain unreachable, length 63
11:48:36.798497 IP localhost > localhost: ICMP localhost udp port domain unreachable, length 63
11:48:36.798501 IP localhost > localhost: ICMP localhost udp port domain unreachable, length 63
11:48:36.798691 IP localhost > localhost: ICMP localhost udp port domain unreachable, length 76
11:48:36.798705 IP localhost > localhost: ICMP localhost udp port domain unreachable, length 76
11:48:36.798792 IP localhost > localhost: ICMP echo request, id 10, seq 1, length 64
11:48:36.798794 IP localhost > localhost: ICMP echo reply, id 10, seq 1, length 64
11:48:36.798832 IP localhost > localhost: ICMP localhost udp port domain unreachable, length 76
11:48:36.798844 IP localhost > localhost: ICMP localhost udp port domain unreachable, length 76
11:48:37.822668 IP localhost > localhost: ICMP echo request, id 10, seq 2, length 64
11:48:37.822677 IP localhost > localhost: ICMP echo reply, id 10, seq 2, length 64
11:48:37.822760 IP localhost > localhost: ICMP localhost udp port domain unreachable, length 76
11:48:37.822777 IP localhost > localhost: ICMP localhost udp port domain unreachable, length 76
ここで、予想外のパケット(localhost udp port domain unreachable)が出てきた。
「tcpdump」の後ろに「-vvv」を付け、「wireshark」で解析してみると、
DNSサーバを指定せず、「/etc/hosts」にもない場合、「ping localhost」を実行すると、自分自身に対するDNS問い合わせ処理がある
処理流れ:
①自分自身のUDP53ポートに、localhostのAレコードを引く
②自分自身がDNSサーバではなく、UDP53ポートがあっていないため、「Destination unreachable (Port unreachable)」で返す
③①と同じくAAAレコードも引いて、②がはしる
④①②③はもう一回実行
⑤A/AAAレコードを引くのが終わって、ICMPの処理開始
⑥まだ①と同じで、今度は127.0.0.1の逆引きを引く
⑦②と同じ、「Destination unreachable (Port unreachable)」で返す
⑧⑥⑦もう一回実行
⑨終わり
「/etc/resolv.conf」と「/etc/hosts」両方設定されている場合、pingがどっちを参照する
DNSサーバを「8.8.8.8」にして、「www.yahoo.co.jp」をpingしてみよう
[root@test9-1 ~]# nmcli c mo ens34 ipv4.dns 8.8.8.8
[root@test9-1 ~]# nmcli c u ens34
接続が正常にアクティベートされました (D-Bus アクティブパス: /org/freedesktop/NetworkManager/ActiveConnection/7)
[root@test9-1 ~]#
[root@test9-1 ~]# ping -c 1 www.yahoo.co.jp
PING edge12.g.yimg.jp (182.22.16.123) 56(84) bytes of data.
64 バイト応答 送信元 182.22.16.123 (182.22.16.123): icmp_seq=1 ttl=52 時間=7.22ミリ秒
--- edge12.g.yimg.jp ping 統計 ---
送信パケット数 1, 受信パケット数 1, 0% packet loss, time 0ms
rtt min/avg/max/mdev = 7.223/7.223/7.223/0.000 ms
「www.yahoo.co.jp」を「/etc/hosts」に書いてみたら、「/etc/hosts」の方が有効になっているね
[root@test9-1 ~]#
[root@test9-1 ~]# egrep -v "^#|^$" /etc/hosts
127.0.0.1 www.yahoo.co.jp
[root@test9-1 ~]# ping -c 1 www.yahoo.co.jp
PING www.yahoo.co.jp (127.0.0.1) 56(84) bytes of data.
64 バイト応答 送信元 www.yahoo.co.jp (127.0.0.1): icmp_seq=1 ttl=64 時間=0.028ミリ秒
--- www.yahoo.co.jp ping 統計 ---
送信パケット数 1, 受信パケット数 1, 0% packet loss, time 0ms
rtt min/avg/max/mdev = 0.028/0.028/0.028/0.000 ms
結論
①DNSサーバの設定によって、digできる/できない場合がある
②プログラムの内部処理によって、「/etc/hosts」も参照する
(pingは、「/etc/hosts」が優先的に参照する。)
③pingの参照流れ:「/etc/resolv.conf」→「/etc/nsswitch.conf」→「/etc/hosts」
(後ろのが優先)
④nicを経由するので、nftableもコントロールできると思われる
(loもnicだっけ微妙だけど)
⑤localhostはDNS問い合わせ処理がはしる場合があるので、localhostより127.0.0.1の方がはやいと思う