AWS Wavelength上にNTPサーバー（chrony）を立てる

AWS Wavelength zone内のサブネット上に、chronyを使ったNTPサーバーを立ててみました。

## AWS Wavelengthとは
AWS Wavelengthとは、簡潔に表現すると、EC2を利用したコンピューティング環境をモバイルキャリア網（日本ではKDDI）に直結する形で構築することができるサービスとなります。

:::note warn
ヒント
WavelengthゾーンにEC2のインスタンスを立てる場合ですが、インスタンス・タイプなど、いろいろな限定がありますので、東京リージョンとすべて同じというわけではありません。
:::

下の図で説明しますと、AWS Wavelength Zoneは、キャリアネットワーク（日本ではKDDI）の雲の一部に設置されるようなイメージになります。実際のAWS Wavelength Zone（東京）の物理的な場所は、KDDIのネットワークセンター内になりますので、ちょうど、キャリアネットワークの中にAWSの出張所がある感じですね！

![Wavelength.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2054456/a1c8be2d-e1a2-8a37-9175-89240755c46e.jpeg)

## Wavelengthゾーンにサーバーを立てるとどうなるか？
WavelengthゾーンにWindows Serverを立てて、そのWindows Serverへリモートデスクトップで接続してみますと、そのデスクトップ上でブラウザを使ってGoogle、Yahooなどの通常のWebサービスにアクセスすることができます。

ただし、その逆については制限があり、例えば、PCからWavelengthゾーン上のWebサーバーへアクセスしようとするケースでは、そのPCがauまたはUQのSIMを使って通信を行っている場合のみ可能となります。（au/UQのスマホによるテザリング、または、au/UQのSIMを使っているモバイルルーターなど。もちろん、au/UQのSIMを使っているスマホのブラウザでアクセスすることも可能です。）

また、次に出てきますが、Wavelengthゾーン上のサーバーとインターネット上のサーバーがUDPを使って通信をする場合、仕様上、Carrier Gateway（AWS WavelengthとKDDIモバイル網の接続ポイントにあるルーター）がパケットを通さないので、通信できません。

## 問題点
AWS Wavelength zone内に普通にEC2インスタンスを立ててchronyをインストールしても、WavelengthはUDPを通さないので、外部のNTPサーバーにアクセスして時間情報を取得することができません。

:::note warn
補足
下記のAWSのマニュアルにある通り、Wavelength上のEC2インスタンスとKDDIのモバイルネットワークを利用している端末はUDPで通信できるのですが、外部のNTPサーバーがauで通信しているわけがない（当然固定回線ですね！）ので、結局、このケースでは「通信できない」となります。
:::

下記は、AWS Wavelengthのマニュアルからの抜粋です。

![NetworkingConsiderations.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2054456/4c7a9e88-3f52-b481-4839-e1653f46651b.png)

## 解決策
仕方がないので、下記の2つの方法を試してみることとしました。

    1. 同じVPC内の東京リージョン側に同様のNTPサーバーを立てて、それを参照する
    2. Amazon Time Sync Serviceを利用する

それでは、下記の構成図のような形で設定していきます。

![NTPServersInAWS6.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2054456/d1c775d6-4ebf-1784-5bb4-525cf392a03c.jpeg)

## 東京リージョン（Public Subnet）のinstanceへchronyをインストール
Ctrl+Alt+Tでターミナルを開いて、コマンドでchronyをインストールします。

```
sudo apt install chrony
```
次に、/etc/chrony/chrony.confをエディターで開いて、chronyのコンフィグファイルを編集します。

```
sudo nano /etc/chrony/chrony.conf
```
そうすると下記のような画面が開きますので、デフォルトで入っているサーバーを消して、下記の画面のような感じで、サーバーを追加しましょう。

![Chrony-Ubuntu-PublicSubnet-Settings.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2054456/0920da91-dc5a-d56f-508d-4619c5d11dc8.jpeg)

