ネットワークタイムプロトコルデーモン

提供: ArchWiki
Network Time Protocolから転送)
ナビゲーションに移動 検索に移動

関連記事

ネットワークタイムプロトコル(NTP) は GNU/Linux のソフトウェアクロックをインターネット上の時刻サーバーと同期するのに使われる最も一般的な方法です。変動的なネットワークの遅延を軽減し、インターネットを使って数十ミリ秒の範囲で時刻を維持できるように設計されています。ローカルエリアネットワークの場合、一ミリ秒まで正確性を保てます。

NTP プロジェクト は NTP という名前のプロトコルのリファレンス実装を提供しています。NTP の代わりになるものとして、ダイアルアップフレンドリで常時オンラインではない環境用に設計されている Chrony と、OpenBSD プロジェクトの OpenNTPD があります。

この記事ではクライアント・サーバー両方で NTP デーモンを設定・起動する方法を説明しています。

インストール

公式リポジトリにある ntpインストールしてください。

設定

メインのデーモンは ntpd で、/etc/ntp.conf から設定を行います。

ntp パッケージのデフォルトの設定ファイルでは、設定のカスタマイズを行わなくてもクライアントモードで ntpd が動作するようになっています。デフォルト設定を使って起動したい場合は、#使用方法 までスキップできます。

以下ではメイン設定のアイテムのカスタマイズについて説明しています。マニュアルページも参照してください: ntp.conf(5) や関連する man {ntpd|ntp_auth|ntp_mon|ntp_acc|ntp_clock|ntp_misc}

NTP サーバーへの接続の設定

/etc/ntp.conf を手動で設定したい場合は、まずマシンが同期するサーバを設定してください。

NTP サーバは階層的なシステムによって strata と呼ばれるたくさんのレベルにクラス分けされています。その定義は、独立したタイムソースとされるデバイスは stratum 0 ソース、stratum 0 のデバイスに直接接続しているサーバーを stratum 1 ソース、stratum 1 ソースに接続しているサーバーを stratum 2 ソース、と続きます。

サーバーの stratum は正確性や信頼性を表しているわけではないことを理解する必要があります。一般的に、stratum 2 のサーバーが時刻同期に使われます: どのサーバーに接続するのかまだ決めてない場合、pool.ntp.org サーバー (alternative link) を使って一番地理的に近いサーバープールを選んで下さい。

サンプル:

/etc/ntp.conf
server 0.jp.pool.ntp.org iburst
server 1.jp.pool.ntp.org iburst
server 2.jp.pool.ntp.org iburst
server 3.jp.pool.ntp.org iburst

iburst オプションは推奨です。最初に試行した時に接続できなかったときだけパケットのバーストを送信するようになります。burst オプションは常時バーストを送信するので、許可を得ているときにだけ使って下さい。さもないとブラックリストに入れられてしまう可能性があります。

あなた自身の NTP サーバーの設定

NTP サーバーを設定する場合、サーバーとして local clock を追加する必要があります。これによりインターネットアクセスを失った時でも、ネットワークへの時刻の提供を続行することができます。(fudge コマンドを使って) stratum 12 サーバーとして local clock を追加すればインターネットアクセスが失われない限り使用されません (stratum 15 まで設定することができます):

server 127.127.1.1
fudge  127.127.1.1 stratum 12

次に、restrict コマンドを使ってあなたのサービスに接続できるクライアント (localhost もクライアントとして見なされます) を制限するルールを定義します。あなたのファイルには次のような行がすでに存在するはずです:

restrict default nomodify nopeer noquery

これで誰も何も変更できなくなり時刻サーバーの状態の問い合わせも制止されます: nomodifyntpd (と ntpq または ntpdc) の再設定を無視し、noqueryntpd (と ntpq または ntpdc) の状態データのダンプを防ぎます

また、他のオプションを加えることも可能です:

restrict default kod nomodify notrap nopeer noquery
ノート: これは他の人々があなたの時刻サーバーに問い合わせるのを許可します。noserve を追加して時刻の提供を止めて下さい。また ntpq と ntpdc クエリ以外の全てのパケットをブロックするので時刻同期もブロックされます。

"restrict" オプションの完全なドキュメントは man ntp_acc にあります。詳しい説明は https://support.ntp.org/bin/view/Support/AccessRestrictions を参照してください。

次の行のように、サーバーへの接続を許可する IP を ntpd に伝える必要があります; NTP サーバーを設定しない場合はこのままで問題ありません:

restrict 127.0.0.1

DNS 解決を IPv6 ネームスペースに強制したい時は、IP アドレスやホストネームの前に -6 を書いて下さい (-4 は IPv4 を強制します)。例:

restrict -6 default kod nomodify notrap nopeer noquery
restrict -6 ::1    # ::1 is the IPv6 equivalent for 127.0.0.1

最後に、ドリフトファイル (時計の時刻のズレを記録します) と任意でログファイルの場所を指定してください:

driftfile /var/lib/ntp/ntp.drift
logfile /var/log/ntp.log

