debianで仮想マシンのntpサーバ間の同期を制限する

■仮想マシンのntpサーバ間の同期を制限する。
 仮想マシン(vmsqueeze)から見た「192.168.164.1」はホスト側(squeeze)の「192.168.188.188」に紐付く。

■まずは仮想マシンとホストOSの同期方法をIPv4のみにする
 「-4」をつけるだけ。「ntp.conf」で「-6」のある行はコメントアウトしておく。

$ sudo grep . /etc/default/ntp
NTPD_OPTS='-4 -g'

■設定ファイル「ntp.conf」

$ sudo grep -v "^#\|^\$" /etc/ntp.conf
driftfile /var/lib/ntp/ntp.drift
statsdir /var/log/ntpstats/
statistics loopstats peerstats clockstats
filegen loopstats file loopstats type day enable
filegen peerstats file peerstats type day enable
filegen clockstats file clockstats type day enable
server -4 192.168.164.1 iburst
restrict -4 default ignore
restrict -4 127.0.0.1
restrict -4 192.168.164.1 kod notrap
restrict -4 192.168.164.0 kod notrap nomodify nopeer
restrict -4 192.168.164.255 kod notrap nomodify nopeer noquery

■構文チェック(正常時)
 「normally」がどのような制限をしているかは出てこない点に注意。

$ sudo tail -100 /var/log/syslog | \
  grep ntpd | \
  sed s/"^.* ntpd\[[0-9]*\]\: "//g | \
  grep -A 6 "signal 15" | tail -7
ntpd exiting on signal 15
ntpd 4.2.6p2@1.2194-o Sun Oct 17 13:35:13 UTC 2010 (1)
proto: precision = 0.105 usec
Listen and drop on 0 v4wildcard 0.0.0.0 UDP 123
Listen normally on 1 lo 127.0.0.1 UDP 123
Listen normally on 2 eth0 192.168.164.188 UDP 123
Listen normally on 3 eth1 172.16.32.188 UDP 123

■構文チェック(異常時)
 以下のように「syntax error」、つまり構文エラーと出る。

$ sudo grep ntpd /var/log/syslog | grep syntax | sed s/".*ntpd\[[0-9]*\]\: "//g
line 40 column 27 syntax error, unexpected T_Mask, expecting T_EOC
line 41 column 25 syntax error, unexpected T_Mask, expecting T_EOC
syntax error in /etc/ntp.conf line 2, column 1
syntax error in /etc/ntp.conf line 36, column 27

■待ち受け

$ netstat -an | grep 123
udp        0      0 172.16.32.188:123       0.0.0.0:*
udp        0      0 192.168.164.188:123     0.0.0.0:*
udp        0      0 127.0.0.1:123           0.0.0.0:*
udp        0      0 0.0.0.0:123             0.0.0.0:*

■時刻のズレの傾向「driftfile」
 ※整数の桁が3桁になったことを見た事が無いが、ここの値に変化があるのが正常。

$ man ntp.conf | grep -A 9 driftfile
       driftfile driftfile
              This command specifies the name of the file use  to  record  the
              frequency  offset  of  the  local clock oscillator.  If the file
              exists, it is read at startup in order to set the  initial  fre‐
              quency  offset  and  then updated once per hour with the current
              frequency offset computed by the daemon.  If the file  does  not
              exist or this command is not given, the initial frequency offset
              is assumed to be zero.  In this case, it may take some hours for
              the  frequency  to  stabilize  and the residual timing errors to
              subside.

$ cat /var/lib/ntp/ntp.drift
-16.568

■時刻同期の記録「statsdir」
 「statistics」「filegen」で指定したファイルに出力。
 debianではデフォルトでコメントアウト(無効)になっている。
 ただし、「clockstats」ファイルを見た事が無い。。。

