定時帰る術-localhostと127.0.0.1

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問い合わせ処理がある
![localhost.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3569536/1cdd30e2-e9a5-6f32-5e05-126e72c664ab.png)

処理流れ：
①自分自身の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の方がはやいと思う