2015年3月10日火曜日

Workgroup環境でのWindowsの時刻同期の設定方法

Linuxはntpd使って同期設定をきちんとしてあげれば高い精度で時刻を維持してくれるが、Windowsを使って、特にドメインに所属しないで使うWorkgroup環境の場合は、Windows Timeサービス(=W32Time)をデフォルトの設定で使うだけでは、イマイチな精度でしか同期されない。

Windows Timeサービスの仕様と精度を上げる方法について記載する。

Windows Timeサービス(W32Time)の仕様

まず、前提としてMicrosoftのKB939322から以下の文言を引用する。
ネットワーク上のノード間の W32Time サービスの精度は、保証およびサポートされません。W32Time サービスは、時間が重要となるアプリケーションのニーズを満たす完全な機能を備えた NTP ソリューションではありません。W32Time サービスは、主に次の手順を実行するように設計されています。

・Kerberos v5 認証プロトコルが正しく動作するようにします。
・クライアント コンピューターに緩やかな同期時刻を提供します。

W32Time サービスは、1 ~ 2 秒の範囲で同期時刻を確実に維持できません。このような許容誤差は、W32Time サービスの設計仕様に含まれていません。

ntpdの発想とは全く異なることがわかると思うが、簡単に言うと数秒のずれは平気で起きるし、Kerberos認証の時刻のずれの許容時間は5分なので±5分のずれは許容するということ。この発想を考えると、間違ってもWindows ServerをNTPの時刻参照先サーバーとして構築などしてはいけない。

また、Active Directory環境とWorkgroup環境で時刻同期の内容も異なるので、以下に違いを記載する。

Workgroup環境

「タスクスケジューラ」→「タスクスケジューラ ライブラリ」→「Micrsoft」→「Windows」→「Time Synchronization」に「SynchronizeTime」というタスクがあり、以下の通りとなっている(※Windows7の場合)。
・トリガー:2005/1/1以降毎週日曜日、1:00に起動
・操作:%windir%\system32\sc.exe start w32time task_started
・オプション:スケジュールされた時刻にタスクを開始できなかった場合、すぐにタスクを実行する
つまり、日曜1:00または、日曜1:00を過ぎた初回起動時に一度同期するがその後は次の日曜1:00まで同期しない。はっきり言って、Windows標準設定では時刻同期にやる気は無い。また、sc.exe start w32time task_startedの"task_started"の意味はw32timeのサービスを開始して同期が取れたら自動でサービスを停止する引数となり、同期を取ったらサービスは停止状態になる。

さらにもう1つ面倒な設定が存在する。それが「トリガーサービス」となる。トリガーサービスは、サーバー起動時に動作する機能で、その際のシステムの状態をトリガーにしてサービスの起動・停止を判断して実行する機能となる。w32tmの場合は以下の通り設定されている。
・ドメイン参加:w32tmサービス開始
・ドメイン非参加:w32tmサービスを停止
ドメイン非参加のWorkgroup環境では、トリガーサービスによりサービスが起動していても停止されてしまう。

Active Directory環境(概要)

今回はWorkgroup環境の説明がメインなので概要だけ。

Active Directoryでは、ドメインへのログイン認証にKerberos認証を使うためドメインコントローラーとメンバー間で時刻のズレを±5分に抑える必要がある。そのため、ドメインコントローラーとメンバー間では以下の通り同期が機能する。
1. ドメインコントローラーのPDCエミュレーターがドメインのタイムサーバーとなる
2. 他のドメインコントローラーはPDCエミュレーターのドメインコントローラーと同期する
3. メンバーはログイン先のドメインコントローラーと同期する
さらに同期間隔もWorkgroup環境のように週1回ということはなく、もっと短い間隔(1時間に1回)で行われるようだ。

Workgroup環境でも精度をそこそこ上げる方法

以下の観点で精度を上げる。
1. W32Timeサービスを常に開始状態にする
2. トリガーサービスを停止する
3. 同期間隔を短くする
4. (おまけ)時刻のズレを確認するコマンドを覚えておく
順番に対応しよう。

