プライベートキーファイル /etc/ntp/keys

プライベートキーファイルは、ntpd が認証に使用するキーのセットを記述するファイル。ディストリビューションの違いや NTP のバージョンによっては /usr/local/etc/ あるいは /etc/ にあったり、ファイル名が ntp.keys だったりする場合もある。NTP パッケージのコンパイル時に rsaref20 というコンポーネントを組み込んであれば、上位サーバの参照時や下位クライアントに身元を証明したり通信を暗号化することも可能なようだが、ここでは、ntpq, ntpdc ユーティリティによるリモート管理を許可しないため、あるいは、これらのユーティリティでの操作を受け入れるためにだけ設定するので、かなりはしょった 内容となる。 ntpd のセキュリティ機構がたいして立派なものではないということも肝に銘じておかなくてはいけない。

ntp-keygenユーティリティ

キーファイルの作成を簡素化するプログラムが ntp-keygen だ。同ユーティリティの名前は NTP パッケージ Ver.4.1.x で一度 ntp-genkeys となったが、 4.2.x で再び ntp-keygen に戻った。しかし、4.0.x の頃の ntp-keygen とは仕様がかなり異なり、コマンドラインオプションもがらりと変化しているので、最新の情報は ntp-genkeys - generate public and private keys で確認したほうがいいだろう。このプログラムが動作するためにはシステムに OpenSSL がインストールされていることが必要だが、日本で入手可能な Linux ディストリビューションで、OpenSSL がインストールされていないないものはまずありえないだろう。

ntp-keygen のヘルプで表示される主なコマンドラインオプション (ntpd 4.2.x)
-c enc_type RSA-MD5, RSA-SHA1, DSA-SHA1 などを指定。keys の生成では使わない
-d デバグメッセージを出力
-M これが今回の本命。 MD5 の対称鍵リストを出力する。私の手元の ntp-keygen ではカレントディレクトリに ntpkey_MD5key_<host_name>.num というキーリストファイルとそれへのシンボリックリンクである ntpkey_MD5_<host_name> ができる。
-p pwd ホストキーなどを暗号化する。その時のハッシュパスワード
-q pwd ホストキーなどの読み取り用に設定するパスワード
ntp-genkeys の場合 (ntpd 4.1.x)
-c conf_file ntp.conf ファイルのパスを指定。通常は指定の必要なし
-d デバグメッセージを出力
-g [d][m][r] 引数 d を指定すると Diffie-Hellman パラメータファイル ntp_dh を作成。
m は MD5 キーファイル ntp.keys.num を作成。
r は RSA のプライベートキーファイル ntpkey と パブリックキーファイル ntp_host を作成する。
rsaref20 がコンパイルされていない場合 dr は無意味で、m は指定しなくてもキーファイルは MD5 で作られるので、結局このオプションは不必要
-k k_file 吐き出すキーファイルのパスや名称を指定。デフォルトは ntp.keys.num となる。num は勝手に付く10ケタのタイムスタンプ
-l ntp-genkeys は、特に何も指定しない通常動作では、ntp.keys.num と、それを指すシンボリックリンク ntp.keys を自動的に作る。しかし -l オプションを付けるとシンボリックリンクは作られない
-t 上記で説明した通常動作の際に、既存の古いキーファイルやリンクを削除する
-h "here" の意。今いるディレクトリにキーファイルを吐き出す。シンボリックリンクは作られない
-n テストモード。実際にファイルは作らず、何が行われるかのメッセージだけを stdout に出力
ところが、実際は、ほとんどのオプションがうまく働かない。以下に、最も確実な方法を示す。
  1. root でログインするか、su - (単なる "su" ではなく必ず ログインシェルを移る "su -" )
  2. キーを保存するディレクトリに移動:
    cd /etc/ntp (通常)
    cd /etc/ntp/crypto (NTP 4.2.4 且つキーを暗号化する場合)
  3. 古いキーファイルとシンボリックリンクがあれば削除 (または別ディレクトリに一旦避難させる):
    rm keys ntpkeys_* ntp.keys*
  4. キーを生成する:
    ntp-keygen -M (NTP 4.2.x で、キーを暗号化しない場合)
    ntp-keyten -M -p passwd -q read_passwd (NTP 4.2.x で、且つキーを暗号化する場合)
    ntp-genkeys (NTP 4.1.x の場合)

    この時 "RAND_load_file /root/.rnd not found or empty" というエラーが出てキーが作れないことがる。これは OpenSSL が吐いているエラーで、その場合は root のホームディレクトリにランダムシードファイル .rnd を作っておく必要がある。 .rnd を作るには、例えば:
    dd if=/dev/urandom of=/root/.rnd bs=1024 count=1
    または、他の場所にある既存のランダムシードファイルを使うなら、 OpenSSL に環境変数 RANDFILE でその在処を伝えるてやる手もある。下記のようにすれば、環境変数でパスを与えて ntp-genkeys が実行できる:
    env RANDFILE=/path/to/random_seed_file ntp-keygen -M
  5. 生成されたキーリストファイルへのシンボリックリンク ntpkey_MD5_<hostname> へのシンボリックリンク /etc/ntp/keys (または ntp.keys) を作る。()
  6. パスワードを扱うデリケートなファイルなので、ntpkey_MD5key_<hostname>.num のパーミションは必ず root.root 600 にしておく。

