dullwhaleのメモ帳

何度も同じことを調べなくてよいように...

OpenWrtでBusyBox ntpdを用いてNTPサーバ機能を提供する

この記事ではOpenWrtにプリインストールされているBusyBox ntpdを使ってLAN内のノードにNTPサーバ機能を提供する方法について説明する。 続く文章では、初めにBusyBox ntpdが有用な状況と、その機能について説明する。 続いて、OpenWrtにおけるBusyBox ntpdの具体的な設定方法を説明し、合わせて設定すると便利なDHCPオプションについても述べる。 最後に、参考情報としてNTPサーバが機能しているかテストする方法と、RTCを備えていないマシンでNTPサーバを稼働させることに対する懸念について書き残している。

目的と背景

小規模なネットワークであっても、複数サーバのログを照合しようとすると時刻同期が重要になる。 このため、LAN(local area network)内にNTP(network time protocol)サーバが欲しくなる。 ただし、自分の環境での時刻同期の要求精度は100 msオーダーである。 これより細かい精度で同期していても恩恵が薄い。

この記事ではOpenWrt 23.05.5を用いて簡単に、程々の性能のNTPサーバ機能を提供することを目的とする。

BusyBox ntpd

ルータOSであるOpenWrtにはBusyBoxがプリインストールされている。 このBusyBoxにはNTPクライアント/サーバ機能も備わっている。 ソースコードのコメント文には、以下の記述があるからOpenBSDで開発されているNTPサーバOpenNTPDを元に作られているらしい。

NTP client/server, based on OpenNTPD

精度の高い時刻同期や、高負荷が想定される場合にはより高性能/高機能なNTPサーバを使用すべきだが、小規模なネットワークではこれで要件を満たせることがある。

OpenWrtにおけるBusyBox ntpdの設定

OpenWrtにおけるNTPサーバの設定は次に示すファイルで行う。 このファイルはOpenWrt標準の設定ファイルの1つであり、設定に当たって複雑な手順は必要ない。

⚠️ 注意

これはあくまでOpenWrtの仕組みを利用したものであり、他の汎用的なLinuxディストリビューションにおいては異なる方法で設定が必要なことに注意せよ。

cf. https://openwrt.org/docs/guide-user/base-system/system_configuration

/etc/config/system

config system
        # NTPの設定に無関係の設定項目は省略
        option zonename 'Asia/Tokyo'
        option timezone 'JST-9'

config timeserver 'ntp'
        option enable_server '1'
        list server 'ntp.nict.jp'
        list server 'ntp1.v6.mfeed.ad.jp'
        list server 'ntp2.v6.mfeed.ad.jp'
        list server 'ntp3.v6.mfeed.ad.jp'

上記は日本標準時JST: japan standard time)に同期することを目的に、時刻に関係する項目だけを記載している。 それぞれの設定値と意図について簡単に説明する。

次の示すブロックはシステム全般に関する設定である。 タイムゾーンJSTとするために2つの設定を行っている。

config system

次に示すブロックはNTPに関する設定を行う。

config timeserver 'ntp'

次のように設定することでBusyBox ntpdをクライアントだけでなくNTPサーバとしても稼働させる。 このオプションのデフォルト値は0であり、サーバ機能の無効化を意味する。

option enable_server '1'

上位Stratumの指定は次の構文で行う。

list server 'host'

ここでは2つの観点から 国立研究開発法人情報通信研究機構NICT: national Institute of information and communications technology)とインターネットマルチフィード株式会社が提供する公開NTPサーバを指定している。

  • 正確なJSTを提供することを主目的としている。厳密に見ると+09:00すれば良いだけでなかったりする。
  • インターネット的な距離が近い。つまりレイテンシやジッタが少ない。

上位Stratumの障害やサービス停止に備えて、少なくとも2つ以上のサーバをすべき(SHOULD)である。 ここでは更なる耐障害性を目的として、上記の通り2つの組織が運営するものを指定している。 一方の組織が運営するNTPサーバ全体がサービスダウンする状況に備えている。

ホストの指定ではIPv6を利用を前提としている。 NICTのホストntp.nict.jpからはAAAAレコードとAレコードを引ける。 インターネットマルチフィードのホスト名はIPv6IPv4で異なる。 ここではIPv6用のホスト名をすべてを設定している。