基本的な設定ファイルは以下のようになります:

/etc/ntp.conf
server 0.pool.ntp.org iburst
server 1.pool.ntp.org iburst
server 2.pool.ntp.org iburst
server 3.pool.ntp.org iburst

restrict default kod nomodify notrap nopeer noquery
restrict -6 default kod nomodify notrap nopeer noquery

restrict 127.0.0.1
restrict -6 ::1  

driftfile /var/lib/ntp/ntp.drift
logfile /var/log/ntp.log
ノート: ログファイルの定義は必須ではありませんが、ntpd の操作のフィードバックを得るのはどんなときでも良い考えです。

使用方法

このセクションでは ntpd やその他の ntp パッケージに入っているコマンドの使い方を扱います。

デーモンとして使う

NTP デーモンを起動する基本コマンドは:

# ntpd

ただし、これだと root としてバックグラウンドで動作します。このため、user オプションを毎回指定するべきです:

# ntpd -u ntp:ntp 

#systemd サービス も見て下さい。

デーモンが正しく同期を実行しているか確認する

ntpq を使って設定されたピアの一覧を見て下さい:

$ ntpq -p

delay, offset, jitter のカラムがゼロではないはずです。ntpd が同期しているサーバーにはアスタリスクが前に付けられます。ntpd が同期するサーバーを選ぶまで数分間かかることがあります。17分 (1024秒) 後に確認してみてください。

デーモンを使わない

デーモンを使わずにシステム時刻を同期させることも可能です。ただし、この方法は数日以上再起動を行わないようなマシンには相応しくありません。システム時刻を一度だけ同期するには、ntpd を起動する代わりに、次を実行してください:

# ntpd -q

-q フラグは ntpd で時刻を一度だけ設定して終了します。つまりデーモンは起動しません。この操作が失敗した場合、システムクロックは同期されません。

ノート: 上のコマンドは今はもう廃止された ntpdate コマンドと同じ働きをします。

また、システムプロセスの実行を保護するために、システム時刻と ntp サーバーの時刻が所与の閾値以上に食い違っている場合はシステム時刻は同期されません (いわゆる panic-gate)。ただし、-g オプションを使うことでこの閾値は無効にすることができ制限を越えることができます (時刻を初めて設定するときやハードウェアクロックが誤っている場合など)。

自動起動

systemd サービス

ブート時に systemd によって ntpd を自動起動することが可能です。

ブート時にデーモンを起動する

ntp パッケージには systemd 用に ntpd.service が入っています。このサービスを systemctl を使ってブート時にデーモンを起動してください。

もしくは次のコマンドを使って下さい:

起動毎に同期する

警告: サーバーや、数日間電源を落とさないようなマシンではこの方法は非推奨です。

ntp パッケージには ntpdate.service が入っています。このサービスを systemd によって有効化して起動毎に時刻を同期するようにできます。この oneshot サービスは、一度時刻同期が完了したらもうデーモンを起動し続ける必要がない場合に助けになる選択肢になります。

同期した時刻をハードウェアクロックにも書き込む必要があるときは、systemd#ユニットファイルの編集 に書かれているように既存のユニットを設定してください:

/etc/systemd/system/ntpdate.service.d/hwclock.conf
[Service]
ExecStart=/usr/bin/hwclock -w

それから起動してください。

ネットワーク接続時

ntpd をネットワークマネージャによって起動させることも可能です。こうすることでコンピュータがオンラインのときだけデーモンが動くようになります。

Netctl

以下の行をあなたの netctl プロファイルに追加してください:

ExecUpPost='/usr/bin/ntpd || true'
ExecDownPre='killall ntpd || true'
ノート: #使用方法 で説明されているように ntpd コマンドのオプションをカスタマイズすることを推奨します。

NetworkManager

NetworkManager の dispatcher スクリプトを使ってネットワーク接続にあわせて ntpd デーモンを立ち上げたり終了することができます。公式リポジトリから networkmanager-dispatcher-ntpdAUR をインストールしてください。

Wicd

Wicd の場合、postconnect に起動スクリプトを、predisconnect ディレクトリに停止スクリプトを作成してください。スクリプトは忘れずに実行可能にしてください:

/etc/wicd/scripts/postconnect/ntpd
#!/bin/bash

/usr/bin/ntpd &
-or-
systemctl start ntpd &
/etc/wicd/scripts/predisconnect/ntpd
#!/bin/bash

killall ntpd &
-or-
systemctl stop ntpd &
ノート: #使用方法 で説明されているように ntpd コマンドのオプションをカスタマイズすることを推奨します。

Wicd#スクリプト も参照。

ヒントとテクニック

GPS で ntpd を使う

GPS から時刻を取得するように ntpd を設定する方法が書かれたネット上の記事は大抵 SHM (共有メモリ) を使うことを推奨しています。しかしながら、ntpd バージョン 4.2.8 からはさらに良い方法が存在します。直接 gpsd に接続するため、gpsd をインストールしてください。

