Windows TIPS
[Scripting]
  Windows TIPS TOPへ
Windows TIPS全リストへ

ログオンの失敗をメールで通知する

解説をスキップして設定方法を読む

山本謙次
Microsoft MVP for Security)
2004/07/24
 
対象OS
Windows 2000
Windows XP
Windows Server 2003
重要なサーバなどでは、ログオンの失敗が発生したことを検知したい場合がある。
WMIを利用して、ログオン失敗時に発生するイベントを監視することができる。さらにCDOを組み合わせれば、ログオン失敗の発生をメールで通知させることが可能である。
 
解説

 重要性の高いサーバを管理しているときには、サーバへのログオン失敗が発生したことを検知したい場合がある。例えば社外ユーザー向けにホスティング・サービスを提供する場合や、社内ネットワーク向けのサーバであっても、個人情報などの重要データを扱うサーバを管理する場合などが考えられる。こうしたサーバでの認証失敗は、管理を行う部署から見れば想定外のことで、本来の状態から逸脱している。原因としては、例えば辞書攻撃などによる不正アクセスの発生や、自動化した処理の失敗などが考えられる。

Windows標準機能とWSHを使ってメールを送信する(TIPS)
管理者のためのWSH入門

 ログオンの失敗を検知する処理は、Windowsシステムに関する管理情報の取得や、各種管理作業の実行など、スクリプトやアプリケーションなどからWindowsシステムを制御可能にするインターフェイスのWMI(Windows Management Instrumentation)を利用すれば実現可能である。本稿では、このWMIを利用して、ログオン失敗が発生したら管理者にメールを送信するWSHスクリプトを紹介する。メールの送信では、Windows 2000/XP/Server 2003に標準搭載されているCDO(Collaboration Data Objects)と呼ばれるメッセージング・コンポーネント(CDOSYS.DLL)を利用する。


設定方法

 認証失敗が発生したことを検知するには、イベントログ上で特定イベントの発生を待ち受け、別の処理を開始する。前述したとおり、これにはWMIを利用できる。今回はWMIが提供するさまざまなクラス/オブジェクトのうち、WbemServicesオブジェクトとその配下のメソッドを利用している。

スクリプトの構成と作成のポイント

 以下は今回紹介するスクリプトの構成である。

スクリプトでの処理の流れ
WMIのWbemServicesオブジェクトとその配下のメソッドを利用してイベントを検知し、CDOでメールを送信する。通知処理実行後は、初期化を行って次のイベントに備える。

■指定したイベント発生の検知
 WbemServicesオブジェクトのメソッドの1つであるExcecNotificationQueryを使うと、事前に指定したイベントの発生を監視し、このイベントの照会を行ったアプリケーションに結果を通知することができる。監視したいイベントの指定は、ExcecNotificationQueryの後にSQL文を使って実施する。

■監視対象とするイベント
 今回のログオン失敗の検知には、イベントID=529の「ログオン失敗の発生」を指定した。これはほかに見掛けないイベントIDであることと、イベントのパラメータとして「どのユーザーが」「どのワークステーションから」ログオンを試みたかの情報を取得できるからである。

 幸い今回のログオン失敗の検知では、全イベント・カテゴリを通じて目的を一意的に識別できるイベントID(529)が見つかった。しかし一般には、イベントIDを指定するだけでは目的とするイベントの発生を絞り込んで検知することは難しい。このような場合には、イベントのカテゴリ(システム、アプリケーション、セキュリティ)やソース(Service Control Manager、MSSQLServer、eventlogなど)、イベントIDで絞り込む必要がある。あるいはイベントの発生パターンとメッセージ内容が決まっているなら、メッセージ内容の一部も絞り込みの条件として指定するとよいだろう。

 例えば、クラッシュダンプやCHKDSKの後に記録されるイベントを検知するのに EventIdentifier(例えば1000や1001)だけで検索を行うと、Windows XP や Windows Server 2003では、OSのクラッシュだけではなく、アプリケーションのハングアップや、サーバ・ベンダなどが独自に提供しているサーバ管理ツールによるメッセージまで拾ってしまい、極めて精度が粗くなってしまう。このような場合には、EventType(情報、警告、エラー、成功の監査、失敗の監査)やSourceName(ソース名)を併せて指定するとよいだろう。

 イベント特定のために指定可能な項目の詳細については、Platform SDKに含まれるWMI SDKを参照されたい。WMI Classesの解説部分にWin32_NTLogEventの項目があり、こちらに情報がまとまっている。

■警告の発信
 イベントが発生したら、イベントから得られた情報をメールで送信する。今回はWindows 2000以降で汎用的に使用可能なCollaboration Data Object(CDO)for Windows 2000を用いた。CDOはスクリプトから利用可能な送信専用のメール・クライアントである。利用に当たっては、送信用として利用可能なSMTPサーバを適切に設定しておく必要がある。詳細については関連記事「Windows標準機能とWSHを使ってメールを送信する」を参照されたい。

 発信するメッセージの件名には、ログオン失敗が発生したコンピュータ名を記載し、メッセージ本文には注意を喚起する簡単な文章に加え、作成時刻、メッセージ内容を記載する。

