ちょっと今どきのntp.confの設定

Debian stretchがリリースされて、定番パッケージのメジャーバージョンが上がったことにより、従来とは作法が変わったものもある。ntpもその一つ。
いろいろ検索してみても、微妙に古い知識なども混じっているのでまとめ。対象はDebian stretchなので4.2.8p10だけど、4.2.7p22以降だったら同じと思われ。ただしCentOS7でも4.2.6系っぽいし、デフォルトのNTPサーバがchronyになってるようなので、対象外かな。


## serverとpoolの違いを知る
ntpdの同期先の指定方法としてserverとpoolがあります（もう一つpeerというのもあるけど、ここでは省略）。
serverで指定した場合は、実質的に1つのサーバを同期先として指定することになりますが、poolの場合、DNSラウンドロビンなどで複数のIPアドレスを返してくるサーバをまとめて指定できます。

具体的には

```
pool ntp.jst.mfeed.ad.jp iburst
```

```
server ntp1.jst.mfeed.ad.jp iburst  
server ntp2.jst.mfeed.ad.jp iburst  
server ntp3.jst.mfeed.ad.jp iburst
```


この2つはほぼ同義ということになります。どっちがスマートかは明らかですし、DNSラウンドロビンをするタイプのNTPサーバならともかく、ランダムなIPアドレスを返すpool.ntp.orgのようなNTPサーバの場合は、serverでちまちま書くのもナンセンスですね。

iburstもデフォルトでついていることが多いので、そのままで行きましょう。
これがあるとntpdの起動時と相手が応答しないときのみ、2秒間隔で8パケット確認を行い、初回の同期を高速化できます。burstというパラメータも指定できますが、こちらは常にバーストをすることになるので、余程の必要があってしかも迷惑がかからない相手以外には指定すべきではありません。

## restrictをちゃんと設定する
意外とちゃんとrestrictを理解して設定してる人って少ないと思うんですよねぇ。
とはいえDebian stretchの場合はデフォルトで下記のようになっているため、このままでもいいように思います。

```
restrict -4 default kod notrap nomodify nopeer noquery limited
restrict -6 default kod notrap nomodify nopeer noquery limited
restrict 127.0.0.1
restrict ::1
restrict source notrap nomodify noquery
#restrict 192.168.123.0 mask 255.255.255.0 notrust
```

defaultはいろいろ拒否しつつ、kodとlimitedで制限系のパラメータを有効に、localhostに対しては全許可、poolやserverで指定されてる参照先に対してはそこからの問い合わせ系パケットが来たら拒否、一方LAN内などで参照される場合は、クライアントを参照源とはしないという感じ。
昔の設定例だと`restrict default ignore`としてるものが多いですが、いつの間にか変わっています。全拒否をするならファイアウォールで対処すればよくて、アプリケーション側のデフォルト値としてはlimitedやkodの量的制限をすべきという考え方なのかな。この辺りはお好みでいいと思いますし、参照時のrestrictの中でkodやlimitedを指定するのもまた一案でしょう。

4.2.7p22以降だと、ホストの指定に"source"という指定ができるので、昔ながらにpoolやserverに書いてあるFQDNやIPアドレスを列挙しなくていいのはお手軽です。こう書いておけば、DNSラウンドロビンやランダム応答で別のIPアドレスを参照することになっても、ntpd側がよしなに処理してくれます。便利な半面セキュリティ的にどうなのかというのはちょっと感じますが、iptablesなどとの合せ技で外部からのNTPパケット（UDP123）を制御できればいいのかなとも思います。

## うるう秒に備えておく

直近では2017年1月1日にあったので、次はだいぶ先じゃないかとも思いますが、それなりに備えておきたいところ。影響が少なくなるのはslewモードで動かしておくことなので、起動オプションでこれを強制しておくのがよいでしょう。時刻のズレが大きくなってしまった場合はそれなりのデメリットもあるので、注意したいところですが、常時大きくズレるようならマザーボードやカーネルが異状などの別の要因があるので、そっちを先になんとかした方がいいですね。
てなわけで、Debian stretchでは/etc/default/ntpを下記のようにしてntpdを再起動します。

`NTPD_OPTS='-x'`

余談ですが、デフォルトだと-gオプションが指定されてますが、これはいらないと思うので抜いてしまってもよいかな。-gを付けると、NTPサーバとカーネルクロックが1000秒以上ズレていてもexitしなくなるということのようですが、そんなにズレてれば一度exitさせて手動でntpdateをするなりして誤差を小さくしてからntpdを起動すればいいじゃんというわけで。

## 正しい参照先サーバ選び

Debian stretchの場合は、デフォルトでNTP POOL PROJECTのサーバが指定されていて、そこそこ近いサーバがピックアップされるので、このままでもまあ良いかなぁ。
とはいえ時間を調整するという機能の特性上、ネットワーク的に近いことが最も優先すべき事項です。プロバイダやデータセンタで提供されているNTPサーバがあれば、そちらの方が近いことがままあるので、その方が最適かもしれません。それがない場合はMFEEDがIXに近いところにあるため、ヘタなNTPサーバよりも近いことが多いようです。

個人的な優先度は
プロバイダのNTPサーバ＞MFEED＞その他RINGでもNTP POOLでもGoogleでも
という感じ。Googleはうるう秒が挿入されないという便利な機能がありますが、それに無自覚でいてかつ自分のntpdをslewモードにし忘れてたりすると、別のサーバを指定してるホストがうるう秒の直撃を食らったりもするので、気をつけたいところですね。

また複数サーバがある環境やクライアントPCがたくさんある環境では、外部への参照を行うサーバは限られたものにして、それ以外はLAN内に立っているNTPサーバを参照するような構造を採るようにするべきなのは言うまでもありません。

## まとめ
ログを出すのはご自由にという感じですが、まとめるとこんな具合。デフォルトからは大きく変わってません。

```
statsdir /var/log/ntpstats/
statistics loopstats peerstats clockstats
filegen loopstats file loopstats type day enable
filegen peerstats file peerstats type day enable
filegen clockstats file clockstats type day enable
pool ntp1.sakura.ad.jp iburst
pool ntp.jst.mfeed.ad.jp iburst
restrict -4 default kod notrap nomodify nopeer noquery limited
restrict -6 default kod notrap nomodify nopeer noquery limited
restrict 127.0.0.1
restrict ::1
restrict source notrap nomodify noquery
```

LAN内に他のホストがいなくてスタンドアロンで動いているので、外部から参照されることは想定していません。で、さくらのVPSにいるのでさくらのNTPを指定しつつ予備でMFEEDという具合。さくらのNTPサーバは実質1台なんですが、IPv4とIPv6のアドレスを両方持ってるので、serverではなくpoolで指定しています。IPv6の方が遅延が少ないっぽいですけど。

地味なサービスで忘れられがちですが、サーバの時刻がズレると他にいろんな影響が出ることが多いので、ちゃんとわかった上で設計・設定をしたいもんです。

## 参考
http://www.asahi-net.or.jp/~aa4t-nngk/ntpd.html