※ 4.2.x より前の特定のバージョンの NTP パッケージで、ntp.keys.num がルートディレクトリにできてまうことがあった。しかも、 シンボリックリンク /etc/ntp/ntp.keys のリンク先は相対指定で "ntp.keys.num" となっているという破滅的状態。その場合は、ntp.keys.num/etc/ntp に移動:
mv /ntp.keys.* ./

ntpkey_MD5key_<hostname>.num ファイルはこういうような内容になっている:

# ntpkey_MD5key_hoge.cxm.3299580246
# Fri Jul 23 23:04:06 2004
 1 MD5 Vsd}/qnt>}%_3),j	# MD5 key
 2 MD5 fE09t[Bkq^OnTD"C	# MD5 key
 3 MD5 zm|Z@jG/=`vZRnq9	# MD5 key
 4 MD5 r?Z"9eUsH&S\R;BJ	# MD5 key
 5 MD5 0;_d01tOa5S,(s:C	# MD5 key
 6 MD5 yi&)=CUv2dn3edP,	# MD5 key
 7 MD5 F(z]')`|""5oM@59	# MD5 key
 8 MD5 DIxXdh,jgw\"i+,&	# MD5 key
 9 MD5 ki"[/P`Igy8fux.B	# MD5 key
10 MD5 Q_d'd@]~]tyxb|~{	# MD5 key
11 MD5 ^nqx@3nQ(BqY/{?u	# MD5 key
12 MD5 _Wj:=hySnbPVE>]_	# MD5 key
13 MD5 T4{XO8m-W,}+>Wz,	# MD5 key
14 MD5 |D\JAF-_\MOeI0uZ	# MD5 key
15 MD5 'kJ+ZZ?\ZCkAFiw1	# MD5 key
16 MD5 ]bDc::<4]b/AZ}]a	# MD5 key

1 から 16 の数字で始まる行それぞれがキーで、16 個のキーができている。各行のフォーマットは:

KEYID TYPE MD5_16_RANDOM_CHARS # COMMENT

TYPE の部分 MD5 (古いNTPでは M) は、キー文字列が MD5 ハッシュであることを示すキーワード。keys ファイルに関する限り、事実上 MD5 (M) しか有効でないようだ。これらのキーは、サーバ参照時の認証に使われるものであって、今回のような普通の運用では結局利用されない。しかし、セキュリティ上、作っておくことが肝心なのだ。

ntpqntpdc ツールをローカルでもリモートでもまったく使うつもりがないか、使うとしてもステータスの確認だけの場合は、ここまでで完了。

ntpqやntpdcで設定やステータス変更まで行いたい場合

