chrony(NTPd代替)の設定方法



●chronyとは

 CentOS7(RHEL7)からNTPに替わりchronyが時刻同期サーバ/クライアントとして採用されました。
RedHatより引用
 chronyはユーザースペースで実行するデーモンであるchronydとchronydを調整するコマンドラインプログラムであるchronycで構成されています。常時接続でない、もしくは常時電源が付いていないシステムでは、ntpdを使ったシステムクロックの調整は、比較的時間がかかります。これは、多くの小さな修正がクロックのずれと補正の観測に基づいてなされるためです。温度変化はシステムの電源を入れる際に大きくなる場合がありますが、これはハードウェアクロックの安定性に影響します。調節はシステムの起動のほんの数千秒以内に始まりますが、許容範囲の正確性は機器が温まっている場合の再起動では10秒、または要件や操作環境およびハードウェアによっては数時間という幅の時間がかかる可能性もあります。chronyはntpdとは異なるNTPプロトコルの実装で、システムクロックをより迅速に調整することが可能です。

●NTPデーモンの選択

 chronyは、頻繁にネットワーク接続が一時停止したり、断続的に切断され再接続されるようなシステムの場合に検討してください。たとえば、モバイルや仮想システムなどです。
 NTPデーモン(ntpd は、通常、常時接続のシステムの場合に検討してください。ブロードキャストまたはマルチキャストIPを使用する必要のあるシステム、またはAutokeyプロトコルでパケット認証を実行する必要のあるシステムの場合は、ntpdの使用を検討してください。chronyは、MD5、SHA1、またはより強力なハッシュ機能のあるメッセージ認証コード(MAC)を使用した対称鍵認証のみをサポートしますが、ntpdはPKIシステムの活用も可能なAutokey認証プロトコルもサポートします。AutokeyはRFC 5906で説明されています。

●ntpdとchronydの違い

 ntpdとchronydの大きな違いの1つは、コンピューターのクロックを管理するために使われるアルゴリズムにあります。chronydがntpdよりも優れている点は、以下のとおりです。

 chronydは外部の時間参照が断続的にアクセス可能な場合でも機能しますが、ntpdが機能するには、規則的な時間参照のポーリングが必要になります。
 chronydはネットワークの混雑が長時間にわたる場合でも機能します。
 chronydのクロックの同期は通常より高速で、時間の正確性もより高いものです。
 chronydは、水晶振動子の温度変化などによってクロックのレートが突然変更しても素早く適応します。一方、ntpdの場合は、落ち着くまでに長時間かかる場合があります。
 chronydはデフォルト設定では、他の実行中のプログラムを乱さないように、クロックがシステム起動時に同期された後は、時間を更新しません。ntpdも時間を更新しないように設定できますが、クロックの調整に異なる手段を用いる必要があり、これは不利益となる面があります。
 chronydはLinux上のクロックのレートを幅広い範囲で調整できるため、たとえば仮想マシン上など、壊れたクロックもしくは不安定なクロックのあるマシン上でも操作が可能になります。

 chronydでは可能で、ntpdではできない点は、以下のとおりです。

 chronydは、時間修正の方法が手動での入力のみという分離したネットワークのサポートを提供します。たとえば、管理者がクロックを見ている場合などです。chronydは、異なる更新で修正されたエラーを見てコンピューターが時間を進めたり遅らせたりするレートを予測し、これを使ってコンピュータークロックを調整することができます。
 chronydは、コンピューターの電源を切った際に時間を維持するハードウェアクロックを進めたり遅らせたりするレートを計算するためのサポートを提供します。システムが起動して、リアルタイムのクロックから取ってきた時間の調整された値を使ってシステム時間を設定する際に、このデータを使うことができます。このガイドの執筆時点でこれが可能なのは、Linuxのみです。

 ntpdでは可能でchronydではできない点は、以下のとおりです。

 ntpdは完全にNTPバージョン4(RFC 5905)をサポートします。これには、ブロードキャスト、マルチキャスト、manycastのクライアントおよびサーバー、さらに孤立モードが含まれます。また、公開鍵の暗号化に基づく特別の認証スキームもサポートします(RFC 5906)。chronydはNTPバージョン3(RFC 1305)を使用します。これは、バージョン 4と互換性があります。
 ntpdには多くの参照クロック用のドライバーが含まれていますが、chronydはgpsdなどの他のプログラムに依存して参照クロックからデータにアクセスします。

●chronyのインストールと起動

 参考URL:Chrony によるNTP設定(CentOS7.4)
 参考URL:chrony の時刻同期を監視
 参考URL:CentOS7の時刻同期 chronyについて

  CentOS 7ではOSインストール時にインストールされていなければyum install chronyでインストールすることができます(CentOS 6はEPEL上にあります)。
 chronyのデーモンはchronydです。chronyをインストールした時点でchronydはenabled、つまりシステム起動時に自動起動する状態になっていますが、インストール直後は起動していません。
 手動で起動させる場合はsystemctl start chronydを実行します。
 なお、chronydとntpdの両方がenabledになっている場合、システム起動後はchronydだけが起動した状態となります。手動で両方を起動した場合、後から起動した方が起動状態になり、先に起動した方は停止状態となります。
 ntpdを使いたい場合は忘れずにchronyをアンインストールするかsystemctl disable chronydでchronydがシステム起動時に自動起動しないようにする必要があります。
 ちなみにntpd起動中は-uオプションを付けないとntpdateを実行できませんでしたが、chronyd起動中は-uオプションがなくてもntpdateを実行できます。

●chronyの設定

 chronyの設定ファイル/etc/chrony.confはntpdの設定ファイル/etc/ntp.confと同じフォーマットであり設定項目も非常に似ています。
 /etc/chrony.confはインストール直後の場合、下記のようになっています。
 初期状態のままではNTPサーバにはなりません。問い合わせに行くNTPサーバもそのままでよければ設定を変更せずに起動するだけです。
# vi /etc/chrony.conf
# Use public servers from the pool.ntp.org project.
# Please consider joining the pool (http://www.pool.ntp.org/join.html).
# 下記サーバのうち1台には「trust」オプションを追記します。
# 「server」で始まる記載方法は、CentOS 7の場合のようです。
server 192.168.0.254 iburst trust ← 同期したいNTPサーバを指定
server 192.168.0.253 iburst ← 同期したいNTPサーバを指定

# 「pool」で始まる記載方法は、CentOS 8の場合のようです。
pool 192.168.0.254 iburst trust ← 同期したいNTPサーバを指定
pool 192.168.0.253 iburst ← 同期したいNTPサーバを指定
# Ignore stratum in source selection.
stratumweight 0
# Record the rate at which the system clock gains/losses time.
driftfile /var/lib/chrony/drift
# Enable kernel RTC synchronization.
rtcsync ← システムクロックの時刻をハードウェアクロックに書き出す。ただし、仮想サーバ上では効果がないらしい。
# In first three updates step the system clock instead of slew
# if the adjustment is larger than 10 seconds.
makestep 1.0 3 ← chrony起動後、1.0秒以上のズレが3回あった場合、slewモードにかわりstepによる時刻調整をする
# Allow NTP client access from local network.
#allow 192.168/16 ← NTPクライアントからの接続を制限する場合の設定
# Listen for commands only on localhost.
bindcmdaddress 127.0.0.1
bindcmdaddress ::1
# Serve time even if not synchronized to any NTP server.
#local stratum 10 ← Stratum1を最上位としてローカルがどこのNTPになるかを設定(NTPサーバとする場合は記述)
keyfile /etc/chrony.keys
# Specify the key used as password for chronyc.
commandkey 1
# Generate command key if missing.
generatecommandkey
# Disable logging of client accesses.
noclientlog
# Send a message to syslog if a clock adjustment is larger than 0.5 seconds.
logchange 0.5
logdir /var/log/chrony ← ログの出力先ディレクトリを指定
#log measurements statistics tracking ← 取得するログの種類を指定
 下記で設定項目のいくつかを説明します。

●NTPクライアントとしての設定

server
書式: server <NTPサーバ> [<オプション1> <オプション2> ...]
デフォルト: 指定なし
複数指定可能
 NTPクライアントとしてどのNTPサーバに時刻問い合わせに行くかを指定します。ntpdにもオプションは一部異なりますが同一の設定項目があります。
 オプションの中でiburstオプションは付けておく方がメリットがあります。chronydはiburstオプションの付いたNTPサーバに対して、起動直後に短い間隔で4回問い合わせをします(ntpdのiburstは8回)。NTPサーバの妥当性の判断には1回の問い合わせだけでは足りず数回を要するのですが、起動直後に4回問い合わせをすることによって妥当性判断が早く済み、結果として起動から時刻同期が行われるまでの時間が短くなります。

●時刻調整の設定

時刻調整の設定
rtcsync
書式: rtcsync
デフォルト: 指定なし
 コンピュータがマザーボード上に保持する時刻をハードウェアクロックと呼びますが、ピコ秒単位で動作するCPUなど相手に使用するには秒の小数点以下の桁数が足りないため、OSカーネルは起動時に、より高精度のソフトウェアクロックを生成します。これをシステムクロックと呼びます。
 ntpdはシステムクロックを問い合わせたNTPサーバの時刻に同期しますが、ハードウェアクロックは同期しません。ハードウェアクロックはさほど正確に時間を刻むわけではないので、時間経過とともにシステムクロックとのずれが大きくなっていきます。
 そこで、cronで定期的にシステムクロックの時刻をハードウェアクロックに書き出すhwclock -wを実行させるのが定番でした。
 一方、chronyでは設定ファイルにrtcsyncと書いておけばシステムクロックを11分置きにハードウェアクロックに書き出してくれます。
 ハードウェアクロックはリアルタイムクロックとも呼ばれ、rtcsyncのrtcはリアルタイムクロックの略です。
makestep
書式: makestep <何秒以上> <何回目まで>
デフォルト: 指定なし
 システムクロックの調整には、NTPサーバから取得した時刻にすぐに修正するstep調整と、他アプリへの影響が少ないようにシステムクロックのずれを徐々に修正するslew調整という2つの方式があります。
 chronydは基本的にはslew調整を行いますが、起動直後だけstep調整を行うようにすることができます。それがこのmakestepであり、続く1つ目の数字で何秒以上のずれがあればstep調整を行うのか、2つ目の数字で起動から何回目の同期までstep調整を行うのかを設定します。2つの数字両方の条件に一致している時はstep調整、そうでなければslew調整となります。
 ntpdではntpdサービス有効時にntpdateサービスも有効にしてntpdが動く前にntpdateを実行します、ということをしていたが、この機能があるためchronydサービス有効時にはntpdateサービスを有効にする必要はありません(ntpdでもtinkerで調整できます)。
 なお、chronydがslew調整中に強制的にstep調整させたい場合はchronyc -a makestepを実行します(ntpdateがインストールされているならntpdate <NTPサーバ>でも良いでしょう)。
maxslewrate
書式: maxslewrate 
デフォルト: maxslewrate 83333.333
 slew調整を最大どれだけの速さで行うかを決定する設定項目です。最大と言っても、大抵そのペースで動作しますが、slew調整が行われている間は1秒間に設定したslewレートの100万分の1、NTPサーバから取得した時刻に近づくように調整されます。
 つまり、デフォルト値の83333.333なら1秒間で83333.333/1000000 = 1/12秒だけ近きます。言い換えればシステムクロックが遅れていれば1秒ごとに13/12秒、早ければ1秒ごとに11/12秒、システムクロックが進むようになるということです。
 一方、ntpdのslewレートは500で固定です。
 つまり、1秒間で1/2000秒だけNTPサーバから取得した時刻に近づきます。
 特に、一部の仮想環境ではそれでは追いつかないのでchronyでは大胆に大きな数値に設定されている、ということのようですが、物理環境でもslewレート500じゃどうにもならないこともままあるようです。

●NTPサーバとしてのアクセス制御設定
port
書式: port 
デフォルト: port 123
 chronydはntpdとは違い、設定によりNTPリクエストの待ち受けUDPポート番号を変更することができます。ただし、SELinuxが有効な場合はsemanage port -a -t ntp_port_t -p udp <ポート番号>を実行する必要があります(実行するにはpolicycoreutils-pythonをインストールしておくこと)。 ここでport 0を指定するとNTPサーバとして動作せず、NTPクライアントとして動作することになります。
 この設定項目でポート番号を変更したchronydには、server設定項のオプションとして「port <ポート番号>」を指定することで時刻問い合わせが可能です。
 ntpdでは問い合わせに行く時のポートも123だが、chronydは問い合わせには空いている適当なポートを使うためportの設定値には影響されません(問い合わせ時のポート番号を固定するための「acquisitionport <ポート番号>」という設定項目もあります)。
allow / deny
書式:
allow [all] 
deny [all] 
デフォルト: 指定なし(全IPアドレスからのアクセスを禁止)
複数指定可能
 ntpdではrestrictで書いていた、NTPサーバとしてどのコンピュータにアクセスさせるか、の設定です。
 ntpdのrestrictではいくつかの項目のアクセス制御ができました、chronyではシンプルにNTPクライアントからのアクセスを許すかどうかだけです。
 allowに設定されたIPアドレスやサブネットはアクセスが許可され、denyに設定されたIPアドレスやサブネットはアクセスが許可されません。どちらも複数書くことができ、上にあるものが優先順位が高い。ただし、allを付けると上にあるものを上書きして指定されたIPアドレスやサブネットを許可/禁止することになります。
 公式ユーザガイドにある例では
allow 1.2.3.4
deny 1.2.3
allow 1.2

は、1.2.3.4は許可、それ以外の1.2.3.0/24は禁止、それ以外の1.2.0.0/16は許可ですが、
allow 1.2.3.4
deny 1.2.3
allow all 1.2
は、1.2.0.0/16はすべて許可になります。
 また、この例の通りいくつかの省略記法が使用できます。
 x.y.zと書いてあればx.y.z.0/24のことです。
 x.y.z/22という書き方もできます。これは当然x.y.z.0/22のことです。
 allowとだけ書いてあればallow 0.0.0.0/0と同義となります。
bindaddress
書式: bindaddress 
デフォルト: 指定なし(*と::で待ち受け)
IPv4とIPv6で1つずつ指定可能
 特定のIPアドレスをバインドするための設定項目です。
 ここで指定したIPアドレスへの接続のみと通信するようになります。
 確認はss -nplu | grep chronydです。

●NTPサーバ

 ネットワーク内に1台以上設定します。
/etc/chrony.conf
server ntp.nict.jp iburst
server 0.jp.pool.ntp.org iburst
server 1.jp.pool.ntp.org iburst
stratumweight 0
driftfile /var/lib/chrony/drift
rtcsync
makestep 1.0 3
allow 192.168.0.0/24 ← すべてのコンピュータが所属するサブネット
bindcmdaddress 127.0.0.1
bindcmdaddress ::1
keyfile /etc/chrony.keys
commandkey 1
generatecommandkey
noclientlog
logchange 0.5
logdir /var/log/chrony
log measurements statistics tracking


●NTPクライアント

 NTPサーバを除く、すべてのコンピュータで設定します。
/etc/chrony.conf
server ntp1 iburst ← 立てたNTPサーバのホスト名
stratumweight 0
driftfile /var/lib/chrony/drift
rtcsync
makestep 1.0 3
port 0
bindcmdaddress 127.0.0.1
bindcmdaddress ::1
keyfile /etc/chrony.keys
commandkey 1
generatecommandkey
noclientlog
logchange 0.5
logdir /var/log/chrony
log measurements statistics tracking


●chronyの同期確認方法

 参考URL:chrony の時刻同期を監視
 参考URL:32.2. chrony の同期確認

 上記URLには「トラッキングの確認」「ソースの確認」「ソースの統計情報の確認」「システムクロックを手動で調整する」が記載されており役立つと思います。
 chrony の追跡を確認するには、下記コマンドを実行します。
$ chronyc tracking
Reference ID    : 7F7F0101 ()
Stratum         : 10
Ref time (UTC)  : Wed Jul 14 01:10:12 2021
System time     : 0.028182456 seconds fast of NTP time
Last offset     : +0.040092021 seconds
RMS offset      : 0.269157678 seconds
Frequency       : 40.577 ppm fast
Residual freq   : +0.000 ppm
Skew            : 0.000 ppm
Root delay      : 0.000000000 seconds
Root dispersion : 0.000000000 seconds
Update interval : 64.1 seconds
Leap status     : Normal
 chronyd がアクセスしている現在の時間ソースの情報を表示するには、下記コマンドを実行します。
$ chronyc sources
MS Name/IP address         Stratum Poll Reach LastRx Last sample               
===============================================================================
^- *******.bigbang.mydns.jp      1   6   377    53  +6898us[+6898us] +/-   23ms
^* xxxxxxx.bigbang.mydns.jp      2   6   377    56  +6771us[  -30ms] +/-   24ms
^x 2001:ce8:78::2                1   6   377    34   -963ms[ -963ms] +/- 8575us

任意の引数 -v (verbose (詳細) の意) を指定できます。
 chronydが現在調べている各ソースに関するドリフト量とオフセット推定プロセスの情報を表示するには、下記コマンドを実行します。
# chronyc sourcestats
210 Number of sources = 3
Name/IP Address            NP  NR  Span  Frequency  Freq Skew  Offset  Std Dev
==============================================================================
*******.bigbang.mydns.jp    8   4   453   -115.934    153.103  -8475us    11ms
xxxxxxx.bigbang.mydns.jp    6   3   324   -110.774    255.739  +2004us  8272us
ntp-a3.nict.go.jp           4   3   194    -80.739     57.178   -956ms   290us

任意の引数 -v (verbose (詳細) の意) を指定できます。


●Can't synchronise: no majority

 参考URL:chronyd[]: Can't synchronise: no majority

 下記のようにchrony.confを修正しました。
# vi /etc/chrony.conf
server 192.168.0.254 iburst trust ← 「trust」を追記
server 192.168.0.253 iburst
server ntp.nict.jp iburst

# systemctl restart chronyd
 これで「Can't synchronise: no majority」が記録されなくなれば良いのですが。

●Fatal error : Could not parse allow directive at line 26 in file /etc/chrony.conf

 CentOS Stream 8でUpdateを実施したところ、Chronyが自動起動できなくなりました。
Fatal error : Could not parse allow directive at line 26 in file /etc/chrony.conf
 Chronyは
chrony.x86_64 4.1-1.el8
 ↓
chrony.x86_64 4.2-1.el8
にアップデートしていました。
 allowディレクティブの記載方法に問題があるようです。 
 下記のように変更(「,(カンマ)」による記載もエラーとなりました。)することにより、問題が解決しました。
# vi /etc/chrony.conf
allow 10.0.0/24 192.168.0.0/16
 ↓
allow 10.0.0/24
allow 192.168.0.0/16