$ head -1 /var/log/ntpstats/*
==> /var/log/ntpstats/loopstats <==
56218 43145.569 0.001143000 -0.423 0.000404061 0.002703 6

==> /var/log/ntpstats/loopstats.20121018 <==
56218 43145.569 0.001143000 -0.423 0.000404061 0.002703 6

==> /var/log/ntpstats/peerstats <==
56218 43139.569 192.168.188.188 9024 0.001187589 0.000479525 7.937500361 0.000000238

==> /var/log/ntpstats/peerstats.20121018 <==
56218 43139.569 192.168.188.188 9024 0.001187589 0.000479525 7.937500361 0.000000238

■「loopstats」の簡単なグラフの作成例

$ dpkg -l | grep gnuplot | grep ^ii || sudo apt-get install -y gnuplot
$ (echo 'set terminal png size 1024,600'; \
 echo 'set output "loopstats.png"'; \
 echo 'plot "/var/log/ntpstats/loopstats" using 2:3 with linespoints'; \
 ) | gnuplot

■「loopstats.yyyymmdd」形式の一日前のグラフの作成例

$ (echo 'set terminal png size 1024,600'; \
 echo 'set output "loopstats.png"'; \
 echo 'plot "'/var/log/ntpstats/loopstats.`date '+%Y%m%d' --date "1days ago"`'" using 2:3 with linespoints'; \
 ) | gnuplot

■「iburst」(unreachable)での初期同期確立を高速化
 「burst」(reachable)オプションもある。

$ man ntp.conf | grep -A 7 iburst
       iburst When  the  server  is unreachable, send a burst of eight packets
              instead of the usual one.  The packet spacing is normally  2  s;
              however, the spacing between the first and second packets can be
              changed with the calldelay command to allow additional time  for
              a  modem  or  ISDN  call to complete.  This option is valid with
              only the server command and is a recommended  option  with  this
              command.

■「0.0.0.0」すべてのパケットを無視(ignore)。

restrict -4 default ignore

■「127.0.0.1」すべてのパケットを許可(フラグなしのデフォルトは許可)

restrict -4 127.0.0.1

■配信先のサブネットはアクセス制御フラグをつける。
 「mask 255.255.255.0」をつけると「syntax error」になったので省いた。
 デフォルトマスクは「255.255.255.255」

「notrap」はtrap サービスのためのパケットを拒否
 ⇒ネットワーク経由のロギングをさせない
「nomodify」はサーバーの状態を変更するntpq のクエリーを無視
 ⇒NTPのモード67の再設定要求をさせない
「nopeer」は通信相手用のメモリ資源を割り当て無い
 ⇒通信効率よりも都度メモリ資源を確保する
「noquery」はNTP のモード 67 のすべてのパケットを無視
 ⇒NTPのモード67の再設定要求と情報問い合わせの両方をさせない

restrict -4 192.168.164.1 kod notrap
restrict -4 192.168.164.0 kod notrap nomodify nopeer
restrict -4 192.168.164.255 kod notrap nomodify nopeer noquery

■「0.0.0.0」は「172.16.32.0/24」を含むのですべての問い合わせが出来ない。

$ sudo ntpdate 192.168.32.188
18 Oct 22:49:18 ntpdate[15228]: no server suitable for synchronization found

■「192.168.164.0」内ではクエリの問い合わせのみ行える。
 ※自身のIPでntpdateで問い合わせることは出来ない。ntpサービス(デーモン)を止める必要があるため。

$ sudo ntpdate 192.168.164.188
18 Oct 22:42:05 ntpdate[14886]: adjust time server 192.168.164.188 offset -0.000089 sec

■「192.168.164.1」は「192.168.188.188」に紐付く親「stratum=2」なので、「modify」を許可
 時刻同期の再設定を受け入れる。

$ ntpq -p -n
     remote           refid      st t when poll reach   delay   offset  jitter
==============================================================================
*192.168.164.1   133.243.238.244  2 u    2   64  367    0.229    0.073   0.021

■「127.0.0.1」はすべての問い合わせ、設定が許可されているので、以下のすべての監視が出来る。
 ※アクセス制御フラグにどんな影響があるか確認するには「127.0.0.1」に対してフラグを付けてみるのが手っ取り早い。

$ sudo watch -d -n 1 'ntpq -c rv -p -n ;ntptime'
Every 1.0s: ntpq -c rv -p -n ;ntptime                   Thu Oct 18 22:46:41 2012

associd=0 status=0615 leap_none, sync_ntp, 1 event, clock_sync,
version="ntpd 4.2.6p2@1.2194-o Sun Oct 17 13:35:13 UTC 2010 (1)",
processor="x86_64", system="Linux/2.6.32-5-amd64", leap=00, stratum=3,
precision=-23, rootdelay=8.942, rootdisp=945.224, refid=192.168.164.1,
reftime=d42a8690.798df705  Thu, Oct 18 2012 22:45:52.474,
clock=d42a86c1.780af037  Thu, Oct 18 2012 22:46:41.468, peer=24094, tc=6,
mintc=3, offset=0.073, frequency=-0.386, sys_jitter=0.021,
clk_jitter=0.021, clk_wander=0.009
     remote           refid      st t when poll reach   delay   offset  jitter
==============================================================================
*192.168.164.1   133.243.238.244  2 u   49   64  367    0.229    0.073   0.021
ntp_gettime() returns code 0 (OK)
  time d42a86c1.797a2000  Thu, Oct 18 2012 22:46:41.474, (.474520),
  maximum error 973475 us, estimated error 20 us
ntp_adjtime() returns code 0 (OK)
  modes 0x0 (),
  offset 60.000 us, frequency -0.386 ppm, interval 1 s,
  maximum error 973475 us, estimated error 20 us,
  status 0x1 (PLL),
  time constant 6, precision 1.000 us, tolerance 500 ppm,