これから作るキーは、ntpq, ntpdc を使用する場合で、なお且つステータスや設定に某かの変更を加えるコマンドを掛ける際にだけサーバ側に必要となる。これらのツールをローカル上で使うかリモートから使うかは関係ない。逆に言えば、これらのツールを使うにしても、ステータス確認までしか行わないのなら、このキーが使われる機会はなく、その時に影響してくるのは ntp.conf ファイルの restrict の内容だけだ。

じつは、前のセクションで keys ファイルに作られた 16 個のキーは、ntpqntpdc の認証には使われない。これらのツールの認証のためには、 ntpkey_MD5key_<hostname>.num ファイルに手動でキーを書き足す必要がある。足すのはこのようなものだ:

998 MD5 PaSSwOrd00000000

keys ファイルは最大 65534 個のキーを保持できる (らしい) ので、書き加えるキーID の部分は 17 から 65534 までのいずれかとなる。ここでは、前出の ntp.conf ファイルに合わせて 998 とした。キー文字列のタイプは、ntpqntpdc が要求してくるのは必ず MD5 であることから、必ず MD5 (古くは M) を指定。キー文字列は、キーボードから打ちやすい、自分の憶えやすいフレーズにしておくといいだろう。ただし、フレーズが16文字に満たない場合には、右側を 0 で埋めて16文字きっかりにする。 ntpd の実装する MD5 プライベート鍵は32ビット固定長だからだ。なお、ntpqntpdc のセッションで認証が必要になった際には、コンソール上でキーIDとパスワードを直接タイプすることとなり、それがサーバ上でキーと比較されるだけなので、操作する端末にこの keys ファイルをコピーしておく必要はない。

それに加えて、前出 ntp.conf の:

# trustedkey 1 998
# requestkey 998
# controlkey 998

