[Linux] 時刻を正確に合わせるためのNTP設定あれこれ | A Day In The Boy's Life

A Day In The Boy's Life

とあるエンジニアのとある1日のつぶやき。

サーバーの時刻は、その上位のミドルウェアやアプリケーションでも用いられるため、それが狂うとシステムトラブルを招く恐れがあります。

よくあるのが、サーバーの時刻が進んでいた場合にそれを元に戻すと、アプリケーションで取り扱うデータが過去のものなのに未来の時刻となり、データ自体に矛盾がでてしまうというようなものです。

また、DBシステムでリカバリを行う場合に、サーバー上での時間が前後したがために、DBシステム自体がどの時点にリカバリをすればよいのかわからなくなって正常に復旧できないというような場合もあります。


そのように、たかが時刻といっても大事な設定となるわけですが、定期的に手動で設定するのも面倒なので、自動化してくれるNTPの設定方法をまとめてみたいと思います。



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


サーバー上でNTPを動かすためには、NTPのパッケージのインストールと設定ファイルをいくつか変更することで簡単に他のサーバーと時刻を同期させることができます。

NTPのパッケージについては、RedHatLinuxやCentOSを使っているのであれば、yumコマンドからインストールできるでしょう。


※ yumコマンドの使い方については「yumによるRPMパッケージの更新管理 」も参照してみてください。


時刻を合わせたいサーバーの指定方法は、NTPの設定ファイル(/etc/ntp.conf)の「server」ディレクティブを編集することで可能となります。

例えば、CentOSのntp.confのデフォルトでは下記のように指定されています。


server 0.centos.pool.ntp.org
server 1.centos.pool.ntp.org
server 2.centos.pool.ntp.org

上記のように複数指定することも可能です。

直接外部のNTPサーバーを指定することもできますが、全てのサーバーが外部にあるNTPサーバーを参照するのも非効率なので、環境内(社内とか)にあるNTPサーバーを参照するような構成をとるのが良いでしょう。


NTPサーバーはググってみればいくつかすぐに見つけることはできますが、有名どころでは独立行政法人 情報通信研究機構(NICT) が提供するNTPサーバーなどがあります。

NICTは「Stratum 1」のNTPサーバーになります。

Stratumは、NTPサーバーにおける階層構造をあらわしたもので、最上位のStratum 0は原子時計やGPSなど、正確な時刻を提供してくれるシステムをさしています。

Stratum 1はそれに直結されたNTPサーバーとなり、同様に正確な時刻を提供してくれる役割を持っています。


※ Stratumは提供する側で適当に名乗ることができるようなので、番号が若いから正確、番号が大きいから信頼できないという意味にはなりません。


Stratum 2のNTPサーバーの多くは、Stratum 1のNTPサーバーと時刻の同期を行っていますので、自分の環境でも最も近いNTPサーバーを探して指定しておくということでも問題ないでしょう。(消えてなくなると困りますので、ある程度信頼がおけるところが良いと思いますが)


適当なNTPサーバーを設定し、NTPデーモンを起動してみると時刻の同期が始まります。


# /etc/init.d/ntpd start
ntpd:時間サーバと同期中:                                [  OK  ]
ntpdを起動中:                                          [  OK  ]

NTPデーモンが正常に動いているかは、下記のコマンドで確認できます。


# ntpq -p
     remote           refid      st t when poll reach   delay   offset  jitter
==============================================================================
*192.168.0.100   ntp-a3.nict.go.  2 u  552 1024  377    1.409   -0.156   0.349

頭に「*」がついているサーバーが同期対象のサーバーです。

上記の場合は、環境内にあるNTPサーバーを指定していますが、そのNTPサーバーもNICTのサーバーを参照していることがわかります。(refidが参照元)

また、「st」欄がStratumになり、上記の場合はStratum 2のNTPサーバーという意味になります。


また、ntpdateコマンドでも問い合わせてみることができます。


# ntpdate -q 192.168.0.100
server 192.168.0.100, stratum 2, offset 0.000660, delay 0.02577
16 Mar 22:49:06 ntpdate[18891]: adjust time server 192.168.0.100 offset 0.000660 sec

-pオプションをつけて実行すると、NTPサーバーに問い合わせるだけで、サーバーの時刻合わせは行いません。



NTPサーバーのセキュリティ


これで時刻も正確になったし、めでたしめでたし・・・というわけにはいきません。

NTPでは、クライアントとサーバーの機能が一緒になっており、時刻を合わせることができる機能と、その時刻を他に提供する(時刻を他のサーバーから合わせられる)機能が動いてしまいます

時刻が参照されるぐらいどうってことないと思うかもしれませんが、極端に多くのリクエストが発生するとサーバーに負荷がかかってしまいますし、参照されることでそのサーバーをメンテナンスすることもできない、というような状態にもなってしまいます。


また、NTPにはntpdcというリモートのNTPサーバーのステータスや設定を変更するツールが付属しています。

適切なACLが書かれていない状況では、このntpdcコマンドによってリモートから設定が変更される可能性もあります。

例えば、NTPサーバー側でなんらアクセス制御を行っていない状態の場合


# ntpdc 192.168.0.100
ntpdc> sysstats
***Warning changing to older implementation
time since restart:     19
time since reset:       19
packets received:       0
packets processed:      1
current version:        1
previous version:       4
bad version:            0
access denied:          0
bad length or format:   0
bad authentication:     0
rate exceeded:          0