ちなみに、169.254.169.123は、Amazon Time Sync Serviceのアドレス、ntp.nict.jpは情報通信研究機構が運営する時刻サーバーのドメインとなります。（それ以外は適当に選びました。）

https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/set-time.html

https://www.nict.go.jp/JST/JST5.html

また、最後の行にWavelength上のサーバー(10.50.50.234)で稼働しているchronyから参照できるように、下記のような設定を1行追加します。

```
allow 10.50.50.234
```
もし、複数のサーバーからのアクセスを許可したい場合は、複数の行にして、それぞれ記入するか、または、CIDRフォーマット（例えば、10.50.50.0/24）で記述します。

```
allow 10.50.50.0/24
```

ここで一度、chronyサービスをリスタートしましょう。

```
sudo systemctl restart chrony.service
```

## chronyを有効にするためのサーバーの設定変更

さらに、上記のallow 10.50.50.234の設定はあくまでもchronyの話なので、サーバーのセキュリティグループも同時に設定変更する必要があります。

Wavelength側のchrony(10.50.50.234) => 東京リージョン側のchrony(10.50.10.252)という形のアクセスになりますので、東京リージョン側のEC2インスタンスにおけるセキュリティグループのインバウンドルールの設定において、すべてのトラフィック（all traffic, all protocol）について10.50.50.234を許可しましょう。

EC2 > セキュリティグループの設定 > 該当するセキュリティグループにおいて、インバウンドルールを編集します。

```
ルールを1行追加して、typeでall trafficを選択、Sourceは10.50.50.234を入力
```

## Wavelength Subnet上のinstanceへchronyをインストール
Wavelength上のインスタンスに接続するためには、通常は、踏み台サーバー（Jump Box）を立てて、それを経由してアクセスします。Jump Boxを使った接続方法については、Public Subnet上にあるJump BoxからPrivate Subnet上にあるサーバーにアクセスする方法と全く同じですので、その部分については省略させていただきます。

https://www.youtube.com/watch?v=Mwf17O45IA0

ちなみに、auの携帯を持っている方であれば、Jump Boxなしで、au携帯のテザリングで直接接続することもできます。
その場合、Internet Gatewayは通らず、Wavelength側のCarrier Gatewayを通ってサーバーにアクセスする形となりますが、Wavelength上のサーバーのセキュリティグループを編集して、RDPでauが使っているIPアドレスレンジを受け付ける設定を入れましょう。

サーバーに接続できたら、先ほどと同様に、chronyをインストールしましょう。

```
sudo apt install chrony
```
次に、/etc/chrony/chrony.confをエディターで開いて、chronyのコンフィグファイルを編集します。

```
sudo nano /etc/chrony/chrony.conf
```
そうすると、また下記のような画面が開きますので、デフォルトで入っているサーバーを消して、こちらも下記の画面のような感じで、サーバーを追加しましょう。

169.254.169.123はAmazon Time Sync ServiceのIPアドレス、10.50.10.252は、東京リージョン側のchronyが稼働しているサーバーのアドレスとなります。

この10.50.10.252を入れることで、chronyが自動的に東京リージョン側のchrony（NTPサーバー）へアクセスするようになります！

![Chrony-Ubuntu-Wavelength-Settings.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2054456/38cb428e-afda-3be5-cc1d-7f69d2b0e813.jpeg)

設定が終わりましたので、一度、chronyサービスをリスタートしましょう。

```
sudo systemctl restart chrony.service
```

chronyが稼働しているかどうか、サービスのステータスを見てみましょう。

```
sudo systemctl status chrony
```

![Chrony-Ubuntu-Wavelength-Systemctl.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2054456/99b7df43-a2c5-49ad-c8f7-754ace39fbf3.jpeg)

## 東京リージョン側のchrony(NTP Server)の稼働状況を確認

chronyc sourcesコマンドによって、情報ソース毎の状況を確認できます。-vをつけると、説明が付きます。

上から6番目の星印が付いているサーバーが現在同期しているサーバーであり、調整されたオフセットが百万分の98秒であると表示しています。

