ようやく,満身創痍って感じでなんとかGarmin GPS 15xLを使って1ppsをntpdに食わせて同期させてstratum 1をまっとうに実現する準備ができました。本当は,ここまでくるのは一瞬で終わっているはずだったのに,なぜかワナにはまりまくって遠回りをしまくっていました。何かがおかしいですが,気にしたら負けですので不幸な過去はなかったことにします。
これまで,私が使ってきた/etc/ntp.confはきわめて単純で,
server 127.127.20.1 mode 0 minpoll 4 maxpoll 4 prefer
fudge 127.127.20.1 flag1 1 flag3 1 time2 0.0 refid GPS
という2行だけでした。
127.127.20.1というのは,20のところがドライバの番号,1のところがデバイスの番号です。この場合は,NMEAドライバ(driver 20)で,/dev/gps1を参照する,という意味です。デバイスファイルは,/etc/devfs.confに
link cuau0 gps1
とだけ書いて,
service devfs start
とやればOKです。これで,/dev/gps1から/dev/cuau0にシンボリックリンクが張られます。いっぱいオプションがありますが,ざっと復習をしておくと以下のとおりです。
mode 0 --> 通信速度 4800bps。mode 16とすると9600bps
minpoll 4 --> ポーリングの最小間隔で2^4 =16秒
maxpoll 4 -->ポーリングの最大間隔で2^4 =16秒
minとmaxを上のように設定の場合は,常に16秒間隔でサーバーへ問い合わせをする。
prefer --> この設定が優先される。
fudge --> 指定したホストまたはドライバを独立したntpサーバーとして宣言する。
flag1 1 --> 1でPPSを使う
flag3 1 --> 1でカーネルのPPS diciplineを使う。
FreeBSDならば,/usr/src/sys/i386/conf/GENERICを適当にコピーしてoptions PPS_SYNCを追加してコンパイルして作ったカーネルが必要。
time1 --> PPSのずれの調整(sec)
time2 --> NMEAコードとのずれの調整(sec)
refid --> ntpq -pでリストを表示したときに表示されるサーバーのID
なんだかわからんけれども,とりあえずntpサーバーになればよい,というのであれば上記の2行だけでOKです。しかし,サーバーごとに絶対時刻が違うと困る,という場合は,これではどうにもなりません。
職場のntpサーバーはどうやらほかのntpdと比較してきっちり1秒ずれています。いったいどのサーバーが正しいのかまったくわかりませんが,こうなったら,ntpdを較正するしかありません。
幸いにも,FreeBSD 10.3Rでntpdを較正する方法を
懇切丁寧に紹介している人がおられたので,これを参考にさせてもらいました。というか,これをそのままなぞっただけです。こういうとき,インターネットって便利だと思います。ありがたいことです。
ntpは複数のサーバーを参照して多数決でもっともらしい時刻を見つけようとする仕組みを持っています。これを利用してNMEAドライバやPPSドライバのtime1やtime2の補正値を決めるのが目的です。なるほど,こういうふうにして較正するとは考えもしませんでした。このために,公開ntpサーバーに接続して統計値を収集します。
公開ntpサーバーに接続するために,まずは,ローカルのルーターの123番ポートを開きます。Century SystemsのFuture Net XRシリーズのルーターをここ10年以上使い続けていますが,このシリーズでは,ルーターがntpサーバーになることができます。ところが,ルーターがntpサーバーになっているとなぜか外部のntpサーバーに正しくアクセスできませんでした。何か,間違った使い方をしている可能性がありますが,とりあえず,ルーターのntpサーバーは停止しておくのが平和そうです。
余談ですが,古い機種ではntpdのバージョンも古くて,うっかりフィルタ設定を誤るとntpdのmonitor機能を使ったDDoS攻撃の踏み台にされてしまいます。ルーターの機能はROMに書き込まれているのでntpdのバージョンアップを自分でやるというわけにはいきません。古いルーターではntpdは停止しておくのが平和かつ安全そうです。
公開ntpサーバーは多くの人が接続してくるため,あまり頻繁にポーリングすると迷惑をかけてしまいます。NICTのサーバーは1時間に
20回以上のアクセスには事前承認が必要ということですので,maxpollは8以上に設定しなくてはなりません。ほかの公開ntpサーバーについてはよくわかりませんが,maxpollが8より小さくてよい,とは思えませんのでNICTのサーバーと同じ設定として,minpoll 6 maxpoll 8とすることにします。
まずは,公開ntpサーバーへ問い合わせするように設定をします。
#
restrict default ignore
# <-- 誰からも接続させない
restrict 127.0.0.1
# <-- ローカルホストからの接続を許可
restrict 192.168.0.0 mask 255.255.0.0 nomodify notrap
# <-- LANからの接続を許可
server 127.127.1.1 minpoll 4
# <-- ローカルのRTCに同期
fudge 127.127.1.1 stratum 13 refid ALOCAL
# <-- 最悪の事態を考えてのことなのでstratumは悪い数字にしておく
restrict ntp1.lan.jp notrust
server ntp1.lan.jp iburst minpoll 6 maxpoll 6
# <-- ローカルネットワーク内のntpサーバーを参照する。notrustとして信用しない設定。
# 信用しないので結果的には同期には使われない(たぶん)。
restrict ntp1.jst.mfeed.ad.jp noquery nomodify nopeer notrap
server ntp1.jst.mfeed.ad.jp minpoll 6 maxpoll 8
restrict ntp.nict.jp noquery nomodify nopeer notrap
server ntp.nict.jp minpoll 6 maxpoll 8
restrict s2csntp.miz.nao.ac.jp noquery nomodify nopeer notrap
server s2csntp.miz.nao.ac.jp minpoll 6 maxpoll 8
# <-- 公開ntpサーバーを設定。
disable monitor
logconfig =all
logfile /var/log/ntpd.log
# <-- ログの設定。=allは=の後ろに空白をあけてはいけないらしいが,ホンマか?
statistics loopstats peerstats clockstats
statsdir /var/db/ntp
filegen loopstats file loopstats type day enable
filegen peerstats file peerstats type day enable
filegen clockstats file clockstats type day enable
# <-- 統計値の出力の設定。
# <-- clockstats: 参照している時計の情報
# <-- loopstats: ローカル時計の更新時に出力される時刻情報
# <-- peerstats: 通信相手との統計値の更新時に出力される時刻情報
# serial 4800bps (mode 0)
server 127.127.20.1 mode 0 noselect
fudge 127.127.20.1 refid AGPS
#
# serial DCD
server 127.127.22.1 minpoll 4 noselect
fudge 127.127.22.1 refid APPS
NMEAと1PPSはnoselectとしているので動作はするけれども時刻同期には使われません。これによって,公開サーバーとの時刻のずれの統計量を記録して,そのずれをtime1とかtime2で補正すればよい,というわけです。実際に使うのはpeerstatsがあれば十分そうな感じです。これで1, 2日ほど放置して動作させてログを収集します。
