share facebook facebook2 twitter menu hatena pocket slack

2015.06.10 WED

WINDOWSサーバでのログオン・ログオフイベントを検知するnagiosプラグイン(powershell,イベントログ)

WRITTEN BY三浦 剛慈

■説明

WINDOWSサーバにユーザーがリモートログオン・ログオフしたことを検知するnagiosプラグインを書きました。

poweshellのGet-WinEventコマンドレットを使って、securityイベントログからログオン・ログオフのログを検索します。HITすればCRITICALとなり通知されます。

  • ログオン情報として [ログオン時間・ログオンアカウント・IPアドレス]
  • ログオフ情報として [ログオン時間・ログオンアカウント]
    を表示します。

■目的

本番環境用のWINDOWS踏み台サーバに仕込んでおいて、作業者がログオン・ログオフしたことを、管理者がnagiosを利用して自動チェック出来るようにする為に作成しました。

■ソースコード

##################################
## parameter
param
(
    #events log is checked from "$beforemin" min ago
    [int]$beforemin=5,
    [string]$logonevent='logon_event'
)

##################################
## consts
$LOGON='LOGON_EVENT'
$LOGOFF='LOGOFF_EVENT'
$LOGON_EVENTID='4624'
$LOGOFF_EVENTID='4634'
$STATE_OK = 0
$STATE_WARN = 1
$STATE_CRITICAL = 2
$STATE_UNKNOWN = 3

##################################
## variables
$Ret_Code=$STATE_UNKNOWN
$beforemsec=$beforemin*60*1000

##################################
## routine

#decide whether logon-event or logoff-event
if( $logonevent -eq $LOGON)
{
    $EventID=$LOGON_EVENTID
    $printBuf+=$LOGON + '; '
    $seek_time_file = ".logonchk" + $LOGON + ".seek"
}
else
{
    $EventID=$LOGOFF_EVENTID
    $printBuf+=$LOGOFF + '; '
    $seek_time_file = ".logonchk" + $LOGOFF + ".seek"
}
#get seek point data(time)
If(Test-Path -path $seek_time_file)
{
} 
else
{
        New-Item $seek_time_file -itemType File|Out-Null
    (Get-Date).AddMinutes(-$beforemin).ToString("yyyy-MM-dd hh:mm:ss")|Out-File $seek_time_file
}
$lines = @(Get-Content $seek_time_file)
#set seek point(time)
If( $lines.Count -eq 0)
{
    $seek_time=$beforemsec
} 
else
{
    $seek_time= (New-TimeSpan $lines[0] (Get-Date -format "yyyy-MM-dd hh:mm:ss")).TotalMilliseconds
}
#get eventlog of logon or logout event with get-winevent cmdlet
$Events = get-winevent -logname Security -filterxpath `
            ("Event[System[Provider[@Name='Microsoft-Windows-Security-Auditing'] "`
            +"and EventID=$EventID and TimeCreated[timediff(@SystemTime) <= $seek_time]]] "`
            +"and Event[EventData[Data[@Name='LogonType']='10']]") 2> $null
#check whether logon or logout event is exist
if( $Events -eq $null)
{
    write-host "OK - No matches found."
    $Ret_Code = $STATE_OK
}
else
{
    ForEach ($Event in $Events)
    {
    #convert eventlog to xml format
        $eventXML = $Event.ToXml()
        For ($i=0; $i -lt $eventXML.Event.EventData.Data.Count; $i++)
        {
            Add-Member -InputObject $Event -MemberType NoteProperty -Force `
            -Name $eventXML.Event.EventData.Data[$i].Name `
            -Value $eventXML.Event.EventData.Data[$i].'#text'
        }
    #edit print message buf in eventlog
        if( $logonevent -eq $LOGON)
        {#logon event
            $printBuf += "[" + $Event.TimeCreated.ToString() + " , " `
            + $Event.TargetUserName.ToString() + " , " `
            + $Event.IpAddress.ToString() + "] "
        }
        else
        {#logoff event
            $printBuf += "[" + $Event.TimeCreated.ToString() + " , " `
            + $Event.TargetUserName.ToString() + "] "
        }
    }
    #print message
    Write-Host $printBuf
    $Ret_Code = $STATE_WARN
}
#get next seek point(time)
$last_date=get-date -format "yyyy-MM-dd hh:mm:ss"
#save date
$last_date|Out-File $seek_time_file

exit $Ret_Code

■各種設定 ※監視間隔が5分のケース

・nrpe.cfg
#ログオン検知
command[nt_logon_event]=powershell -nologo -NoProfile -ExecutionPolicy unrestricted -command "& { C:nrpe_ntnrpe_nt' pluginsbincheck_logon_account.ps1' -beforemin 5 -logonevent 'LOGON_EVENT'; exit $lastexitcode }"
#ログオフ検知
command[nt_logoff_event]=powershell -nologo -NoProfile -ExecutionPolicy unrestricted -command "& { C:nrpe_ntnrpe_nt' pluginsbincheck_logon_account.ps1' -beforemin 5 -logonevent 'LOGOFF_EVENT'; exit $lastexitcode }"
・command.cfg
#ログオン検知
define command{
        command_name nt_logon_event
        command_line $USER1$/check_nrpe -H $HOSTADDRESS$ -c nt_logon_event
}
#ログオフ検知
define command{
        command_name nt_logoff_event
        command_line $USER1$/check_nrpe -H $HOSTADDRESS$ -c nt_logoff_event
}
・nagisサーバ側の監視サーバ用configファイル
#ログオン検知
define service {
        use cloudpack_service
        host_name clp_mgmt-ec2
        service_description eventlog_logon_event
        service_groups nt_eventlog
        check_command nt_logon_event
        max_check_attempts 1
        contact_groups rjb_sulog-group
        notification_interval 5
        flap_detection_enabled 0
}
#ログオフ検知
define service {
        use cloudpack_service
        host_name clp_mgmt-ec2
        service_description eventlog_logoff_event
        service_groups nt_eventlog
        check_command nt_logoff_event
        max_check_attempts 1
        contact_groups rjb_sulog-group
        notification_interval 5
        flap_detection_enabled 0
}

■実行例 ※nagiosサーバから手打ち実行

※ログオンイベント検知
# /usr/lib64/nagios/plugins/check_nrpe -H 10.0.XX.XX -c nt_logon_event
LOGON_EVENT; [2015/04/17 20:49:48,Administrator,172.XX.XX.XX] [2015/04/17 19:46:57,Administrator,172.30.4.22] [2015/04/17 19:29:40,Administrator,172.XX.XX.XX] [2015/04/17 19:29:20,Administrator,172.30.12.14] [2015/04/17 19:28:58,Administrator,172.XX.XX.XX]
〜
※ログオフイベント検知
# /usr/lib64/nagios/plugins/check_nrpe -H 10.0.XX.XX -c nt_logoff_event
LOGOFF_EVENT; [2015/04/17 20:52:25,Administrator] [2015/04/17 19:48:35,Administrator] [2015/04/17 19:29:54,Administrator] [2015/04/17 19:29:36,Administrator] [2015/04/17 19:29:12,Administrator]

powershell難しい・・・

元記事はこちら

koujiのblog : WINDOWSサーバでのログオン・ログオフイベントを検知するnagiosプラグイン(powershell,イベントログ)