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

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

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

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

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

しかし、今度は実際のユーザがログオフしていないにも関わらずイベントが記録されてしまうため、結局のところ、ユーザのログオフを判断することができないでいます。なぜ、こうした事象が発生するのでしょうか?また対策はないのでしょうか?
これは、Windowsの認証機構やActive Directoryの仕様となります。
まず、「アカウントログオンイベントの監査」とは、厳密にはActive DirectoryのKerberos認証におけるTGTその他のチケットの発行を監査する機構になります。図6のように、TGTの発行は通常対話ログオン時にKDC(ドメインコントローラ)がクライアントと通信することによって行われます。TGTが発行されると「認証チケットの許可」(ID: 672)がイベントログに記録されます。しかし、ログオフ時にはこのチケットはサーバと通信を行うことなく単に破棄されるため、特にイベントは発生しません。

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

対話的なログオンログオフを確実に記録したいという場合は、ログオンスクリプトやログオフスクリプトを活用すると良いでしょう。簡単なスクリプト例を図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のようにイベントログに出力することが可能です。

