NTP は、ネットワークを経由してコンピュータの時間を同期するためのプロトコル。通信は UDP プロトコルの 123 番どうしで行う。そして、NTP サーバデーモンの標準が ntpd だ。マシン自体の時計を合わせるだけなら、 NTP パッケージに含まれる ntpdate を使ってもいいが、オフィシャルドキュメントによると、 ntpdate はエラーハンドリングが「いい加減」なので、ntpd を -q オプションで使ったほうが良いようだ。
UNIX, Linux はサーバ運用を主眼として作られているので、時間が急に変わってしまっては問題が生じることが多い。そのため、ntpd は、マシンのクロックが違っていたからといって、いきなり何十分も遅らせたり進めたりはしない。連続性が失われないよう 「1 秒の長さ」 を実際よりも長くしたり短くしたりすることによって、徐々に補正していこうとする (一概に言えない - 後述 デーモン起動オプション の -x オプション参照)。そこは、所詮クライアントOSの域を出ない WINDOWS の時間補正とは大きく異なる点だ (※)。設定オプションによっては WINDOWS のようにガバッと合わせることも可能だが、某かのサーバとして運用中の Linux マシンでは「ガバッ」はなるべく避けなければならない。
※ Windows 2003/XP 以降の w32time は SNTP でなく NTP を実装しており、ntpd のようにクロックを徐々に調整する方式が標準になった。「Linux野郎のための WINDOWS 2003/XP/2008/2012 時刻同期解説」を参照のこと。
NTP パッケージは仕様がコロコロ変わるしドキュメントも読みにくく、設定ディレクティブ用の語彙が適切さを欠いているなどの点で、筆者が最も嫌いなサーバソフトのひとつだ。例えば、以前は ntp-keygen という名前だった認証用キー作成ユーティリティが、 4.1.x で ntp-genkeys という名前に変わり、 4.2 で再び ntp-keygen に戻ったりした。しかもコマンドオプションまで変わっていたりする。PC及びカーネルのクロックについての概略は、The Clock Mini-HOWTO でつかめる - 日本語訳は JF に上がっている。インストールについては説明を省く。
/etc/ntp.conf | メインの設定ファイル |
/etc/sysconfig/ntpd | RedHat系で起動オプションを記述しておくファイル |
/etc/sysconfig/ntpdate | RedHat系で ntpdate の起動オプションを記述しておくファイル |
/etc/ntp/keys | 認証に使われる対称鍵ファイル。このファイルはシンボリックリンクで、実体は /etc/ntp/ntpkey_MD5key_hostname.timestamp または、NTP 4.2.4 でキーを暗号化してある時は /etc/ntp/crypto/ 下の同名ファイル |
/etc/ntp/step-tickers | 簡易的に時刻同期を行う非デーモン型のツール ntpdate が参照するファイル。同期のために参照するタイムサーバを書いておく |
他にもあるが、一般的な使用で必要なのはこれだけ。認証ファイルのパスはディストリビューションによっても違う。 デフォルトでインストールされた主設定ファイルに記述があるはずなので確認していただきたい。
ntp-keygen | ntpd 用の暗号キーを作成するプログラム |
ntpstat | NTP稼働状態の概略を表示する |
ntpdate | 非デーモン型の時刻合わせクライアントプログラム |
ntpdc | ntpd の状態を見たり、設定を変更するためのインターフェース |
ntpq | 現在の優先NTPサーバがどれかなど、NTPサーバの稼働状況の詳細を問い合わせる |
ntptime | クロック関連のカーネル変数値を表示する |
tickadj | カーネルの「1秒」が「何マイクロ秒」にあたるか表示、微調整する |
ntptrace | 指定したタイムサーバがどういった上位サーバから時間を得ているか、stratum 1 まで遡って調べる |
インストールの仕方やディストリビューションによって、一部なかったりするかもしれない。
ntpd の起動オプションには、主に、以下のものがある。この他は滅多に使う必要がないか、主設定ファイルで指定すれば良い。
-a | 認証機構を有効にする (デフォルト)。主設定ファイルで指定すれば良い |
-A | 認証機構を無効にする。やめておいたほうがいい (理由は後述) |
主設定ファイルの場所を指定 | |
-d num | デバグモード。num の数字が高いほど冗長 |
-g | ntpd は通常、参照した NTP サーバと現在のカーネルクロックの差異が 1000秒 より大きい場合には、メッセージを吐いて exit する。マザーボードやカーネルの異常の可能性があるからだ。この差異の閾値を ntpd では `panic threshold' と呼ぶ。そのチェックを無効にするのがこのオプション。ただし、異常を無視するのは 1回だけで、次にまた 1000秒を超える差異があった場合にはやはり exit する。マシンを純然たるクライアント用途で使っている場合を除いては、-g オプションの使用は控えたほうがいい。狂いが大きい場合には、`ntpdate -b -v server ' でカーネルクロックを強制的に修正し、 `hwclock --systohc' でハードウェアクロックをカーネルクロックに合わせてから ntpd を起動するのが常套手段。なお、-g 起動オプションの代わりに、設定ファイルの tinker panic ディレクティブで panic閾値 を調整することもできる |
-f | drift ファイルのパスを指定。 drift ファイルとは、参照時計と現在のカーネルクロックとのずれを記録するファイル。通常は主設定ファイルでディレクティブによって指定する |
-l | ログの出力先を指定。デフォルトでは syslog デーモンに渡す |
-x | ntpd の動作にはふたつのモードがある。slew モードと step モードだ。slew モードでは、 1 秒あたり最大で 0.5ms (0.0005 秒) づつ徐々に時間を合わせ、連続性を重視する。step モードでは、不連続に時間を一気に進める (または遅らせる)。 デフォルトでは、時間のずれが 128 ms (0.128 秒) よりも小さかった場合には slew 動作を行い、128 ms 以上ずれた状態が 300秒以上続くと step モードに切り替わる。動作切替の閾値を ntpd では `step threshold'、それがどれだけ長く続いたら動作を切り替えるかの閾値を `stepout threshold' と呼ぶ。-x オプションを指定すると、step閾値が 600 秒という非常に大きな値に変わり、 ntpd は (実質的に) 専ら slew モードで動作することになる。-x オプションは一見、時間の連続性を保つという点で好ましいように思えるが、slew モードでは 10 秒の狂いを調整するのに 20000 秒 (= 10 / 0.0005) つまり 5 時間半もかかってしまうということを頭に置いておかなくてはならない。なお、起動時に -x オプションを与える代わりに、設定ファイルの tinker ディレクティブを使えば step閾値と stepout閾値を任意の値に設定することもできる |
-q | 時間合わせが済み次第 ntpd は exit する。 ntpd をデーモンとしてではなく ntpdate 的に使うわけだ。 cron などでスケジューリングする時に -g オプションと組み合わせて使用することが多い |
-u user | ntpd を user 権限で動かす。当然 user ユーザはあらかじめ作成しておかないと駄目。或るバージョンの ntpd では大文字の -U だったり、`-u ntp:ntp' という具合に UID と GID が指定できたりと仕様が何度か変わってきているので、使う前に一度 man で確認した方がいい |
-i /dir | ntpd が自らを /dir へ chroot する。詳しくは「ntpdをchrootする」を参照 |
-I iface | [4.2.4のみ] リッスンするインターフェイスを限定する。`-I eth0 -I lo' のように複数回使用可能。4.2.2 には、逆にリッスンしない IP を指定する -L というオプションがあるようだが、仕様が無計画にコロコロ変わってあんまりアホらしいので無視 |
-4 | 名前解決の際に、IPv4 アドレスへの解決のみ試みる。OSとして IPv6 が殺してある時は指定した方がよい |
-6 | 名前解決の際に、IPv6 アドレスへの解決のみ試みる |
多くの動作オプションは主設定ファイル内で設定できるので、起動時にオプションとして渡すとすれば -u, -4, -i などといった程度。一般的には、起動スクリプトで指定するのだろうが、RedHat系では /etc/sysconfig/ntpd ファイルで OPTIONS 変数に書いておくと、rcスクリプトがこのファイルをインクルードして ntpd の起動引数に加えてくれる。ただし -x オプションだけは、 ntpd に直接渡す時とはちょっと異なり、sysconfig/ntpd ファイルから渡すと step-tickers 動作を行う仕掛けがされている。
メインの設定ファイルは、どこのタイムソースサーバに時間を合わせるかはもちろん、どの範囲のクライアントにこのサーバの参照を許すかなど、セキュリティ面でも非常に重要な規定を行う。ntpd は、時間を合わせられる こともできる。たかが時間合わせと侮るなかれ、大幅にクロックを狂わせれば、サーバ上のサービスをダウンさせるのも簡単だ。さらに、ntpdc という「両刃の剣」とも言える付属ユーティリティを使えば、 ntpd の設定をリモートで随時変更することも可能なのだ。設定例は下記、それから要点を説明する。ここで述べるのはディレクティブの一部に過ぎないが、通常はこれだけで事足りる。
tinker step 2 stepout 300 panic 1800 tos orphan 6 disable monitor restrict default ignore restrict 127.0.0.0 mask 255.0.0.0 restrict 192.168.0.1 restrict 210.173.160.57 noquery nomodify notrap nopeer restrict 133.40.41.134 noquery nomodify notrap nopeer restrict 192.168.0.0 mask 255.255.255.0 noquery nomodify nopeer driftfile /var/lib/ntp/drift # ntp2.jst.mfeed.ad.jp server 210.173.160.57 maxpoll 11 # one of s2csntp.miz.nao.ac.jp server 133.40.41.134 prefer maxpoll 11 # local clock #server 127.127.1.0 #fudge 127.127.1.0 stratum 10 crypto pw secret # includefile /etc/ntp/crypto/pw keys /etc/ntp/keys # trustedkey 1 998 # requestkey 998 # controlkey 998
NTP サーバには、このように自分で構築するサーバも含めて、stratum (ストレータム=階級) というものが必ずある。stratum の数字が小さいほど、その NTP サーバは階級が高い。stratum 1 のサーバは、我々が時間合わせに使ってはいけない(NICTなど例外もある)。そうした上位階級 NTP サーバは、それ自身で電波時計や原子時計などの基準デバイスを備え、次の階級のサーバから時間合わせのために参照される。下々の有象無象がいちいち参照したら、starum 1 サーバに無用な負荷をかけてしまう。よって、我々が通常使うのは stratum 2 の NTP サーバだ。公開されているサーバは、ネットの検索エンジンで「NTP サーバ 公開」などとして検索すれば出てくるだろう。自分の加入しているプロバイダが NTP サーバを公開しているのならば、それを使うのも手。NTP サーバとそのサブネットを構築する上で要となる、その他の鉄則を以下に挙げておく:
server コマンドは、参照する NTP サーバの指定に使う。NTPv4 プロトコルでやりとりされるデータは、世界標準時における 1900 年 1 月 1 日 00:00 からの経過時間 (秒) なので、NTP サーバが日本にあろうがアメリカにあろうが基本的には関係ない。ただし、パケットを要求してからこちらに届くまでのタイムラグは、正確な時間補正に影響を与えるので、経路コストの低いサーバを参照したほうが良いとされている。ただ、ntpd は、stratum はもちろん、参照するクロックのジッター (時間の刻みの微妙な揺らぎ) や、到達に要するタイムラグなど、様々な要素を総合評価しているので、複数のサーバを指定した場合 (普通はそうする) には、メインとして参照するサーバ (これを System Peer と呼ぶ) が逐次選択しなおされる。そうした評価をこちらの意向や都合で変えるもののひとつが、例に見られる prefer というキーワード。「なるべくならこれをつかってよ」という意味だ(※)。
※ さらに、候補選定でなるべく生き残らせる true というキーワードもある。
サーバに対して時間確認を行う頻度のことを、ポールインターバル (poll interval) と呼ぶ。ポールインターバルは、ntpd では動的に変化していく。これは、最小 (minpoll) と最大 (maxpoll) で規定され、デフォルトでは、ローカルの時計が安定しないうちは 64 秒毎、それから次第に、128 秒、256 秒と間隔が長くなり、最終的には最大ポールインターバルである 1024 秒 (デフォルトの場合) に落ち着く。これらふたつの値は server コマンドのオプションとして "minpoll num " または "maxpoll num " あるいはその両方を指定して、変更することもできる。間違えやすいのは、この num が文字通りの秒数ではないという点だ。num は 2を基底とする指数、つまり 2n の n にあたるもの (ビット数とも言える)。maxpoll のデフォルト値は 10 (1024秒) で、指定可能な最大値は 17 (約36時間25分)。minpoll のデフォルトは 6 (64秒) で、指定できる最小値は 4 (16秒) となっている。例では maxpoll を 30分くらいにしたいと思い、num を 11 (約34分) に設定している。また、minpoll を 30 秒くらいにしたいなら num には 5 (32秒) を指定する。
!! ここでは使用例を示すために maxpoll を使っているだけで、34分に変更するのが必ずしも最適というわけではない。
server コマンドで、もうひとつ、127.127.1.0 (127.127.1.1 でもいいようだ) を書いている(ただしコメントアウト)。これは、自分のマシンのマザーボード上のクロック (ハードウェアクロックとかリアルタイムクロック [RTC] とも呼ばれる) だ。自分のハードウェアクロックを server として追加登録すると、万が一、他の参照サーバが全部不合格だった場合の「押さえ」となる。 fudge コマンドは、本来、ハードウェア的な基準時計から時刻を読み込む際に使うコマンドだが、筆者は別途電波時計などのデバイスを接続した経験はない。興味のある人は Reference Clock Options を読んでみるといいだろう。
ただし、ntp-4.2.2 以降では、fudge や server で RTC を指定することの代替として orphan という仕組みが導入されたので、そちらを使った方がいい。詳しくは tos の項を参照。
server コマンドでローカルクロックを指定しないほうがいい、とするドキュメントも多く見られる。Linux はどうやら、他の参照クロックをすぐに切り捨ててローカルクロックを優先同期先に選んでしまう傾向があるからだ。筆者も最近では `server 127.127.1.0' を書くことはほぼない。
ntp.jst.mfeed.ad.jp や s2csntp.miz.nao.ac.jp など、DNSラウンドロビンによって特定またはランダムな実ホストを返してくるサイトを利用するためのもの。左記に挙げたサイトはどちらも、DNSで牽いた時に、1回のクエリで 3つの IPアドレスを返してくる。これを
pool ntp.jst.mfeed.ad.jp
のように指定すると、牽かれたうちの 1つの IPアドレスしか ntpd のタイムソース候補に登録されない "server ..." とは違い、3つの IP全てが登録される。ただし、Automatic Server Discovery 機構 (オフィシャルDoc) が一枚噛むということの他には、動作にはほとんど違いはない。指定するのは DNSラウンドロビンのタイムサーバだけとは限らず、通常の単一ホストを追加で pool 指定することもできる。
pool ディレクティブは複数回使うことができ、そうすると、ntpd に登録されるリストは全ての pool 指定サイトからリゾルブされたホストの総和となる。重複したIPは自動的に除外される。ntpd によるサンプリング評価で不合格となったホストを除き、既定では最大 10ホストが System Peer 候補に残る (tosディレクティブの maxclock オプションで変更可能)。
peer ディレクティブは、server ディレクティブによって指定してある時刻参照先サーバが全てダウンした時の、バックアップタイムサーバを指定するためにある。NTP の用語ではこれを、シンメトリック (Symmetric) モードという。peer だけ指定して server や pool を指定しない設定は通常あり得ない。通常の参照先が1つでも生き残っている間は、peer指定の参照先は時刻参照には使用されない。シンメトリックモードを組むタイムサーバは、それぞれ異なったタイムソースを参照していないとあまり意味がない。
例えば、LAN内の NTP トポロジーの頂点に、同じ階層 (stratum) のNTPサーバA とNTPサーバB が立ててあるとする。この時、サーバA とサーバB を互いにシンメトリックピアにしておけば、サーバA の参照している外部のNTPサーバが全てダウンしたとしても、サーバA はサーバB に時刻を同期して、自機の時刻を正常にキープすることができる。また、逆の局面ではサーバA がサーバB を助けてやれる。それだけでなく、(NTPの Association Management ページによると) 生き残った健常なシンメトリックピアは、他のピアの時刻提供能力喪失を検知でき、クライアントへの時刻提供の責務を迅速に引き受けることができるというメリットもあるらしい。このように互いに相手を peer にしている状態を、シンメトリック-アクティブ モードと呼ぶ。それに対して、サーバB の設定ファイルにはサーバA が peer指定されておらず、サーバA が一方的に peer を張っている状態を シンメトリック-パッシブ モードという。
peer の基本的な記述法は、前記 server ディレクティブとほぼ共通。前出の ntp.conf をベースにすると、シンメトリック-アクティブ モードの場合のサーバA (192.168.0.1) とサーバB (192.168.0.2) それぞれの主設定ファイルは以下のようになる。
tinker step 2 stepout 300 panic 1800 tos orphan 6 disable monitor restrict default ignore restrict 127.0.0.0 mask 255.0.0.0 restrict 192.168.0.1 restrict 192.168.0.2 noquery nomodify restrict 210.173.160.57 noquery nomodify notrap nopeer restrict 133.40.41.134 noquery nomodify notrap nopeer restrict 192.168.0.0 mask 255.255.255.0 noquery nomodify nopeer driftfile /var/lib/ntp/drift # Symmetric Peer peer 192.168.0.2 key 8 minpoll 6 maxpoll 6 true # ntp2.jst.mfeed.ad.jp server 210.173.160.57 maxpoll 11 # one of s2csntp.miz.nao.ac.jp server 133.40.41.134 prefer maxpoll 11 # local clock #server 127.127.1.0 #fudge 127.127.1.0 stratum 10 crypto pw secret # includefile /etc/ntp/crypto/pw keys /etc/ntp/keys trustedkey 8 998 # requestkey 998 # controlkey 998
tinker step 2 stepout 300 panic 1800 tos orphan 6 disable monitor restrict default ignore restrict 127.0.0.0 mask 255.0.0.0 restrict 192.168.0.2 restrict 192.168.0.1 noquery nomodify restrict 210.173.160.27 noquery nomodify notrap nopeer restrict 210.173.160.87 noquery nomodify notrap nopeer restrict 192.168.0.0 mask 255.255.255.0 noquery nomodify nopeer driftfile /var/lib/ntp/drift # Symmetric Peer peer 192.168.0.1 key 8 minpoll 6 maxpoll 6 true # ntp1.jst.mfeed.ad.jp server 210.173.160.27 maxpoll 11 # ntp3.jst.mfeed.ad.jp server 210.173.160.87 maxpoll 11 # local clock #server 127.127.1.0 #fudge 127.127.1.0 stratum 10 crypto pw secret # includefile /etc/ntp/crypto/pw keys /etc/ntp/keys trustedkey 8 999 # requestkey 999 # controlkey 999
アクセス制限:
peer指定:
trustedkey指定:
ピア両方の主設定ファイルと対称鍵ファイルを整備後、ntpd をリスタートして、外部参照クロックの選定が終わる頃を見計らって ntpq ツールで状態を確認する。
root# ntpq ntpq> lpeers remote refid st t when poll reach delay offset jitter ============================================================================== 192.168.0.2 210.173.160.27 3 u 46 64 376 0.919 -306.72 12.189 <--st=16やoffset=0は異常 *133.40.41.134 133.243.238.244 2 u 30 64 377 10.162 19.916 42.331 ntpq> assoc ind assID status conf reach auth condition last_event cnt =========================================================== 1 55276 f014 yes yes ok reject reachable 1 <--reach=yesでauth=okであれば正常 2 55277 9614 yes yes none sys.peer reachable 1 ntpq> pstatus 55276 assID=55276 status=f014 reach, conf, auth, 1 event, event_reach, <--reach、authがあること。状態コードが eで始まるのは変 srcadr=192.168.0.2, srcport=123, dstadr=192.168.0.1, dstport=123, leap=00, stratum=3, precision=-23, rootdelay=10.437, rootdispersion=586.502, refid=210.173.160.27, reach=036, unreach=0, <--(以下略)
ここで試しに、カーネルファイヤーウォール iptables を使って外部クロックサーバを参照不能にしてみる。
root# iptables -A OUTPUT -p udp -d 133.40.41.134 --dport 123 \
-j REJECT --reject-with icmp-host-unreachable
暫く後、状態の推移を観察してみる。
ntpq> pstatus 55276 assID=55276 status=f414 reach, conf, auth, sel_candidat, 1 event, event_reach, <--候補に格上げされた srcadr=192.168.0.2, srcport=123, dstadr=192.168.0.1, dstport=123, leap=00, stratum=3, precision=-23, rootdelay=10.452, rootdispersion=365.265, refid=210.173.160.27, reach=376, unreach=0, ntpq> assoc ind assID status conf reach auth condition last_event cnt =========================================================== 1 55276 f414 yes yes ok candidat reachable 1 <--候補になっている 2 55277 8623 yes yes none sys.peer lost reach 2 <--外部サーバは通信不可だがまだ優先参照先のまま ntpq> lpeers remote refid st t when poll reach delay offset jitter ============================================================================== *192.168.0.2 210.173.160.27 3 u 28 64 377 0.029 -322.55 1.115 <--さらに暫く後、遂に優先参照先に 133.40.41.134 133.243.238.244 2 u 909 64 0 10.037 -9.161 0.000 ntpq> pstatus 55276 assID=55276 status=f614 reach, conf, auth, sel_sys.peer, 1 event, event_reach, <--優先参照先になっている srcadr=192.168.0.2, srcport=123, dstadr=192.168.0.1, dstport=123, leap=00, stratum=3, precision=-23, rootdelay=10.315, rootdispersion=324.524, refid=210.173.160.27, reach=376, unreach=0,
実験が終わったら、ファイヤーウォールを元に戻すのを忘れずに。
root# iptables -D OUTPUT -p udp -d 133.40.41.134 --dport 123 \
-j REJECT --reject-with icmp-host-unreachable
ntpd の時刻合わせアルゴリズムを調整する場合に指定する。書くなら、設定ファイルの一番最初に書かなければならない。上の例は、「参照クロックと 2秒以上ずれた状態が 300 秒以上続いたら slew モードから step モードへ動作を切替え、1800秒以上のずれが 2回続いたらデーモンを停止する」を意味する。既定動作では、ずれが 0.128秒以上の状態が 300秒以上続いた時に step モードに切り替わり、1000秒以上のずれが 2回連続して認められた時に停止する。ただし、上の例はあくまでも例であって、お勧めというわけではないので念のため。
step閾値は、0 に設定すると、ntpd は決して step モードへ移行しなくなる。panic閾値を 0 にすると、どんなに時間のずれた参照クロックにでも時刻を合わせる。stepout閾値は、マニュアルによると、他の動作にも影響を与えるので 300秒より小さくしてはならないとされている。tinker ディレクティブを書く時は 3つのオプションをセットで書かなければならないわけではない (そもそも tinker のオプションは他にもっとある)。サーバの設定ガイドなどでしばしば見かけるのは `tinker panic 0' の指定だ。
tos は、ntpd のタイムソース選定に関する動作を変更するためのディレクティブ。オフィシャルドキュメントに曰く "滅多に触ることはないが、そこにツマミがあると回す誘惑に耐えきれない輩も..." と。パラメータは幾つもあるが、変更することがあるのは以下の項目くらいだ。複数のパラメータを変更したい時は、ひとつの tos 行で、
tos orphan 6 maxclock 5
といった具合に書く。
orphan
ntp-4.2.2 以降では、fudge で RTC を指定することの代替として、orphan という仕組みが導入された。これを上記例 2行目のように tos コマンドで指定しておくと、他の参照サーバが全部駄目になった時にも NTPクライアントに時刻を提供し続けることができる。よって、純然たる NTPクライアントの ntp.conf に書いても無意味だ。orphan を使う時は "server 127.127.1.0" はもちろん "fudge 127.127.1.0" も書かない。orphan の引数は stratum で、"tos orphan 6" とすると、stratum 1 以上 5 以下のタイムソースが参照できているうちは orphan モードに切り替わらない。support.ntp.org の OrphanMode によると、参照ソースの想定される最悪の stratum + 2 の値にするのが妥当とされている。また、ntpd の起動直後や短時間の一時的なネットワークトラブルなどで orphan モードにころころ切り替わることのないよう、既定では 300秒 (=5分) の猶予期間が設けられている(※)。
※ 猶予時間は tos コマンドのパラメータ "orphanwait SEC" で変更できるらしいが、実装されたのは 4.2.7 (?)からで、CentOS 7 の ntp-4.2.6p5 では検証できない。
maxclock
pool ディレクティブでタイムソースリストに登録されるホストが多数の場合に System Peer 候補として残すホストの上限数。既定は 10。正確でない、遅延が大きいなど他の選定基準で落選しているホスト (ntpq コマンド出力の先頭記号の説明参照) は勘定に入らない。
restrict コマンドは、アクセスの restriction (制限) を規定するコマンド。書式は:
restrict {host|default} [mask netmask] [parameter] [parameter] ...
平たく言えば、「パケットの送信元が host にマッチしたら parameter を適用せよ」という構文だ。host 部は、アドレスでも、DNS や /etc/hosts での名前でも良い。例に挙げたアクセス制限セクションの1行目は、以降のマッチに当てはまらないアドレスだった場合の規定動作を default という特別なホスト部を使って指定している。主なパラメータには以下のものがある。support.ntp.org の AccessRestrictions が要点を突いていて分かりやすい。
ignore | すべての NTP パケットに答えない |
noquery | サーバの設定変更や状態の確認/変更に使用される NTP モード 6 (ntpq で使用) および 7 (ntpdc で使用) のパケットは受け付けない。時間の問い合わせには影響なし。なお、これらのパケットも UDP の 123 番ポートを使用する点に変わりはない。restrict による方法以外で、特に危険な一部のコマンドだけを無効にするやり方もある(※1) |
nomodify | noquery のモードに当てはまるパケットが送られ、実際に設定や状態が変更されるようなコマンドが来た場合には拒否する。noquery よりは規制が若干緩いことになる。時間の問い合わせには影響なし |
notrap | host に対して、こちらの NTP内部情報 (設定変数や時間の参照源などの情報) を提供しない。そうした情報の伝達に使われるのは NTP モード 6 のサブセットで、 `control message trap service' と呼ばれる。 ntpq に返答を返さなくなるが、時間の問い合わせには影響なし。 noquery との差異が分かりづらいが、 noquery は「要求を受け取らない」であるのに対し、 notrap は「返答を返さない」ということのようだ |
notrust | NTP Ver.4.2 以降と 4.1 以前とでは働きが大きく異なる。バージョン 4.1 まででは、「時間の参照源としては使わない (信用しない) が、その他の面では制限なし」の意。かたや NTP 4.2 からは、「参照源としてだけでなくクライアントとしても信用しない。ただし暗号認証によって信頼関係が証明されればその限りでない」という意味となり、サーバ側でこれを指定された host やサブネット (クライアント) からは、そのサーバを時間参照することさえできなくなる |
limited | ntpd のレートリミット(※2) を超えた頻度の問い合わせに対して、参照サービスの提供を拒絶する。モード 6/7 つまり ntpq 及び ntpdc のパケットはこの規制の対象とならない。limited を指定した restrict セクションがひとつでもあると "disable monitor" は無効(つまり monitor機能有効) になることに注意 |
limited (旧) |
ntpd は、ひとつのネットワークセグメントから同時に問い合わせできるクライアントの数を制限することができ、この制限パラメータを付けた host から問い合わせがあると、そのクライアントは接続数にカウントされる。「同時に」とはいっても、1度問い合わせがあるとそのクライアントは一定時間「アクティブ」なものとして記録に蓄積されるので、すぐに勘定からはずされるわけではない。蓄積時間は、別途 clientperiod コマンドで指定もでき (デフォルトは 3600 秒)、クライアントの「同時」接続台数は clientlimit コマンドで指定できる (デフォルトは 3 台)。その後、 clientperiod と clientlimit コマンドは廃止された? |
kod | "Kiss of Death" の頭文字。通常、ntpd のレートリミットを犯した問い合わせパケットは破棄されるだけだが、kod の指定してあるクライアントに対しては、破棄するとともに キス・オブ・デス パケットが送られる。KoD は NTPプロトコルのパケットフォーマットのひとつで、クライアントに対して「もう問い合わせをやめてくれ」という意向を伝えるもの。KoD を受け取った NTPクライアントは、「断られた」ことを示すビットを立て、そのサーバへはもう問い合わせをしなくなる決まりになっている。KoD パケットの送信自体、最大 1パケット/秒 (送信元アドレス毎) に制限されており、それ以上の頻度で送られてきた失礼な問い合わせパケットはただ単に破棄される。この仕組みによってビットの立ってしまったクライアントと当該サーバとの通信を再び可能にするには、クライアントとサーバ両方の ntpd を再起動しなければならないらしい。kod を指定する場合は limited も指定されていないと機能しない点に注意 |
noserve | ntpq 及び ntpdc のパケットだけを受け入れ、時間参照サービスは提供しない。つまり noquery の逆 |
nopeer | シンメトリック-アクティブモード締結の申し出 (NTP モード 1 のパケット) を受け付けない |
disable monitor
"restrict host " だけが指定してあってパラメータのないエントリは「制限なし」の意味となる。パラメータは常に、規制を強化する方向に働き、ひとつの restrict に複数のパラメータを指定すると、いずれかのパラメータが他のパラメータの効果を打ち消すことはなく、いわば制限ビットの上乗せ上乗せになっていくようだ。ただし、古いバージョンのドキュメントでは複数時の動作が曖昧だったので、まだ NTP 4.0.x や 4.1.x を使っているサーバでは、複数指定は避けたほうがいいと思う。ただし、例えば limited か notrust と、noquery か nomodify とを組み合わせるなど、役割系統の異なるパラメータ同士なら構わないかもしれない。
例の中の restrict セクション 4行目と 5行目は、参照に使う外部の公開 NTP サーバを、参照だけに使い、こちらの設定を変えようとしたり無用な状態問い合わせを行おうとする要求を受け付けないように、NTP パケットのモード 6 と 7 を「受けず答えず変更も拒絶」しシンメトリックモードも禁止している。そして最後の行は、サーバの置いてある LAN 内からの時間問い合わせに答えられるよう、mask キーワードを使用して 192.168.0.0/24、つまり 192.168.0.0 - 192.168.0.255 のアドレス範囲のクライアントに少し緩めの規制を施している (notrap を追加しても参照が成り立たないわけではない)。シンメトリック-アクティブ/パッシブモードを使用しないのなら、クライアントに対しては、より厳重にするため例のように nopeer を付加してもいい。
restrict コマンド行がこのように複数ある場合の ntpd の評価順序は、やや不気味だ。ntp.conf ファイルに書いてある順番ではない。ntpd は、まず、host のアドレスがより限定的具体的なものほど優先するカタチでソートを行い、その順番で評価していくのだ。例で言えば、192.168.0.1, 133.40.41.134 などは、マスクは暗黙に 255.255.255.255 なので同順で、最も限定的具体的なアドレスといえる。次が 192.168.0.0/255.255.255.0。その次は 127.0.0.0/255.0.0.0。そして、数字に直すと 0.0.0.0/0.0.0.0 である default が評価順位では最低になる。そうして最初にヒットした行が適用される。
なお、不正なパケットを、こうしたアプリケーションレベルに達する以前に水際でせき止めるために、ファイヤーウォールを設定するべきだ。外部から送られたパケットは送信元を詐称しているかもしれない。ファイヤーウォール専用のマシンを立てるに越したことはないが、サーバ自体の中にパケットフィルタを構築するだけでもかなりのセキュリティアップになる。
restrict ntp1.jst.mfeed.ad.jp noquery nomodify notrap nopeer restrict ntp2.jst.mfeed.ad.jp noquery nomodify notrap nopeer restrict ntp3.jst.mfeed.ad.jp noquery nomodify notrap nopeer pool ntp.jst.mfeed.ad.jp
restrict に指定するホストは、`dig ntp.jst.mfeed.ad.jp' を何度か発行してDNSサーバが返してくるIPをそのまま書いてもいいが、IPアドレスは変わることがあるので、それぞれを `dig -x 210.173.160.87' のように逆引きしてみてまともなホスト名が返ってくるようであれば、ホスト名で書いた方がより確実だ。
keys から始まる最後の4行は、認証に使う対称鍵(Symmetric Keys) の指定だ。ntpd の認証機構は、いくつかの使われ方をする。どのサーバを参照サーバとして信用するか、この NTP サーバのコントロールを誰にどのような認証方式とパスワードで許可するかなど。認証機構については次節で詳しく述べている。
ntpd は、認証機構そのものを "disable auth" (あるいは "authenticate no" でも可 ?) で無効化することもできる。しかし、参照に認証を使わないからといって認証機構を切ってしまうのは、大きなリスクとなる。オフィシャルドキュメントが不親切なのでいろいろと実験してみたが、"disable auth" した場合、クライアントとしてこのサーバを参照することを許している LAN 内のマシンから、 ntpdc ユーティリティでほぼ自由に設定をいじれてしまうのだ。 ntpdc コマンドは、サーバの設定を変更するようなコマンドをそのセッションで初めて発行した際に、必ずキーID とパスワードを求めてくる。しかし、認証機構を根こそぎ無効にしてあると、プロンプトは「儀礼的」に出すものの、 restrict コマンドで nomodify が指定してあっても、見当外れの ID とパスワードを入力しても設定が変更できてしまった。よって、特に積極的に認証を使うつもりがなくても、後述する対称鍵ファイルは作成し、キーファイルの指定 (keys ディレクティブ) はしておくべきだ。そこまでやっておけば restrict nomodify の設定も間違いなく機能してくれる。
コメントアウトしてある後の 3行は、ntpdc ユーティリティや ntpq を使って ntpd の設定を動的に変更したり、シンメトリックピアとの通信に認証を掛ける場合に使う。まず、対称鍵認証を使うためには、後述の 対称鍵ファイルに記述したキーのうち、使用候補にする全てのキーID を trustedkey に並べておく必要がある。その上で、ntpdc ユーティリティ用のキーID は requestkey ディレクティブで、ntpq ユーティリティ用は controlkey ディレクティブで指定する。このふたつの記述がない場合、ntpd は 「ntpq と ntpdc による設定変更は一切させない」と解釈する。つまり、コンソールマシンから入力されたキーIDとキーフレーズは常に間違いであるという扱いになる。ピアの対称鍵認証に使うキーID は、前述したように peer ディレクティブのパラメータで指定する。
説明が前後するが、keys の前にある "crypto pw secret " のことを付け加えておかなくてはならない。これは、ホスト秘密鍵などを暗号化する機能に関するもので、ntp-4.2.2 (?) から追加された。このディレクティブは ntp-keygen でキーを暗号化して作成してある時、その読み取りパスワードを ntpd に教えてやる。ただし、セキュリティ上、この文言はパーミションビットを絞り込んだ別ファイルに書いておき、 includefile 命令句 (例でコメントアウトしてあるところ) で読み込ませるのが普通だ。