NTP leap indicatorを上書きするProxyを書いた

前置き


かなり無理矢理かつ、動作を保証するものではありません。
手習いで試しに書いてみたぐらいの温度感です


うるう秒

元旦「うるう秒」でエンジニア悲鳴 「年末年始がなくなる」”と言ったニュースサイトでも取り上げられているように、1月1日 日本時間朝9時にうるう秒が挿入されます。つまり、8時59分60秒 という時間が挿入されます。


60秒が挿入されるとはどういうことか
NTP うるう秒(閏秒)」こちらのサイトの情報を引用させていただくと

日付(JST) NTP time LI
2006/01/01 08:59:59 3345062399 01
2006/01/01 08:59:60 3345062400 01
2006/01/01 09:00:00 3345062400 00

NTPサーバからのレスポンスには事前にうるう秒の挿入を示すLeap Indicatorというフラグがセットされます。そうして、60秒から00秒にかけては同じ時間がレスポンスされて帰ってきます。


このLIですが、このLIがセットされているとSlewモードからStepモードに移行してしまうNTPクライアントのバグなども存在していますし、なかなか厄介な存在です。


前回は、このLIがNTPクライアントに到達しないように、該当時間だけ上位のNTPサーバとの同期を停止するという方法を取ったという人もいるようです。もちろん、60秒を挿入しないぶん1秒早く時刻が刻まれていきますが、殆どのソフトウェアは個々に対応が進んでいるとはいえ予期せぬうるう秒に起因する不具合を踏むよりはマシなのかと思います。

NTP leap indicatorを上書きするProxyを書いた

上位のNTPサーバと同期を止める方法は、ローカルのハードウェアクロックを頼りにしており、それはそれで心もとないなと思い、LIフラグをオフにするUDP Proxyを書いてみました。


unset-leap-indicator-proxy
https://github.com/flano-yuki/unset-leap-indicator-proxy


NTPサーバを指定して起動すると、UDPの123 portでLISTENし、受け取ったNTP Requestを指定したサーバにProxyします。

vagrant@vagrant:~/tmp$ sudo go run ./proxy.go -v ntp.nict.jp
Info: Start Proxy on  :123  to ntp.nict.jp
Received from 192.168.0.179:123
Received from 192.168.0.179:123
Received from 192.168.0.179:123



このProxyはNTPパケットを実際にパースすることはなく、単純にUDPボディの上位2bit(Leap Indicator)を 00 に上書きします。
これによってNTPクライアントにLIが入ることもありません。しかし、うるう秒のタイミングでは60秒が挿入されず1秒ずれてしまうので、そこからはNTPの時刻同期の仕組みによってずれが解消されていくものと思います。


ACL機能がないため踏み台攻撃に注意してください。