という形で、NTPサーバー側の情報を取得できます。

また、参照するNTPサーバーをリモートから追加することもできます。(詳細はここでは省略します)


ntpdc> addserver 192.168.0.200
Keyid: 100
MD5 Password:
***Warning changing to older implementation
done!

これで、変更を加えたNTPサーバーでは、上記のIPを新たに同期先としてリストに加えてしまいます。

設定を変更する際には、サーバー上のキーIDとパスワードが求められるのですが、設定を変更するだけでなく、ntpdateなどのクライアントとしてのコマンド以上に詳しい情報をクライアントに返すことになるため(詳細は、ntpdcコマンド実行時にhelpと入力すると表示されます)、必要性がない限りは制限をかけておいたほうが無難です。



クライアントからのリクエストの制御


先ほどのような問題があるため、用途に応じてNTPのリクエストを受付を制限したり、拒否したりする必要が出てきます。

設定ファイルのrestrictディレクティブにより、制限をかけたいIPやN/Wを指定することでその制御が行えます。


restrict default ignore
restrict 192.168.0.0 mask 255.255.255.0 nomodify notrap noquery

上記の場合、まず全てのリクエストを拒否の設定にし、192.168.0.xのセグメントからのみ時刻あわせを許可しています。

restrictディレクティブは、最後にマッチした条件が適用されるため、まず最初に全てを拒否し、後に許可したい設定を書いておきます

逆を言えば「restrict default ignore」を書いていないと意味がありません。

もし、上記のN/Wにマッチしないサーバーから時刻合わせをしようとすると・・・


# ntpq -p
     remote           refid      st t when poll reach   delay   offset  jitter
==============================================================================
 192.168.0.100   .INIT.          16 u    -   64    0    0.000    0.000   0.000

参照元(refid)が「.INIT.」になっており、同期ができていないことがわかります。

ntpdateコマンドで確認してみても


# ntpdate -q 192.168.0.100
server 192.168.0.100, stratum 0, offset 0.000000, delay 0.00000
16 Mar 22:49:28 ntpdate[18892]: no server suitable for synchronization found

のように、サービスが利用できないことが返されます。

時刻合わせを行うサーバーが限定されているのであればそのIPを、特定のN/Wに限定されているのであれば、そのN/W情報を設定しておけばよいと思います。


ただし、この設定はNTPクライアント(時刻を問い合わせるほう)と、NTPサーバー(時刻を返すほう)の共通の設定になります。

なので、問い合わせたいNTPサーバーと、問い合わせられるNTPクライアントのN/WやIPを設定しておく必要があります。

先ほどの例では、NTPサーバーとNTPクライアントが192.168.0.xのN/W上にいるのであれば問題ないですが、そうではない場合はどちらかのリクエストが拒否される結果となります。

NTPサーバーへの問い合わせだけを行いたい場合は、NTPサーバーのIPを直接指定しておいたほうがよいでしょう。



restrictディレクティブのオプション


restrictディレクティブにはいくつかのオプションがあり、それによってNTPのリクエストを制御することができます。

主なオプションは下記のとおりです。


- ignore
これは、先ほどの設定例にあったように全てのリクエストを拒否します。


- noquery
指定したN/Wからのntpq(デーモンの状態確認)とntpdc(デーモンの状態確認・設定変更)リクエストを無視します。

ただし、時刻の同期自体には問題ありません。


例)

# ntpq -p
     remote           refid      st t when poll reach   delay   offset  jitter
==============================================================================
*192.168.0.100   0.0.0.0         16 u   32  128    0    0.238    0.255   0.000

ntpqのコマンドの結果は返ってきますが、参照元(refid)やStratumの情報が正しく返ってきていないのがわかります。

ntpdcもリクエストを受け取れずにタイムアウトしています。


# ntpdc 192.168.0.100
ntpdc> sysinfo
192.168.0.100: timed out, nothing received
***Request timed out

- nomodify


指定したN/Wからのデーモンの設定変更(ntpdcコマンドの一部)のリクエストを無視します。

もちろん、時刻の同期は問題なくできます。


例)

# ntpq -p
     remote           refid      st t when poll reach   delay   offset  jitter
==============================================================================
*192.168.0.100   ntp-a3.nict.go.  2 u  243  256  377    0.274   -0.110   0.347

ntpqコマンドは、正しくデーモンの状態が確認されていることがわかります。

ntpdcコマンドでもサーバーの情報を参照するようなコマンドは実行可能です。


# ntpdc 192.168.0.100
ntpdc> sysinfo
***Warning changing to older implementation
system peer:          0.0.0.0
system peer mode:     unspec
leap indicator:       11
stratum:              16
precision:            -17
root distance:        0.00000 s
root dispersion:      0.00143 s
reference ID:         [0.0.0.0]
reference time:       00000000.00000000  Thu, Feb  7 2036 15:28:16.000
system flags:         auth monitor ntp kernel stats
jitter:               0.000000 s
stability:            0.000 ppm
broadcastdelay:       0.007996 s
authdelay:            0.000000 s

ただし、設定を変更しようとすると


ntpdc> addserver 192.168.0.200
Keyid: 100
MD5 Password:
***Warning changing to older implementation
***Permission denied

のように拒否されます。


- 参考
ntpd @ Stray Penguin