発信メールの例
メッセージの件名にはログオン失敗が発生したコンピュータ名を記載し、メッセージ本文には注意を喚起する簡単な文章に加え、作成時刻、メッセージ内容を記載する。

実行環境、タスク登録時の注意

 スクリプトが完成したら、タスク・スケジューラにスクリプトを追加し、コンピュータ起動時にスクリプトが実行されるように設定する。なお、コンピュータの稼働時間が72時間を超える場合は、作成したタスクのプロパティで継続時間の指定を外すか、適切な時間数を指定すること。デフォルトでは、タスクの連続稼働時間が72時間に設定されているため、これ以上システムを連続稼働すると、タスクが終了されてしまう。

サンプル・スクリプト

 以下にサンプル・スクリプトを示す。なお実際の運用では、スクリプト中のboosterにメール送信に使用するSMTPサーバのIPアドレスまたはFQDNを指定し、FromとToは実環境に合わせた適切なものに置き換えること。End of Article

Option Explicit

' 変数、定数の定義
Const cdoSendUsingMethod        = _
"http://schemas.microsoft.com/cdo/configuration/sendusing"
Const cdoSendUsingPort          = 2
Const cdoSMTPServer             = _
"http://schemas.microsoft.com/cdo/configuration/smtpserver"
Const cdoSMTPServerPort         = _
"http://schemas.microsoft.com/cdo/configuration/smtpserverport"
Const cdoSMTPConnectionTimeout  = _
"http://schemas.microsoft.com/cdo/configuration
/smtpconnectiontimeout"
Const cdoSMTPAuthenticate       = _
"http://schemas.microsoft.com/cdo/configuration/smtpauthenticate"
Const cdoBasic                  = 1
Const cdoSendUserName           = _
"http://schemas.microsoft.com/cdo/configuration/sendusername"
Const cdoSendPassword           = _
"http://schemas.microsoft.com/cdo/configuration/sendpassword"

'boosterには送信に使う SMTP サーバの IP アドレスか FQDN を指定する
Const booster                   = "XXX.XXX.XXX.XXX"

Dim WshShell, env, events, NTEvent, objConfig, Fields, objMessage, subj

' WMIを通じて抽出するイベントの条件指定
'Set WshShell = WScript.CreateObject("WScript.Shell")
'set env = WshShell.Environment("SYSTEM")
Set events =  GetObject("winmgmts:{impersonationLevel=impersonate,(security)}") _
                       .ExecNotificationQuery("SELECT * FROM "    & _
                       "__instancecreationevent WHERE "           & _
                       "targetinstance isa 'Win32_NTLogEvent' " & _
       "and targetInstance.EventIdentifier= '529' " )

' 指定されたイベントの発生に伴い実行するアクションの指定
if err <> 0 then
WScript.Echo Err.Description, Err.Number, Err.Source
end if

Do
'CDOメッセージの作成
Set NTEvent = events.NextEvent
subj ="[Notice] ログオンの失敗発生: " & NTEvent.TargetInstance.ComputerName
Set objConfig = CreateObject("CDO.Configuration")
Set Fields = objConfig.Fields

With Fields
.Item(cdoSendUsingMethod)       = cdoSendUsingPort
.Item(cdoSMTPServer)            = booster
.Item(cdoSMTPServerPort)        = 25
.Item(cdoSMTPConnectionTimeout) = 10
.Item(cdoSMTPAuthenticate)      = cdoBasic
.Item(cdoSendUserName)          = "username"
.Item(cdoSendPassword)          = "password"
.Update
End With

Set objMessage = CreateObject("CDO.Message")
Set objMessage.Configuration = objConfig

With objMessage
.To = "あて名 <あて先メールアドレス>"
.From = "差出人 <差出人メールアドレス>"
.Subject  =subj
.TextBody ="サーバ " & NTEvent.TargetInstance.ComputerName & " で、標記のイベントが発生しました。" &vbCRLF & "即刻、詳細を確認願います。" &vbCRLF &vbCRLF &"検知時刻: "& Now() &vbCRLF &vbCRLF & "[イベント詳細] " &vbCRLF &vbCRLF & NTEvent.TargetInstance.message
.Send
End With

' メッセージ送信後、利用したオブジェクトをクリアする
Set Fields = Nothing
Set objMessage = Nothing

' 処理完了後は次のイベントに備え、LoopによりDoループの先頭に戻る
Loop
  • サンプル・ファイルのダウンロード注:サンプル・ファイルをダウンロードするには、上のリンクを右クリックして適当なファイル名で保存する)
「Windows TIPS」


Windows Server Insider フォーラム 新着記事
@ITメールマガジン 新着情報やスタッフのコラムがメールで届きます(無料)

注目のテーマ

Windows Server Insider 記事ランキング

本日 月間