optinal DHCPのオプションでNTPサーバを通知する

DHCP(dynamic host configuration protocol)では、domain name systemサーバの通知などと同じくNTPサーバについても通知できる。 この仕様はRFC(request for comments) 2132の8.3節に記載されている。 オプションのコードは42である。

なお、同RFCの3.6節にTime Server Optionという記述があるが、これはRFC 868で定義されているTime Protocolのサーバを指定するオプションであり、NTPとは異なる。 混同に注意せよ。

🛈 参考

Time ProtocolはRFC番号からも分かる通り、NTP以前に使われていた時刻を提供するための非常に簡素なプロトコルである。 現在はほぼNTPや、より高精度なprecision time protocolに取って代わられているから、ほとんどの場面で無視してよい。

OpenWrtでDHCPによりNTPサーバのアドレスを通知する設定について説明する。 DHCPの設定は次のファイルに記述する。 複数サブネットやVLANを設定している場合は、以下に示すDHCPプールが複数存在する可能性があり、必要に応じてそれぞれに設定する。

/etc/config/dhcp

# そのほかの設定項目は省略
config dhcp 'POOLNAME'
        # そのほかの設定項目は省略
        list dhcp_option '42,${OpenWrtのIPv4アドレス}'

DHCPオプションは次の構文で指定する。 42を指定しているのは先の説明の通りである。 ここでは、OpenWrtが稼働しているホスト自体をNTPサーバとして機能するよう設定したから、自身のアドレスを記述する。

list dhcp_option '${DHCPオプションのコード},${値}'

DHCPIPv4を前提に作られたプロトコルであるから、同オプションでIPv6アドレスを通知できないことに注意せよ。 RFC 2132の8.3節記述からも4オクテットのIPv4アドレスしか想定していないことが分かる。

The minimum length for this option is 4 octets, and the length MUST always be a multiple of 4.

NTPサーバをIPv6アドレスで通知したい場合、DHCPv6を使う必要がある。 その方法についてはRFC 3646を参照せよ。

なお、OpenWrt 23.05.5ではDHCPv6ではオプションを指定する方法を提供していないようだ。 ドキュメントに書かれていないだけかもしれない。

NTPサーバの動作確認

LANのノードに対しNTPサーバとして振る舞い、時刻を提供できているか簡単に確認する方法について述べる。 ここではntpdateコマンドを使う。

次に示すように、qオプションを付けて問い合わせのみを行う。 qオプションを付けない場合、ホストの時刻を同期しようとするから注意が必要である。

$ ntpdate -qv ${NTP_SERVER}
 8 Dec 22:16:49 ntpdate[5928]: ntpdate 4.2.8p15@1.3728-o Wed Feb 16 17:13:02 UTC 2022 (1)
server ${NTP_SERVER}, stratum 2, offset -0.039960, delay 0.02945
 8 Dec 22:16:49 ntpdate[5928]: adjust time server ${NTP_SERVER} offset -0.039960 sec

NTPサーバとRTCの注意

OpenWrtのNTPのページにも注意があるように、家庭用ルーターとして設計された多くのネットワーク機器はRTC(real time clock)モジュールを持たない。 Raspberry Pi 5のような新しいモデルを除き、Raspberry Piのような多くのシングルボードコンピュータも同様にRTCを持たない。 OpenWrtのwikiのNTPのページにも次の注意書きがある。

Note: most devices supported by OpenWrt do not have a hardware clock.

RTCを備えないハードウェアでNTPサーバ機能を提供するべきではない(SHOULD NOT)。 RTCを備えていない場合、起動直後は時刻が0つまりunix epochになる。 これは上位Stratumとの時刻ずれがとてつもなく大きい状態の一つと見なせる。 この状況において、NTPサーバアプリケーションの実装や設定によっては以下のように振る舞う可能性がある。

  • 上位Stratumとの同期の試みを停止する。
  • 上位Stratumとの同期完了までに長い時間を要する。
  • 上位Stratumと同期が完了していないのに、下位のノードに時刻を提供してしまう。

結果として、NTPサーバとしての稼働率を低下を危険性がある。 BusyBox ntpdの実装を詳しく調査できていないから杞憂かもしれないが、いたずらに稼働率を低下させるような構成は防ぎたい。