以下の行を /etc/ntp.conf に追加:

/etc/ntp.conf
#=========================================================
#  GPSD native ntpd driver
#=========================================================
# This driver exists from at least ntp version 4.2.8
# Details at
#   https://www.eecis.udel.edu/~mills/ntp/html/drivers/driver46.html
server 127.127.46.0 
fudge 127.127.46.0 time1 0.0 time2 0.0 refid GPS

gpsd が動作していれば上記で問題なく動作します。ローカルソケットを使って gpsd に接続し、返ってきた "gpsd_json" オブジェクトを問い合わせます。

セットアップをテストするには、まず以下を実行して gpsd が動作していることを確認してください:

$ cgps -s 

それから数分待ってから ntpq -p を実行します。ntpdgpsd と対話できていれば以下のように表示されます:

$ ntpq -p
remote           refid            st t when poll reach   delay   offset  jitter
 ==================================================================================
*GPSD_JSON(0)    .GPS.            0 l   55   64  377    0.000    2.556  14.109
ヒント: reach カラムが 0 の場合、ntpdgpsd と通信できていません。さらに数分間待ってから再度実行してみてください。しばらく時間がかかることがあります。
ノート: ntpd は GPS デバイスの名前が /dev/gps0 などとなっていることを前提としています。USB で GPS デバイスを接続している場合、/dev/ttyUSB0 という名前になるため、シンボリックリンクを作成 (ln -s /dev/ttyUSB0 /dev/gps0) してリンクを張った /dev/gps0 に対して gpsd を実行しないと GPSD_JSON 行が正しく機能しません。

chroot で実行する

ノート: ntpd should be started as non-root (default in the Arch Linux package) before attempting to jail it in a chroot, since chroots are relatively useless at securing processes running as root.

新しいディレクトリ /etc/systemd/system/ntpd.service.d/ を作成してその中に customexec.conf という名前のファイルを以下の内容で追加してください:

[Service]
ExecStart=
ExecStart=/usr/bin/ntpd -g -u ntp:ntp -i /var/lib/ntp

そして /etc/ntp.conf を編集して driftfile のパスを実際の root ではなく chroot ディレクトリの相対パスに変えて下さい:

driftfile       /var/lib/ntp/ntp.drift

driftfile       /ntp.drift

に変えて下さい。適切な chroot 環境を作成してください。getaddrinfo() を動作させるために適切なディレクトリとファイルを (root で) 作成し:

# mkdir /var/lib/ntp/etc /var/lib/ntp/lib /var/lib/ntp/proc
# mkdir /var/lib/ntp/usr /var/lib/ntp/usr/lib
# touch /var/lib/ntp/etc/resolv.conf /var/lib/ntp/etc/services

そして上記のファイルをバインドマウントしてください:

/etc/fstab
...
#ntpd chroot mounts
/etc/resolv.conf  /var/lib/ntp/etc/resolv.conf none bind 0 0
/etc/services	  /var/lib/ntp/etc/services none bind 0 0
/lib		  /var/lib/ntp/lib none bind 0 0
/usr/lib	  /var/lib/ntp/usr/lib none bind 0 0
/proc		  /var/lib/ntp/proc none bind 0 0
# mount -a

最後に、デーモンを再起動してください。再起動したら /proc/{PID}/root のシンボリックリンク先をチェックすることでデーモンプロセスが chroot されてることを確認できます:

# ps -C ntpd | awk '{print $1}' | sed 1d | while read -r PID; do ls -l /proc/$PID/root; done

/ ではなく /var/lib/ntp にリンクしているはずです。

ntpd は読み書きをあまり頻繁に行わないため、driftfile の設定が実際に機能しているか確認するには少し待つしかありません。何か問題が起こったら、エラーをログ出力します。問題がない場合、タイムスタンプが更新されます。一日中動かして何もエラーが表示されない、そしてタイムスタンプが更新されていれば大丈夫だと思われます。

受信ソケットを制限する

ntpd が listen するソケットを制限するには interface オプションを使います:

interface [listen | ignore | drop] [all | ipv4 | ipv6 | wildcard | name | address[/prefixlen]]

設定例:

/etc/ntp.conf
interface listen lo
interface listen enp3s0
interface ignore enp5s0

トラブルシューティング

Cannot assign requested address

以下のように Cannot assign requested address メッセージが表示される場合:

$ journalctl -u ntpd
ntpd[2130]: bind(21) AF_INET6 fe80::6ef0:49ff:fe51:4946%2#123 flags 0x11 failed: Cannot assign requested address
ntpd[2130]: unable to create socket on eth0 (5) for fe80::6ef0:49ff:fe51:4946%2#123
ntpd[2130]: failed to init interface for address fe80::6ef0:49ff:fe51:4946%2

IPv6 を無効化することでメッセージを消すことができます。ntpd.service編集して -4 を追加:

[Service]
ExecStart=
ExecStart=/usr/bin/ntpd -g -u ntp:ntp -4

参照