Active Directory ドメインで、ユーザのログオン/ログオフの状況を監査したい

対象プラットフォーム

質問

現在、Windows 2000のActive Directoryドメインを管理しています。

不正アクセスの検出などの目的で、ドメインへのユーザのログオンやログオフの成功、失敗を監査しようと考え、ドメインコントローラセキュリティポリシーの「Windows の設定」-「セキュリティの設定」-「ローカルポリシー」-「監査ポリシー」の「アカウントログオンイベントの監査」で図1のように成功、失敗ともにチェックを行なっています。


図1: 監査の設定

現状は図2のように、イベントログにはユーザが実際にログオンやログオフしているかどうかに関わらず、「サービスチケットの許可」(ID: 673)が記録されてしまうものの、


図2: アカウントログオンイベントの監査有効時のイベントログへの出力

ログオンの成功は図3の「認証チケットの許可」(ID: 672)にて代替できると考えています。しかし、ログオフについては、対応する情報が記録されておらず困っています。


図3: イベントID672の詳細
(注)画面サイズが固定のため、この図では複数の画像を結合して表示しています。

なお、図1で「ログオンイベントの監査」も有効にすると、図4のように取得されるログの種類が増え、


図4: ログオンイベントの監査も有効にした状態のイベントログへの出力

「ユーザのログオン」(ID: 540)、「ユーザのログオフ」(ID: 538)が記録されるようになります。


図5: イベントID: 538のログ

しかし、今度は実際のユーザがログオフしていないにも関わらずイベントが記録されてしまうため、結局のところ、ユーザのログオフを判断することができないでいます。なぜ、こうした事象が発生するのでしょうか?また対策はないのでしょうか?

回答

これは、Windowsの認証機構やActive Directoryの仕様となります。

まず、「アカウントログオンイベントの監査」とは、厳密にはActive DirectoryのKerberos認証におけるTGTその他のチケットの発行を監査する機構になります。図6のように、TGTの発行は通常対話ログオン時にKDC(ドメインコントローラ)がクライアントと通信することによって行われます。TGTが発行されると「認証チケットの許可」(ID: 672)がイベントログに記録されます。しかし、ログオフ時にはこのチケットはサーバと通信を行うことなく単に破棄されるため、特にイベントは発生しません。


図6: アカウントログオンイベントの監査イベント発生のタイミング

一方「ログオンイベントの監査」とは、図7のようにサーバに対するセッションの確立、切断を監査する機構になります。例えばサーバ上の共有ディレクトリに接続すると、セッションの確立が行われるため、イベントログに「ユーザのログオン」(ID: 540)が記録されます。しかし、セッションは明示的に処理が行われたり、デフォルトで15分無通信状態が続いたりした場合に切断され、イベントログには「ユーザのログオフ」(ID: 538)が記録されます。これは対話的なログオン、ログオフとは無関係に行われます。

また、そもそも 「318253: ユーザー ログオフ時に監査が機能しない」に記述されているように、監査が機能しないケースもあります。

こうした理由により、監査ポリシーでは、ログオン画面からの対話的なユーザのログオン、ログオフの監査を行うことができないのです。


図7: ログオンイベントの監査イベント発生のタイミング

ログオン/ログオフスクリプトなどで代替を

対話的なログオンログオフを確実に記録したいという場合は、ログオンスクリプトやログオフスクリプトを活用すると良いでしょう。簡単なスクリプト例を図8と図9とに示します。

図8: ログオンスクリプトのサンプル

Const AUDIT_SUCCESS = 8

REM Create Objects
Set objShell = WScript.CreateObject("WScript.Shell")
Set objNetwork = WScript.CreateObject("WScript.Network")
Set objADSys = CreateObject("ADSystemInfo")

REM Build a message string
strMsg = "ユーザ " + objNetwork.UserName + " が、ドメイン " + _
    objNetwork.UserDomain + " (サーバ " + objADSys.GetAnyDCName + _
    ") にログオンしました。" 

REM Write to Eventlog
objShell.LogEvent AUDIT_SUCCESS, strMsg, objADSys.GetAnyDCName

図9: ログオフスクリプトのサンプル

Const AUDIT_SUCCESS = 8

REM Create Objects
Set objShell = WScript.CreateObject("WScript.Shell")
Set objNetwork = WScript.CreateObject("WScript.Network")
Set objADSys = CreateObject("ADSystemInfo")

REM Build a message string
strMsg = "ユーザ " + objNetwork.UserName + " が、ドメイン " + _
    objNetwork.UserDomain + " (サーバ " + objADSys.GetAnyDCName + _
    ") からログオフしました。" 

REM Write to Eventlog
objShell.LogEvent AUDIT_SUCCESS, strMsg, objADSys.GetAnyDCName

こうしたスクリプトを、図10のように適切なGPOの「ユーザの構成」中にあるログオンスクリプトやログオフスクリプトとして構成することで、ログオンやログオフの情報を図11のようにイベントログに出力することが可能です。


図10: ユーザの構成 - Windows の設定 - スクリプト(ログオン/ログオフ)

図11: スクリプトで取得したログオン/ログオフイベント

参考情報

注記・補足

  1. 2006.04.13 スクリプトのコメント行の先頭を「#」→「REM」にしました。
  2. 2003.07.06 HTMLレベルの整形、図の修正を行いました。
  3. 2003.04.11 Win2k:14213 をみて 318253 に関する記述を補足しました。
  4. 本文書は、日経 Windowsプロ 2002 年 12 月号の「トラブル解決 Q&A コーナー」に掲載された「Active Directory ドメインで、ユーザのログオン/ログオフの状況を監査したい」の草稿を筆者の方で HTML 化して掲載しているものです。

Copyright (C) 1998-2009 TAKAHASHI, Motonobu
Last update: 2006-07-12 00:00:19 JST
webmaster@monyo.com