NTPv5の標準化が進められています。
そこで、実験として世の中のパブリックNTPサーバにNTPv5パケットを送信してみました。NTPv5の議論は始まったばかりですので、世の中のNTPサーバはNTPv5には対応しているはずがありません。
しかし結果は、驚くことにversionフィールドに5が指定されたNTPv4形式のパケットを返すサーバが居ることがわかりました。NTPv5とNTPv4パケットはバージョンやモードなどの領域を除き互換性がないため、そのようなパケットは破棄するしかありません。
その他にも奇妙な振る舞いをするNTPサーバもいたので、紹介していきたいと思います。
記事の後半では、そのような状況でNTPv5の仕様ではいくつかの工夫が盛り込まれていますので、それについて紹介します。
NTPv5について基本的なところは以前紹介したとおりです。
asnokaze.hatenablog.com
(なお、NTPv5については議論が始まったばっかりですので、今後大きな変更があるかもしれません)
目次
実験
約80のパブリックなNTPサーバに対して下記の4つのパケットを送信します。
- NTPv4として正常なパケット
- NTPv4形式だが、バージョンフィールドに5を指定したもの
- NTPv4として正常なパケットであり、未定義の拡張フィールドを付加したもの
- NTPv5パケット (draft-mlichvar-ntp-ntpv5-00)
これに対して、どのようなパケットが返ってくるか観測します。
NTPv4として正常なパケット
下記の通り、もちろん正常なパケットが返ってきます (一部、NTPv3を応答しますが、大丈夫です)
- 10%: NTPv3のパケットが返ってくる
- 90%: NTPv4のパケットが返ってくる
NTPv4形式だが、バージョンフィールドに5を指定したもの
先述したような、バージョンフィールドに5が指定されたNTPv4パケットが返ってきます。
- 10%: NTPv3のパケットが返ってくる
- 70%: NTPv4形式のパケットで、バージョンフィールドに5が指定されたものが返ってくる
- 20%: 応答なし
例えば、ntpdは将来のバージョンの扱いに不備があるようです
https://github.com/ntp-project/ntp/blob/master-no-authorname/ntpd/ntp_proto.c#L583
NTPv4として正常なパケットであり、未定義の拡張フィールドを付加したもの
NTPv4は拡張フィールドを付加できます。未定義の拡張フィールドを付加したパケットを送ったときのレスポンスを確認します。
- 75%: NTPv4パケットが返ってくる
- 25%: 応答なし
(TLS1.3がそうしたように、拡張フィールドでバージョンネゴシエーションをする余地があるか確認したかったのですが、いくつかのサーバはパケットをドロップしてしまいます)
なお、1件だけでしたが、未定義の拡張フィールドを送ると、同じ拡張フィールドをつけて送り返してくるようなサーバもいました。
NTPv5パケット
NTPv5はNTPv4パケットと互換がないため、多くは不正なパケットとして破棄されますが、例のパケットが返ってくることもあります
- 10%: NTPv4形式のパケットで、バージョンフィールドに5が指定されたものが返ってくる
- 90%: 応答なし
NTPv5での工夫
不正な振る舞いをするサーバに対して、NTPv5の仕様ではいくつかの工夫が入ってます。
いくつか紹介します。なお、詳細については仕様を参照ください
不正なパケットの識別
NTPv5パケットを送った場合に、バージョン5が指定されたNTPv4が返ってくると、実装としては破棄するしかありません。
どのように、そのような不正なパケットを識別するのでしょうか。実は、NTPv5ではランダムなCookieをリクエスト時に送り、レスポンスにその値をつけて返すような仕様になっています。この仕組みはNTPv5から入ったものですので、Cookieフィールドを見れば不正なパケットを識別できます。
サポートバージョンの示し方
ドロップされてしまうかもしれないので、いきなりNTPv5パケットを送りつけることはできません。そこでクライアントは、NTPv4パケットを送りつつ自身はNTPv5にも対応していることをサーバに伝えたいです。もし、サーバがNTPv5に対応していれば、NTPv5のパケットで応答が返ってくることを期待できます。
新しくNTPv4の拡張フィールドを定義し、それを使ってサポートバージョンを示すことが出来るでしょう。しかし、未知の拡張フィールドはドロップされうるので機能しません。
そこで、比較的自由に使えるNTPv4の”Reference Timestamp”フィールドにシグナルを埋め込みます。具体的には 0x4E5450354E545035 ("NTP5NTP5" のASCII値)を指定します。時刻として 2077年9月29日 7時41分です。クライアントは、このようなNTPv4パケットを送信することで自身がNTPv5に対応している事を示します。
なお、このようなパケットを送っても、パケットがドロップされたりはしなさそうです。
未知の拡張仕様の扱い
今までNTPでは未知の拡張仕様の扱いは決まっていませんでしたが、NTPv5では無視する事がMUSTとなりました。