【KVM入門③】〜DNSとhostsの設定を行う〜

# KVM入門一覧
- [【KVM入門⓪】〜Linuxの基礎知識〜](https://qiita.com/ryutarom128/items/00ed01b0c9dd59716964)
- [【KVM入門①】〜KVMを使って仮想マシンを作成する〜](https://qiita.com/ryutarom128/items/a31cc4e296442cd0f9d6)
- [【KVM入門②】〜複数の仮想マシンを作成して仮想マシン間で通信を行えるようにする〜](https://qiita.com/ryutarom128/items/2665a0f871d90f7f5358)
- 【KVM入門③】〜DNSとhostsの設定を行う〜👈今ここ
- [【KVM入門④】〜NFSを使って全ての仮想マシンでファイルを共有する〜](https://qiita.com/ryutarom128/items/3d66f1a5d61c3eb4e426)
- [【KVM入門⑤】〜LDAPを使ってユーザ情報などを一元管理する〜](https://qiita.com/ryutarom128/items/b008ca44b7265164879c)

# はじめに

KVMシリーズ第3回です。

前回で`8.8.8.8`や他の仮想マシンとの通信は成功しました。

しかしこのままでは名前解決ができないため、例えば`ping google.com`や`dnf update`をしようと思ってもうまくいきません。

そこで、DNSとhostsの変更を行い、以下の図の赤色の部分を設定するところまでをこの回の目標とします。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2906464/7f105f59-777d-776d-08e5-9e465e94a41a.png)

# すること
## 1. DNSの設定と確認

仮想マシンに接続する。
```
sudo virsh console test-vm1
```

DNSサーバの設定を行う。

なお、`8.8.8.8`と`8.8.4.4`はそれぞれGoogle Public DNSの優先DNSサーバ、代替DNSサーバである[^google-public-dns]。
[^google-public-dns]: Wikipedia. Google Public DNS. https://ja.wikipedia.org/wiki/Google_Public_DNS

```bash
nmcli con mod enp1s0 ipv4.dns "8.8.8.8 8.8.4.4"
```

ネットワークの再接続を行う。
```bash
nmcli con down enp1s0
```

```bash
nmcli con up enp1s0
```

以下のように`ping`が通れば設定は成功している。
```bash
[xxx@localhost ~]# ping google.com -c 3
PING google.com (142.250.207.110) 56(84) bytes of data.
64 bytes from kix06s11-in-f14.1e100.net (142.250.207.110): icmp_seq=1 ttl=115 time=2.55 ms
64 bytes from kix06s11-in-f14.1e100.net (142.250.207.110): icmp_seq=2 ttl=115 time=2.91 ms
64 bytes from kix06s11-in-f14.1e100.net (142.250.207.110): icmp_seq=3 ttl=115 time=2.67 ms

--- google.com ping statistics ---
3 packets transmitted, 3 received, 0% packet loss, time 2003ms
rtt min/avg/max/mdev = 2.549/2.711/2.911/0.150 ms
```


## 2. /etc/hostsの変更
仮想マシン間でも名前解決ができるように/etc/hostsの変更を行う。

```bash
vi /etc/hosts
```

以下のように書き込む。
```/etc/hosts
127.0.0.1   localhost localhost.localdomain localhost4 localhost4.localdomain4
::1         localhost localhost.localdomain localhost6 localhost6.localdomain6
172.16.1.1  vm1 vm1.test.internal
172.16.1.2  vm2 vm2.test.internal
172.16.1.3  vm3 vm3.test.internal
172.16.1.4  vm4 vm4.test.internal
```

上のように書くことで、`vm1`と`vm1.test.internal`の名前をどちらも使うことができる。
つまり、`ping 172.16.1.1`、`ping vm1`、`ping vm1.test.internal`のコマンドは全て同じホストとの通信を行う。

以下のように表示されれば設定は成功している。
```bash
[xxx@vm1 ~]# ping vm1 -c 3
PING vm1 (172.16.1.1) 56(84) bytes of data.
64 bytes from vm1 (172.16.1.1): icmp_seq=1 ttl=64 time=0.056 ms
64 bytes from vm1 (172.16.1.1): icmp_seq=2 ttl=64 time=0.035 ms
64 bytes from vm1 (172.16.1.1): icmp_seq=3 ttl=64 time=0.072 ms

--- vm1 ping statistics ---
3 packets transmitted, 3 received, 0% packet loss, time 2052ms
rtt min/avg/max/mdev = 0.035/0.054/0.072/0.015 ms
[xxx@vm1 ~]# ping vm2 -c 3
PING vm2 (172.16.1.2) 56(84) bytes of data.
64 bytes from vm2 (172.16.1.2): icmp_seq=1 ttl=64 time=0.314 ms
64 bytes from vm2 (172.16.1.2): icmp_seq=2 ttl=64 time=0.249 ms
64 bytes from vm2 (172.16.1.2): icmp_seq=3 ttl=64 time=0.336 ms

--- vm2 ping statistics ---
3 packets transmitted, 3 received, 0% packet loss, time 2013ms
rtt min/avg/max/mdev = 0.249/0.299/0.336/0.036 ms
[xxx@vm1 ~]# ping vm3 -c 3
PING vm3 (172.16.1.3) 56(84) bytes of data.
64 bytes from vm3 (172.16.1.3): icmp_seq=1 ttl=64 time=0.239 ms
64 bytes from vm3 (172.16.1.3): icmp_seq=2 ttl=64 time=0.280 ms
64 bytes from vm3 (172.16.1.3): icmp_seq=3 ttl=64 time=0.356 ms

--- vm3 ping statistics ---
3 packets transmitted, 3 received, 0% packet loss, time 2037ms
rtt min/avg/max/mdev = 0.239/0.291/0.356/0.048 ms
[xxx@vm1 ~]# ping vm4 -c 3
PING vm4 (172.16.1.4) 56(84) bytes of data.
64 bytes from vm4 (172.16.1.4): icmp_seq=1 ttl=64 time=0.202 ms
64 bytes from vm4 (172.16.1.4): icmp_seq=2 ttl=64 time=0.378 ms
64 bytes from vm4 (172.16.1.4): icmp_seq=3 ttl=64 time=0.277 ms

--- vm4 ping statistics ---
3 packets transmitted, 3 received, 0% packet loss, time 2064ms
rtt min/avg/max/mdev = 0.202/0.285/0.378/0.072 ms
```

## 3. ホスト名の変更
各仮想マシンに接続し、ホスト名を恒久的に変更する[^hostnamectl]。
[^hostnamectl]: Server World. ホスト名を設定する. https://www.server-world.info/query?os=Rocky_Linux_8&p=hostname
```bash
sudo hostnamectl set-hostname vm1.test.internal
```
ターミナルの表示を変更するために一旦ログインし直す。
```bash
exit
```

以下のように表示されればホスト名の変更は成功している。

```bash
[xxx@vm1 ~]# uname -n
vm1.test.internal
```

# 解説

## DNSとhostsの違い
DNSとhostsは両方とも名前解決の技術である。

以下のような違い[^dns-hosts]がある。
[^dns-hosts]: vanaryu(Tachibana). 【新人向け】わかるようでわかってなかったhostsとDNSのこと〜歴史を知れば覚えられる〜. https://qiita.com/vanaryu/items/6de34a3d611d6b78848e

| | hosts | DNS |
|:-|:-|:-|
| 歴史 | 名前解決のために最初に生まれた | コンピュータが爆発的に増えたため生まれた |
| 使う場所 | LAN | インターネット |
| 使い方 | /etc/hostsを編集する(Linux, Unix, Mac) | ドメイン取得サービスでドメインを取得する |


## `.internal`とは

今まではプライベートネットワーク内で何らかのドメインを使用したい場合、インターネット上のドメインと衝突してしまう可能性があった。これを**名前衝突**[^name-collision]という。
[^name-collision]: 名前衝突(Name Collision)問題. https://www.nic.ad.jp/ja/dom/new-gtld/name-collision/

名前衝突が起こると意図せず外部との通信が行われ、情報が漏洩してしまうリスクがあった。

そこで、プライベートネットワークで使うためのトップレベルドメイン(TLD)としてICANNが暫定的に採用したものが`.internal`である[^internal]（2024/6/2現在）。
[^internal]: ITmedia Inc. 「.INTERNAL」を私的用途のトップレベルドメインに　ICANNが暫定的に決定、その理由とは？. https://atmarkit.itmedia.co.jp/ait/articles/2402/17/news043.html

# さいごに
今回はDNSとhostsの設定を行い、名前解決をできるようにする方法を紹介しました。

次回はNFSを使って全ての仮想マシンでファイルを共有できるようにしていきます。