のセクションのコメント記号 (#) を外して有効にする。trustedkey ステートメントで ID 1 のキーも含めているが、複数指定できるということを示すために書いてみただけで、特に必要というわけではない。また、ここでは ntpdc 用キーの指定である requestkey と、 ntpq 用キーの指定である controlkey ステートメントで同じキーID を指定しているが、別々にしたかったら、keys ファイルにもうひとつキー定義を加え、そのキーID を trustedkey に指定すればいい。

ntpqntpdc で設定に影響を及ぼす操作を行うには、ツール起動側のアドレスに対するサーバのアクセス制限 (restrict) は開放しておかなくてはならない。たいていはループバックアドレスと自分の実アドレスには規制を掛けないのが通例なので、ローカル上でツールを起動して自分自身の ntpd を操作するなら邪魔はされない (キーとパスワードの入力は必要)。しかし、リモートから行う場合には、ntp.conf のアクセス規制セクションに注意が必要だ。例えば、リモートコンソールとして使うマシンのアドレスが 192.168.0.200 だとしよう。例の ntp.conf では、このアドレスは 192.168.0.0 mask 255.255.255.0 に内包され、その restrict には noquery が含まれているので、設定変更どころか、これらツールの使用するモード 6 およびモード 7 の問い合わせそのものを完全に無視してしまう。設定やステータスを変更するような操作を行いたい場合は:

restrict 192.168.0.200

を書き加えればいい。設定内容や状態を見るだけだとしても、例えば、

restrict 192.168.0.200 nomodify

のように、noquery は書いてはいけない。

ntpd の起動

これにて準備は整ったので ntpd デーモンを起動する。`/etc/init.d/ntpd start' でも `service ntpd start' でもお好きなように。起動してすぐにクロックが合うわけではなく、ntpd はまず、指定したタイムサーバのうちどれが信頼に値するかを数分掛けて比較検討し、それから徐々に、ローカルのクロックをタイムサーバの正しい時間に近づけていく。

うまく起動せず、ntpd がすぐに exit してしまう場合は、カーネルクロックが 1000 秒以上狂っていることが原因かもしれない。その場合は:

root# ntpdate -b -v server
root# hwclock --systohc

で、一旦、参照予定のタイムサーバにカーネルクロックを強制的に合わせ(※)、ハードウェアクロックもカーネルクロックの時間にシンクロさせておく。それから改めて ntpd を起動すれば、今度はうまくいくはずだ。きちんと作動しているかどうかは、数分後に ntpq ユーティリティを使えば分かる。 ntpdate については、捕捉程度だが別項にまとめた。

※ RedHat系の NTPパッケージに含まれる rcスクリプトでは、 /etc/ntp/step-tickers というファイルに参照先 NTPサーバを書いておくと、 ntpd を起動させる直前でそのアドレスを参照して ntpdate による一次時間合わせを行う仕掛けになっている。また、 step-tickers が空でも、 /etc/sysconfig/ntpOPTIONS 変数に -x が含まれていれば、 rcスクリプトは ntpd 主設定ファイル (ntp.conf) から peer または server 行を探してアドレスを拾い、やはり ntpdate を実行しようとする (なお且つ step-tickers にアドレスが書いてあれば「探す」手間が省ける)。つまり、どちらか (あるいは両方) やっておけば、マシンの時計が大きく狂っていたとしても ntpd はきちんと起動してくれる。

ntpdをchrootする

安全性をより高めるため、ntpdchroot 環境で動かすのもいい考えだ。これは Xen のホストOS上で時間合わせを行う時に思いついたことだ。

NTP 4.2 から (?) は ntpd-i オプションが使えるようになった。このオプションを `-i /dir/to/chroot' といった具合に付けると、ntpd は自らをそこへ jail して動く。もう数年前にリリースされた Fedora Core 5 でさえ NTP 4.2.0 が乗っていて、やってみると実際にこれが通用した。 -i オプションは -u オプションと併用しないと意味がない。root権限で動いているプログラムを chroot してもほとんど無意味だからだ。以下に、jail ディレクトリを /var/chroot/ntpd/ だとして構築法をまとめる。

ディレクトリ構造:
/var/chroot/ntpd/                        <- [root:root 755] chroot後の ntpd にとって / となる
              \_ etc/                    <- [root:root 755]
                   \_ ntp.conf           <- [root:root 644]
                      localtime          <- [/etc/localtime と同じ] `cp -p' でコピーしてくる
                      ntp/               <- [root:root 755]
                        \_ keys          <- ntpkey_MD5_HOSTNAME への symlink
                           ntpkey_MD5_HOSTNAME         <- 下記への symlink
                           ntpkey_MD5key_HOSTNAME.num  <- [root:root 600]
                        \_ crypto/       <- [root:ntp 750] ntpd-4.2.4の場合のみ
                             \_ pw       <- [ntp:ntp 600] ntpd-4.2.4の場合のみ
              \_ var/                    <- [root:root 755]
                   \_ lib/               <- [root:root 755]
                        \_ ntp/          <- [ntp:ntp 755]
                             \_ drift    <- 必要時に自動的に作られる
                   \_ run/               <- [root:root 755]
                        \_ ntpd.pid      <- 実際には作られない
              \_ dev/                    <- [root:root 755]
                   \_ log                <- syslogソケット
/etc/
   \_ ntp.conf                     <- /var/chroot/ntpd/etc/ntp.conf への symlink
      ntp/
        \_ keys                    <- /var/chroot/ntpd/etc/ntp/keys への symlink
           ntpkey_MD5_HOSTNAME     <- /var/chroot/ntpd/etc/ntp/ntpkey_MD5_HOSTNAME への symlink
           ntpkey_cert_HOSTNAME    <- 上同様
           ntpkey_host_HOSTNAME    <- 上同様
           step-tickers            <- jail へのコピー不要
        \_ crypto/                 <- [root:ntp 750] ntpd-4.2.4の場合のみ
                \_ pw              <- /var/chroot/ntpd/etc/ntp/crypto/pw への symlink (ntpd-4.2.4のみ)
/var/run/
       \_ ntpd.pid                 <- PIDファイルは実際にはこちらにできる

chroot階層構築のポイント;

何度もやっていたら面倒くさくなったので、ここでやるべきことをシェルスクリプトにしてみた -> ntpchroot.sh。ただし sysconfig/ntpd 及び syslog の設定まではカバーしていない。利用する前にファイル冒頭の設定変数を確認/変更するのを忘れずに。また、このスクリプトは /etc/ntp/(crypto/) 下のキーファイル類を一旦削除して jail 下に改めて生成し、強制的にリンクを張り戻すようになっているので、必要に応じてバックアップを採ってから行うこと。

付属ユーティリティの使い方

ntpq

ntpq は、NTP デーモン一般 (ntpd とは限らない) の稼働状態を確認するためのプログラム。通信には UDP プロトコルの NTP mode 6 パケットが使われる。

ntpq [host]

という風に起動すれば、対話モードの ntpq> プロンプト状態に入る。host は、IPアドレスでも、DNS名や /etc/hosts ファイルに書いてある名前でも構わない。host を指定すれば指定したリモートの NTP サーバへつなごうとするし、指定しない場合には、localhost つまり自分自身の中の NTP サーバに接続しようとする。プロンプトに入ってしまえば、help と打てば使用可能なコマンドの一覧、"? command " と打てばそのコマンドに関する簡略なヘルプが表示される。 ntpq の解説は ntpq - standard NTP query program で読める。

また、ntpq の起動時にしかるべきオプションを付けて、コマンドラインモード、つまりコマンドの終了とともに即 exit させることもできる。よく使うのは、稼働確認や、参照している NTP サーバのどれが優先参照先 (system peer) になっているかといった情報を得たい時だ;

ntpq -p

オプションを -pn に変えれば、サーバの名前が名前解決されず数字のままとなる。ちなみに、ntpq にはコマンドラインオプションのヘルプを出すためのオプションはないので、どんなオプションがあるかを知るには、存在しないオプション (-h-v) を付けてコールすればいい。 ntpq -p の出力は下記のようなものになる (いろいろな例を示すため、設定例の ntp.conf とは異なるコンフィグを使っている);

     remote           refid      st t when poll reach   delay   offset  jitter
==============================================================================
+ntp2.jst.mfeed. mf-isdn4.mfeed.  2 u   15   64  377   23.887   -0.824   0.551
*orion.asahi-net p011.gate.atson  2 u   19   64  377   22.809   -0.672   0.757
 LOCAL(0)        LOCAL(0)        10 l   17   64  377    0.000    0.000   0.015
+ns.wakayama-u.a clock.nc.fukuok  2 u   20   64  377   48.459    2.210  44.989
xthink.itsc.cuhk bill.itsc.cuhk.  2 u   31   64  377  202.293   62.274   1.787
 time.nonex.net  0.0.0.0         16 u    -   64    0    0.000    0.000 4000.00 
出力の読み方:
列系統
remote 参照しているサーバの DNS 名。 -n オプションを付けたときはアドレス
refid 各タイムサーバが基準にしているさらにひとつ上位のサーバ名かアドレス。探知できない場合は 0.0.0.0
st ストレータム (stratum) つまり、そのタイムサーバの階級
t そのサーバとの通信タイプ。u = ユニキャスト, m = マルチキャスト, b = ブロードキャスト, l = ローカル
when 直近の通信が何秒前に行われたか
poll 現段階でのポールインターバル
reach アクセス状態 (reachability)。8進数表記
delay そのサーバとの通信に要する時間。ミリ秒単位
offset 現在のカーネルクロックとのずれ。ミリ秒単位
jitter 時間の刻みの揺らぎ。分散 (dispersion) と呼ばれることもある。ミリ秒単位。値が小さいほど、そのクロックは安定している
行の先頭に付く記号 (主なもの)
* 優先参照先 (system peer) に選択されているタイムサーバ
+ system peer に昇格する可能性のある補欠サーバ
x クロックが不正確 (経路的要因を含む) なので無効とされた
  行頭がスペースのものは、通信できないか、時間合わせにこのサーバ自体を使っている (ループ)、シンクロ先としては遠すぎる、のいずれかの理由で無効とされた (ただし、通信タイプが local であるものを除く)

通信できていない場合は、refid, reach など、ほとんどの列が 0 になっていて、 jitter4000.00 などになる。どれもこれもがそうなるのなら、ファイヤーウォールかルータで UDP 123 番ポートのパケットがブロックされているのかもしれない。また、いつまで経ってもどれにも * が付かないのも異常だ。

ntpdc

ntpdc は、ntpd 専用のクエリツールで、ローカル及びリモートにある ntpd の状態の確認や設定変更ができる。通信には、UDP プロトコルの NTP mode 7 パケットが使われる。詳細は ntpdc - special NTP query programntpq 同様に;

ntpdc [host]

とだけすれば対話モードに入り、 ntpdc> のプロンプト表示になる。様々なステータスや変数を表示させることはもちろん、認証関係の設定も含め、ntpd のすべての設定項目がリアルタイムに変更できる。これは、生半可なことでは ntpd の再起動や停止ができない重要な位置を占めるタイムサーバで、緊急的な設定変更に迫られた場合に非常に便利だ。 ntpd を再起動すれば、システムピアが決定されるまでの数分間は、他ホストからのリクエストにも応えることができない。一方、ntpdc での書き換えはメモリ上の ntpd に対して直接行われるので、サービスが途絶えない (設定ファイルが書き換わるわけではない)。その反面、悪用されれば恐ろしいツールでもある。使えるコマンドは help で調べることができ、`? command ' のようにコマンドまで指定すれば当該コマンドの簡単な使い方が表示される。

また、しかるべきオプション付きでコールすると、コマンドラインモードで走ってすぐに終了する。コマンドラインオプションは:

-c command 対話モードで使用するコマンドを引数に付けて実行する
-i 強制的明示的に対話モードに入る
-l 参照先として認識しているタイムサーバをリストアップ
-p 参照先サーバのリストを各々の状態とともに表示。`ntpq -p' の出力とは少々異なる
-s 上記と同じだが、こちらのほうがやや `ntpq -p' に近い。`ntpdc -c dmpeers' と同義
-n ホスト名を DNS 名前解決しないで表示。-l, -p, -s と組み合わせて使用

設定に変更を加えるようなコマンドをそのセッションで初めて発行した際には、キーID とパスワードを求めるプロンプトが行われる。キーID には、サーバ側の ntp.confrequestkey キーワードで設定しておいたキーID を入力。パスワードプロンプトでは、サーバ側の keys ファイルの当該のキーID に書いておいたパスワードフレーズを入力する。パスワードは MD5 が前提になっているので、16 ケタないと認められない。例にした keys であれば、パスワードは PaSSwOrd00000000 をフルに入力する。

なお、ntpdc プログラムは、遠く (ネットワーク的に) 離れた ntpd サーバの保守には使えないようにできている。 ntpd が、リモートによるハッキングを困難にするために、パケットのタイムスタンプをチェックしているのだ。 ntpdc は、同一LAN内や、近くのネットワークセグメントでしか使えないと思ったほうがいい。

ntpdate

デーモンとしてではなく随時起動のプログラムとしてカーネルクロックを調整するユーティリティ。しかし困ったことに ディストリビューション添付の man ファイルのアップデートが間に合っていないようで、オプションなど詳しい使い方を知るにはオフィシャルサイトの WEB ドキュメントを読まなければならない。そのドキュメントによると、このプログラムは「じきに廃止されるだろう」と書いてあり、使用は、時間のズレが非常に大きく (1000秒以上) て ntpd が起動できない時か、Linux を Windows Server に対して時刻合わせしなければならない時くらいに限定した方がいいようだ。基本的なコマンドフォーマットは;

root# ntpdate [options] server [server ...]

重要: ntpdatentpd が稼働していると "NTP socket in use" というエラーを吐くばかりで動作を拒絶する。 ntpdate を使うには一旦 ntpd デーモンを終了しなければならない。

ntpdatentpd と同様に slew モードと step モード (ntpd 起動オプション-x オプション参照) を自動的に使い分ける。デフォルトでは、参照サーバとの時間のズレが +-128ms (?? 0.5秒という記述もありどちらか不明) 以内の場合は slew モードで働き、それ以上のズレがある場合には step モードで動作する。 ntpd を即時終了モード (-q オプション -- 次項参照) で使用した時との違いは、 ntpd がじっくりと腰を据えて参照先を選別してから exit するのに対し、 ntpdate は step モードにしろ slew モードにしろ複数の参照サーバを指定したにしろ (おそらく簡易的な選定アルゴリズムを使って) 即刻 exit するという点だ。オプションはかなりたくさんあるが、主なものだけを以下に列挙する。

ntpdateオプション

オプション 説明
-B 参照サーバとの時間のズレの大小にかかわらず常に slew モードで動作。 ntpd-x オプションに当たる
-b 参照サーバとの時間のズレの大小にかかわらず常に step モードで動作。 ntpd にはない機能
-d デバグモード。サーバ参照や様々な判断の過程を表示する。実際の時間合わせは行わない
-U user (U は大文字) 指定したユーザとして実行する
-v 冗長モード。よりたくさんのメッセージを表示する
-4 参照先サーバを IP でなくホスト名で書いた場合に、 IPv4 として解決を試みる。 IPv6 なら -6
-s STDOUT(標準出力) の出力を syslog へ送る。ファシリティやログレベルは不明だが、実験したところ messages に記録された

cronで実行する時の例

Windows 2003 Server の Windows Time を参照して時刻合わせをしなければならないなど悲しい事情のある場合には、`ntpd -q' をあきらめてこれをやらなければならない。少しでも美しく行うには、まず、下記のようなシェルスクリプトを用意する。仮にこのスクリプトを /etc/cron.misc/timecheck.sh としよう;

#!/bin/sh -
/usr/sbin/ntpdate -b -4 -s -U ntp server &>/dev/null || :

このように -s で時刻合わせ記録を syslog へ送り、その代わりこのスクリプトはいかなるメッセージも奈落 (/dev/null) へ送り、なお且つ、エラーが起きても常に TRUE で exit する (エラー発生時の crond から root へ宛てた告知メールを抑止するため)。参照先サーバをホスト名で書く場合は、最近の Linux ディストリビューションは IPv6 が有効になっているが実際には IPv4 しか利用していない場合が多いので、無駄な DNSクエリをなくすために -4 を指定した方がいい。もちろん timecheck.sh には実行ビットを立てておく (755など)。これをドライブする crontab エントリは下のような塩梅。 0:31, 2:31, 4:31 ... という具合に 2時間毎に実行されるよう /etc/crontab ファイルに定義を書く場合の例を挙げる;

 31 */2 * * * root /etc/cron.misc/timecheck.sh

仕上げに `service crond reload' して完了。

クライアントの設定

LINUX の場合

付属ユーティリティの ntpdate で `ntpdate -b 192.168.0.1 ' (確実に名前解決できるならホスト名でも可) する手もあるが、NTP が推奨しているのは、ちょっと面倒だが、クライアントでも認証を含めたすべての項目を設定しておき `ntpd -q' するという方法だ。タイムサーバ側と同じくデーモンとして常時起動させておく方法もあるが、ここでは cron による方法について述べる。

悲しいかな、Linux (NTPクライアント) から Windows 2003 Server (NTPサーバ) に時刻を合わせようとしても、Linux の ntpd は Windows タイムサーバを信用しようとせず、時刻合わせができない。その場合は仕方ないので ntpdate を cron で走らせる。また、実施経験はないが、Windows Server側のレジストリをいじくって無理矢理ntpd のお気に召すような振る舞いをさせることもできるようだ。

keys ファイルはとにかく作っておくだけでよい。クライアント側の ntp.conf はこんな感じになる:

restrict default ignore
restrict 127.0.0.1
restrict 192.168.0.1 noquery nomodify notrap
 
driftfile /var/lib/ntp/drift
 
server 192.168.0.1 minpoll 5
 
# local clock
server 127.127.1.0
fudge 127.127.1.0 stratum 10
 
keys /etc/ntp/keys

NTPサーバ 192.168.0.1 を、最短ポールインターバル 5 、つまり 32 秒と短くして参照している。このほうが、クライアントの時間補正がやや短時間ですむようだ。32 秒というのは、ntpd の実行間隔ではないので注意していただきたい。自身のハードウェアクロックを「緊急用」に設定しているのはサーバの設定と同じ。アクセス制限項目では、自身についてはループバックだけでちゃんと機能し、サーバのように念のための実アドレスは書かなくても大丈夫だ。もちろん書いても構わない。サーバのアドレスに関しては ntpqntpdc によるモード6/7 パケットを受け付けず返答もせず変更も拒絶する "noquery nomodify notrap" とした。

設定ファイルができたら、cron などで例えば30分毎とか1時間毎に:

ntpd -q -x -g -u ntp:ntp

を実行すれば良い。実際いろいろ試してみると、ntpd はオプションの記述順に神経質なようなので、この通りに記述しないと ntpd が起動してくれない。また、クライアントが NTP 以外の意味で大役を担うサーバである場合には -g は外したほうがいいだろうし、 -x の使用は要考慮 (オプションの意味は前ページ)。なお、 rcスクリプトを通して起動するわけではないので、RedHat 系 OS でも /etc/sysconfig/ntpd の起動オプションは読み込まれないという点に注意。そのため、必要なオプションはすべて起動時に直接渡さなければならない。「こんな使い方なら ntpdate を使った方がいいじゃないか」と思った人もいるかもしれない。それについては ntpdate の項で触れている。

上記コマンドから起動されても、-q オプションが指定してあるからといって、すぐに終了するわけではない。ntpd が指定されたタイムサーバの妥当性チェックと実際のカーネルクロック調整を完了させるには、クロックのずれにもよるが、通常でだいたい 5 分前後かかる。 minpoll が 32 秒というのは、この 5 分の中での問い合わせ間隔だ。メモリ量の逼迫などで、どうしても、なるべく早く ntpd を終了させたい場合には、奥の手を使う。上記 ntp.conf の 1 行目を以下のように書き換えよう:

server 192.168.0.1 iburst

細かい説明はオフィシャルドキュメントの Configuration OptionsAssociation Management に任せるが、iburst には、 -q オプションと併用した時、サーバとのクロック同期をスピードアップする働きがある。実際に試してみたところ、ntpd は30秒ほどで exit するようになった。

WINDOWS の場合

WINDOWSでは、まずタイムサーバの名前解決ができるようにしておく必要がある。名前が牽けるようにしておかないと、シンクロ先を IP で指定したとしても参照に失敗する。ローカルネットワーク用の DNS サーバを立てるか、簡易的な方法として、hosts ファイル (NT系では C:\WINNT\system32\drivers\etc\hosts, 95系では C:\WINDOWS\SYSTEM\hosts ) に:

192.168.0.1    time.localnet

といったように記述しておく。名前は実際のサーバのホスト名である必要はなく、好き勝手で構わない。 SNTPクライアントは、桜時計などのソフトを使うのが手っ取り早く、実際 9x 系では下記の標準ツールが使えないのでそれが唯一の選択肢といえるだろう (WINDOWS ドメイン環境を構築しているのなら方法はあるらしいが)。

2000/XP には、w32time.dllw32tm.exe という標準ツールも付属している。 w32time.dll はサービスコントロールパネルに出ているのでそこで起動をコントロールできるし、コマンドラインから `net start w32time' あるいは `net start "windows time" ' とやっても起動できる。同期間隔はデフォルトではとんでもないことに 8 時間だが、レジストリを直接編集すれば変えられる。 w32tm.exe は単独のプログラムであり、常駐させるのが嫌な場合に向いている。 w32tm.exe 起動コマンドはこうなる;

w32tm -once

w32time, w32tm とも、シンクロ先のサーバは前もって別コマンドで設定しておかなくてはならない。どちらも、同じ変数だかレジストリだかを使うらしく、

net time /setsntp:time.localnet

でシンクロ先を刻み込む。これは、1回やっておけばマシンを終了させても消えないので、シンクロ先を変更する必要が生じない限りいちいち行う必要はない。標準ツールに関しては下記の MSサイト;