RHEL にNTPサーバを立てる

Linux の標準機能でNTP サーバを立ててみます。
動機としては、DNS サーバを立てる検証をするときに、nslookup するだけだと味気ないので、ホスト名で時刻同期させれば少しはおもしろいかな、と思ったことにあります。

## 概要
Azure の仮想マシンをRHEL で2台立てて、時刻同期させる。
パブリックIP を持っている片方のサーバが、プライベートサブネットにいるクライアントに時刻を教える形。
毎度手書きで恐縮ですが構成図です。
![ブログ用構成図_NTP.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3617557/3e6c8ad4-c9bf-7938-9d81-c13d3754de32.jpeg)

## 手順
###  ０．仮想マシン作成とSSH 
いつも通りAzure に仮想マシンを立てます。
サーバ、クライアント両方同じように作成します。互いに同じ仮想ネットワークの別のサブネットに設置。パブリックIP は片方だけでいいですね。

とりあえずNTP サーバとして立てた方にSSH して構築を始めます。
### １． NTP サーバ構築
[この記事](https://www.isoroot.jp/blog/2844/)をトレースしました。
やることとしては
* ファイアウォール穴あけ
* NTP サービス開始
* /etc/chrony.conf 編集

だけですね。

```
# firewall-cmd --add-service=ntp -permanent　　#ファイアウォール穴あけ
# systemctl start chronyd　　　　　　　　　　　　#NTP サービス開始
```
:::note 
[参考](https://manual.sakura.ad.jp/vps/support/security/firewalld.html)
firewall-cmd --get-services でサービス名を調べられる。
firewall-cmd --add-port でポート指定できる。
:::
そして/etc/chrony.conf を編集します。とりあえず参考記事の通りやりますが、許可するネットワークは10.0.0.0/16 にするとこだけ違います。
```
# Use public servers from the pool.ntp.org project.
# Please consider joining the pool (http://www.pool.ntp.
org/join.html).
# pool 2.rhel.pool.ntp.org iburst
（中略）
# Allow NTP client access from local network.
#allow 192.168.0.0/16
allow 10.0.0.0/16

# Serve time even if not synchronized to a time source.
local stratum 10
```
編集後、chrony を再起動させます。
```
# systemctl restart chronyd
```
### ２．クライアント構築
別のサブネットを同じ仮想ネットワークに作成します。今回は10.0.1.0/16 にしました。
そのサブネットにこれまたRHEL を置きますが、パブリックIP は与えません。
さてNTP サーバからプライベートIP を指定してSSH します。
```
# ssh testuser@10.0.1.4
```

そして、クライアントの/etc/chrony.conf も以下の部分を編集します。
```
# Use public servers from the pool.ntp.org project.
# Please consider joining the pool (http://www.pool.ntp.org/join.html).
# pool 2.rhel.pool.ntp.org iburst
server 10.0.0.4 iburst
```
それから次のコマンドでchrony を起動しました。
```
# systemctl start chronyd
```
最後に、NTP の参照先を確認したところ・・・
```
[root@client testuser]# chronyc sources
MS Name/IP address         Stratum Poll Reach LastRx Last sample
===============================================================================
^- 108.160.132.224.vultruse>     2   6   377     0  +1385us[+1385us] +/-   31ms
^- x.ns.gin.ntt.net              2   6   177    65  +2434ns[  +86us] +/-  127ms
^* ntp-b2.nict.go.jp             1   6   377     1   +111us[ +187us] +/- 1084us
^+ mail1.marinecat.net           2   6   377     2    -91us[  -16us] +/- 2876us
```
構築したNTP サーバに見に行っていないようです。
実は今回、参考にした記事とは違う手順でクライアント構築やっていて、
記事では
chrony 起動⇒.conf を編集⇒chrony 再起動
となっているのに対して、私は今回
.conf 編集⇒chrony 起動、としました。つまり再起動はしてません。

:::note
.conf をいじったらとりあえず再起動が必要
:::
というわけで再起動したところ、
```
[root@Client testuser]# chronyc sources
MS Name/IP address         Stratum Poll Reach LastRx Last sample
===============================================================================
^? stepserver.internal.clou>     0   6     0     -     +0ns[   +0ns] +/-    0ns
```
stepserverというのはNTP サーバとして立てた仮想マシンのホスト名です。見に行くリストには入りましたが同期はしていません。
なんでIPアドレス教えただけやのにホスト名知ってんの？
名前解決はしてるけど、NTP の通信をやりあってはいない模様。

:::note
後で調べると、chrony は勝手にDNS サーバに聞きに行って名前解決するらしいです。
:::


NSG の設定も入れ、クライアント側でfirewall-cmd の設定も入れましたがダメでした。
### ３．トラブルシューティング

nc コマンドで疎通確認してみました。

:::note
NTP はUDP のポート123 です。nc コマンドでは-u オプションがUDP を指定します。
:::

```
[root@Client testuser]# nc -vzu 10.0.0.4 123
Ncat: Version 7.70 ( https://nmap.org/ncat )
Ncat: Connected to 10.0.0.4:123.
Ncat: No route to host.
[root@Client testuser]#
```
ちなみに10.0.0.4 あてでもstepserver あてでもping は通ります。

いったんサーバ側に戻って設定確認したところ、さらによくわからない状況に。
```
[root@StepServer testuser]# nc -uvz localhost 123
Ncat: Version 7.70 ( https://nmap.org/ncat )
Ncat: Connected to ::1:123.
Ncat: Connection refused.
[root@StepServer testuser]# firewall-cmd --add-port=123/UDP
Error: INVALID_PROTOCOL: 'UDP' not in {'tcp'|'udp'|'sctp'|'dccp'}
[root@StepServer testuser]# firewall-cmd --add-port=123/udp
success
[root@StepServer testuser]# nc -uvz localhost 123
Ncat: Version 7.70 ( https://nmap.org/ncat )
Ncat: Connected to ::1:123.
Ncat: Connection refused.
[root@StepServer testuser]#
```
firewall 開けたのに開かない状況。

firewall-cmd --list-all やってみると、これまでのファイアウォール穴あけはすべてインターネットに向いた側（public）にやっていたのでは？？という結果（ntp 追加しようとして、すでに入ってますよというメッセージが出てる）が。そういやzone とか指定してるの見たことあるなと

```
[root@StepServer testuser]# firewall-cmd --list-all
public (active)
  target: default
  icmp-block-inversion: no
  interfaces: eth0
  sources:
  services: cockpit dhcpv6-client ssh
  ports: 123/udp
  protocols:
  forward: no
  masquerade: no
  forward-ports:
  source-ports:
  icmp-blocks:
  rich rules:
[root@StepServer testuser]# firewall-cmd --add-service=ntp --permanent
Warning: ALREADY_ENABLED: ntp
success
```
Client に対しては閉じてるのには合点がいったので、インターフェイス確認。

```
[root@StepServer testuser]# firewall-cmd --get-zones
block dmz drop external home internal nm-shared public trusted work
[root@StepServer testuser]# firewall-cmd --get-activezones
usage: see firewall-cmd man page
firewall-cmd: error: unrecognized arguments: --get-activezones
[root@StepServer testuser]# firewall-cmd --get-active-zones
public
  interfaces: eth0
```
やはり、設定されているのはpublic だけだったっぽい。さて、プライベートネットワーク側はinternal のことでいいのかしら。
#### プライベート側のfirewall 設定
[参考になる記事](https://qiita.com/daikumatan/items/0fe4a8ee5e59965814ee#nic%E3%82%92%E6%89%80%E6%9C%9B%E3%81%AEzone%E3%81%B8%E7%99%BB%E9%8C%B2%E3%81%99%E3%82%8B-zone%E3%81%AEactive%E5%8C%96)を見つけました。おそらく、zone がネットワーク、interfaces が個々のインターフェイスでしょう。ではプライベート側はinternal でeth1 だと思ってやってみます。

```
[root@StepServer testuser]# NIC_NAME="eth1"
[root@StepServer testuser]# ZONE_NAME="internal"
[root@StepServer testuser]# firewall-cmd --change-interface=${NIC_NAME} --zone=${ZONE_NAME}
success
```
そして設定が入ったかを確認。
```
[root@StepServer testuser]# firewall-cmd --get-active-zone
internal
  interfaces: eth1
public
  interfaces: eth0
```
ではこのinternal に対してntp を許可する設定を入れます。
```
[root@StepServer testuser]# firewall-cmd --add-service=ntp --zone=${ZONE_NAME}
success
[root@StepServer testuser]# firewall-cmd --list-all --zone=internal
internal (active)
  target: default
  icmp-block-inversion: no
  interfaces: eth1
  sources:
  services: cockpit dhcpv6-client mdns ntp samba-client ssh
  ports:
  protocols:
  forward: no
  masquerade: no
  forward-ports:
  source-ports:
  icmp-blocks:
  rich rules:

```
おお、入った
それではクライアント側に再度ssh し、時刻同期を確認します。
```
[testuser@Client ~]$ chronyc sources
MS Name/IP address         Stratum Poll Reach LastRx Last sample
===============================================================================
^* stepserver.internal.clou>    10   8    77   217    +47us[ +132us] +/-  411us
```
*がついたので、時刻同期できています！！きもちい

以上NTP サーバの構築でした。お疲れさまでした。