1. W32Timeサービスを常に起動させておく

「サービス」の画面で「Windows Time」を「手動」→「自動」または「自動 (遅延開始)」に変更する。

※なお、「自動 (遅延開始)」にすればトリガーサービスによるW32Timeサービス停止が処理された後に開始されるため、「2. トリガーサービスを停止する」を実施しなくても、サービスは開始状態で維持できる可能性があるが、タイミングの問題で上手くいかないこともあり得るので、オススメはできない

2. トリガーサービスを停止する

参考URL(http://support.microsoft.com/kb/2385818/ja)に記載の方法で停止する。
sc triggerinfo w32time delete   ←設定削除コマンド
sc qtriggerinfo w32time      ←確認コマンド
なお、タスクスケジューラの「SynchronizeTime」のタスクについては、W32Timeサービスが開始状態であれば、そもそも動作しない(サービスは既に起動している旨のメッセージが出るだけ)になるため、特に対応は不要となる。

3. 同期間隔を短くする

以下レジストリをいじる。
HKEY_LOCAL_MACHINE¥SYSTEM¥CurrentControlSet¥Services¥W32Time¥TimeProviders¥NtpClient\

SpecialPollInterval (REG_DWORD)
604800→3600 (10進数)
※604800秒(7日間)→3600秒(1時間)に変更
設定を確認するコマンドは以下の通り。
w32tm /query /configuration

4. (おまけ)時刻のズレを確認するコマンドを覚えておく

ntpdであればntpq -pのようなコマンドを覚えておくと同期状態が確認できて便利。
w32tm /monitor /computers:[タイムサーバー]   ←時刻のズレを確認するコマンド

C:\>w32tm /monitor /computers:192.168.100.100
192.168.100.100[192.168.247.100:100]:
    ICMP: 1ms 遅延
    NTP: -0.1615824s ローカル コンピュータの時刻からのオフセット        RefID: 'LOCL' [0x4C434F4C]
        階層: 1
前述のとおり、そもそもW32Timeに正確な時刻同期を求めるのも酷なので、とりあえず同期処理が成功していることを確認するのであれば、以下コマンドでもOK。
w32tm /query /status      ←前回の同期状況を確認するコマンド

閏インジケータ: 0 (警告なし)
階層: 2 (二次参照 - (S)NTP で同期)
精度: -6 (ティックごとに 15.625ms)
ルート遅延: 0.0312500s
ルート分散: 0.5493823s
参照 ID: 0xC0A8F73B (ソース IP:  192.168.100.100)
最終正常同期時刻: 2015/03/09 21:07:46ソース: 192.168.100.100,0x9
ポーリング間隔: 15 (32768s)

---

w32tm /query /status /verbose   ←詳細表示

閏インジケータ: 0 (警告なし)
階層: 2 (二次参照 - (S)NTP で同期)
精度: -6 (ティックごとに 15.625ms)
ルート遅延: 0.0312500s
ルート分散: 0.5493823s
参照 ID: 0xC0A8F73B (ソース IP:  192.168.100.100)
最終正常同期時刻: 2015/03/09 21:07:46ソース: 192.168.100.100,0x9
ポーリング間隔: 15 (32768s)

フェーズ オフセット: -0.0504310s
クロック レート: 0.0156252s
State Machine: 2 (同期)
タイム ソース フラグ: 0 (なし)
サーバーのロール: 0 (なし)
最終同期エラー: 0 (コマンドは正しく完了しました。)最終正常同期時刻からの時間: 2022.3559758s

参考URL

高精度の環境に向けた Windows タイム サービスの構成を目的とするサポート範囲
http://support.microsoft.com/kb/939322/ja

Windows Server 2008 の Windows タイム サービスとこれにより発生するインターネット通信
https://technet.microsoft.com/ja-jp/library/cc731790%28v=ws.10%29.aspx

Windows 7 および Windows Server 2008 R2 のスタンドアロン環境で Windows Time サービスが自動的に起動しない
http://support.microsoft.com/kb/2385818/ja