ネットワークタイムプロトコルデーモン
ネットワークタイムプロトコル(NTP) は GNU/Linux のソフトウェアクロックをインターネット上の時刻サーバーと同期するのに使われる最も一般的な方法です。変動的なネットワークの遅延を軽減し、インターネットを使って数十ミリ秒の範囲で時刻を維持できるように設計されています。ローカルエリアネットワークの場合、一ミリ秒まで正確性を保てます。
NTP プロジェクト は NTP という名前のプロトコルのリファレンス実装を提供しています。NTP の代わりになるものとして、ダイアルアップフレンドリで常時オンラインではない環境用に設計されている Chrony と、OpenBSD プロジェクトの OpenNTPD があります。
この記事ではクライアント・サーバー両方で 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
これで誰も何も変更できなくなり時刻サーバーの状態の問い合わせも制止されます: nomodify
は ntpd (と ntpq または ntpdc) の再設定を無視し、noquery
は ntpd (と ntpq または ntpdc) の状態データのダンプを防ぎます。
また、他のオプションを加えることも可能です:
restrict default kod nomodify notrap nopeer noquery
"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 やその他の 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 で時刻を一度だけ設定して終了します。つまりデーモンは起動しません。この操作が失敗した場合、システムクロックは同期されません。
また、システムプロセスの実行を保護するために、システム時刻と 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'
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 &
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
を実行します。ntpd が gpsd と対話できていれば以下のように表示されます:
$ 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
chroot で実行する
新しいディレクトリ /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