Stratumは、時間ソースサーバーを階層化していて、Startum 0が原子時計に直結している時間サーバー、Stratum 1はStratum 0の時間サーバーに同期していて、Stratum 0の次に正確な時間を供給するサーバーとなります。

```
chronyc sources -v
```

![Chrony-Ubuntu-PublicSubnet-Sources.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2054456/9c8e8afd-5562-69b4-f06d-8d4fc5c052cf.jpeg)

chronyc sourcestatsは、chronyc sourcesによって表示されない詳細な統計情報を表示するコマンドです。

```
chronyc sourcestats -v
```

![Chrony-Ubuntu-PublicSubnet-Sourcestats.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2054456/9f85ec5e-87c7-7aaa-a4e4-fd4d8cdcffbe.jpeg)

また、chronyc trackingコマンドによって、現時点でのトラッキング情報（選択している時間サーバーをベースとした時間情報の追跡状況）を表示します。

こちらで表示している内容では、システムタイムがNTPタイムに対して百万分の6.77秒遅れていると言っています。

```
chronyc tracking
```

![Chrony-Ubuntu-PublicSubnet-Tracking.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2054456/7915b563-7ee0-9c60-4741-4d4021fda671.jpeg)

さらに、chronyc clientsコマンドによって、このサーバー（東京リージョン側のchrony）へアクセスしているクライアントの情報が得られます。
ip-10-50-50-234.ap-north...は、Wavelength側のサーバー（10.50.50.234）のDNSネームになりますので、このサーバー（10.50.10.252）へアクセスしていることがわかります！

```
chronyc clients
```

![Chrony-Ubuntu-PublicSubnet-Clients.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2054456/c0c15ddd-c230-9cb2-9ee7-0a66066bdc51.jpeg)

## Wavelength側のchronyの稼働状況を確認

利用するコマンドは同じですが、下記のようなステータスが確認できます。
時間ソースがAmazon Time Sync Serviceと東京リージョンに建てたNTPサーバー（chrony）の2つとなります。
いずれの調整後のオフセット値も1ミリ秒以下の数値（百万分の884など）となっており、悪くないのでは？！と思っていますが、いかがでしょうか。。

```
chronyc sources -v
```

![Chrony-Ubuntu-Wavelength-Sources.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2054456/3b05cf57-2028-a0da-c47d-083ff3a69afb.jpeg)

```
chronyc sourcestats -v
```

![Chrony-Ubuntu-Wavelength-SourceStats.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2054456/6a1f151b-d28c-f066-8461-e1d6ca05696e.jpeg)

トラッキング情報を見ると、System timeのところで、NTPタイムと比較して百万分の154秒（1万分の1.54秒）早いとのこと。

```
chronyc tracking
```

![Chrony-Ubuntu-Wavelength-Tracking.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2054456/0bdbd9c2-315a-f7a5-d99e-c87249a78132.jpeg)

## Amazon Time Sync Serviceについて
こうしてみると、Linux系、FreeBSD系、MacOSであれば、すべてchronyをインストールできるので、AWSの内部では、片っ端からchronyを入れて、単に、configファイルに、下記のサーバーの記述を入れてしまえば、まあまあの精度が得られるということでしょうか。
※　ただし、この記事では、Amazon Time Sync Serviceに固定されてしまっては面白くないので、下記のサーバーの記述からpreferは外しています。

```
server 169.254.169.123 prefer iburst minpoll 4 maxpoll 4
```

## 参考情報

https://chrony.tuxfamily.org/

https://ubuntu.com/blog/ubuntu-bionic-using-chrony-to-configure-ntp

https://ubuntu.com/server/docs/network-ntp

https://medium.com/bizlab-technologies/aws-setup-bastion-host-ssh-tunnel-f5ec5cf10524

https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/set-time.html

https://docs.aws.amazon.com/AWSEC2/latest/WindowsGuide/windows-set-time.html

https://www.nict.go.jp/JST/JST5.html

https://www.pool.ntp.org/zone/jp