前口上

ntpdやchronyでは問い合わせ先NTPサーバをserverディレクティブに書くのが従来だが、serverディレクティブの代わりにpoolディレクティブを使うとそのFQDNに対してDNSラウンドロビンされたIPアドレス群を取得し、それぞれを問い合わせ先として使ってくれる。

つまり以下のようになる。

/etc/ntp.confの一部
# Use servers from the NTP Pool Project. Approved by Ubuntu Technical Board
# on 2011-02-08 (LP: #104525). See http://www.pool.ntp.org/join.html for
# more information.
pool ntp.nict.jp iburst

$ ntpq -p
     remote           refid      st t when poll reach   delay   offset  jitter
==============================================================================
 ntp.nict.jp     .POOL.          16 p    -   64    0    0.000    0.000   0.000
+ntp-b2.nict.go. .NICT.           1 u   48   64    7    5.821  -69.727  62.623
*ntp-b3.nict.go. .NICT.           1 u   59   64    3    7.504  -64.560  30.538
+ntp-a2.nict.go. .NICT.           1 u   49   64    7   10.237  -71.578  65.055
+ntp-a3.nict.go. .NICT.           1 u   55   64    7    8.362  -66.616  60.709

(ただし、chronyにpoolディレクティブが追加されたのは2015年4月のバージョン2からで、Linuxディストリビューション/バージョンによってはまだ1系が現役のものもありpoolディレクティブが使えなかったりする)

というわけで設定ファイルからserverディレクティブを削除し、poolディレクティブを1行追加してやることにする。また、削除した場所と同じ場所に追加してやりたい。
私はkickstartやpreseedを使う関係上、これをテキストエディタを使って書き換えるのではなく何らかのコマンドで書き換えてやることになる。
というわけでsedを使っているのだが、せっかくなのでワンライナーでやってみるかと。

途中経過

CentOS 7の/etc/chrony.confのserverディレクティブの箇所は以下のようになっている。

chrony.confの一部
# Use public servers from the pool.ntp.org project.
# Please consider joining the pool (http://www.pool.ntp.org/join.html).
server 0.centos.pool.ntp.org iburst
server 1.centos.pool.ntp.org iburst
server 2.centos.pool.ntp.org iburst
server 3.centos.pool.ntp.org iburst

これを受けた初期案。

sed -ri '0,/^(server|pool) / s/^(server |pool ).+$/pool ntp.nict.jp offline iburst/; /.pool.ntp.org/ d' /etc/chrony.conf

0,/^(server|pool) /で最初のserverディレクティブ行かpoolディレクティブ行(Fedora 23とか新しめのでは最初からpoolディレクティブが使われている)を捕まえてpool ntp.nict.jp offline iburstに置換し、残った.pool.ntp.org行を削除するというものである。

しかしUbuntu 14.04の/etc/ntpd.confを見るとserverディレクティブの箇所は以下のようになっている。
.pool.ntp.orgじゃないのがある。

ntp.confの一部
# Specify one or more NTP servers.

# Use servers from the NTP Pool Project. Approved by Ubuntu Technical Board
# on 2011-02-08 (LP: #104525). See http://www.pool.ntp.org/join.html for
# more information.
server 0.ubuntu.pool.ntp.org
server 1.ubuntu.pool.ntp.org
server 2.ubuntu.pool.ntp.org
server 3.ubuntu.pool.ntp.org

# Use Ubuntu's ntp server as a fallback.
server ntp.ubuntu.com

また最初の4行のあと少し離れてまた1行あるので、別案として持っていたserverディレクティブ全部置換して連続する重複行削除も使えないことがわかった。
# more information.のすぐ下にpoolを追加して他削除、なんてことも考えたがコメント行の文字列使うのはちょっと美しくない。

というわけで以下のページとにらめっこして考えてみた。
http://quruli.ivory.ne.jp/document/sed_4.1.2/sed-ja_3.html

完成

で、完成。
ntpdバージョン。1 2

sed -ri '/^(server|pool) / { x; /./ d; s/^.*$/pool -4 ntp.nict.jp iburst/ }' /etc/ntp.conf

chronyバージョン。2 3

sed -ri '/^(server|pool) / { x; /./ d; s/^.*$/pool ntp.nict.jp offline iburst/ }' /etc/chrony.conf

ついでにOpenNTPDバージョン。poolじゃなくてservers。

sed -ri '/^servers? / { x; /./ d; s/^.*$/servers ntp.nict.jp/ }' /etc/openntpd/ntpd.conf

serverディレクティブ行かpoolディレクティブ行だけに作用するよう、残りの部分は{}で囲む。
xでパターン空間(sedが処理中の文字列)とホールド空間(1つの文字列を保存できるsed内のクリップボードのようなもの)を入れ替え、/./にマッチする、つまり1文字以上あれば削除して次の行の処理に進む(dコマンド)。
残りはマッチしなかった場合、言い換えればパターン空間とホールド空間の1回目の入れ替えを行った時であり(ホールド空間は最初は空だから)、つまり最初のserverディレクティブ行かpoolディレクティブ行にぶつかった時、その行をsコマンドでpool -4 ntp.nict.jp iburstに書き換える、というものである。

実行してみるとさっきのUbuntu 14.04の/etc/ntpd.confも以下になる。

# Use servers from the NTP Pool Project. Approved by Ubuntu Technical Board
# on 2011-02-08 (LP: #104525). See http://www.pool.ntp.org/join.html for
# more information.
pool -4 ntp.nict.jp iburst

# Use Ubuntu's ntp server as a fallback.

かなり簡潔に書けたので満足である。



  1. -4はIPv4のみの問い合わせを行うオプション(ntpdのみで使用できる)。chronyだと必要なら起動時オプションを使うことになるだろう。 

  2. iburstは最初の数回の問い合わせを短い間隔で行うオプション(iburstがあろうがなかろうが最初の数回問い合わせが終わるまで結果を採用しないので、採用されるのが早くなる)。 

  3. offlineはchronydサービス起動時には問い合わせを行わない状態とするオプション(chronyのみで使用できる)。デフォルトゲートウェイとなるNIC接続時に問い合わせ先をoffline状態からonline状態に変更するスクリプト /etc/NetworkManager/dispatcher.d/20-chrony が自動で動いてくれるので接続されていればchronydは問い合わせを行ってくれる(CentOS 7で確認)。このオプションは特にモバイルなど常時ネットワークに接続されるわけではない環境では有用である。しかし例えばntpdateサービスもenableにしているとOS起動時の関係各サービスの起動順が変わり結果としてこのスクリプトがchronyd起動前に動いてしまい、OS起動後chronydは問い合わせを行ってくれないので注意。 

TOP