Yahama ルーター 192.168.0.200 から
Windowsサーバー 192.168.0.100 へsyslogを送ることにする。
Yamahaルーターの設定。syslog debugは膨大なのでoffが望ましいだろう。
syslog host 192.168.0.100 syslog facility local1 syslog notice on syslog info on syslog debug off
Windowsサーバーの設定
ルーターからのデータはUDPで受けるので、ファイアウォールの詳細設定で、syslogに使う514番ポートの受信を許可する。
データを受けるためのsyslogサーバーを動かす。ルーターからはUDPでデータがバンバン送られてくるだけである。よって、特別な処理が必要ない場合、syslogサーバー用のソフトは必要なく、UDPで受けたデータをそのままファイルに出力するだけでよい。WindowsのPowerShellでsyslogサーバー(UDPホスト)を動かしているサイトがあったのでこれで動く。
ただ、日付はほしいので上記コードに追加した。以下をsyslog.ps1
に書く。
$Udp = New-Object Net.Sockets.UdpClient -ArgumentList 514 $Sender = $null Add-Type -TypeDefinition @" public enum Syslog_Facility { kern, user, mail, system, security, syslog, lpr, news, uucp, clock, authpriv, ftp, ntp, logaudit, logalert, cron, local0, local1, local2, local3, local4, local5, local6, local7, } "@ Add-Type -TypeDefinition @" public enum Syslog_Severity { Emergency, Alert, Critical, Error, Warning, Notice, Informational, Debug } "@ while($true) ` { if($Udp.Available) ` { $Buffer = $Udp.Receive([ref]$Sender) $MessageString = [Text.Encoding]::UTF8.GetString($Buffer) $Priority = [Int]($MessageString -Replace "<|>.*") [int]$FacilityInt = [Math]::truncate([decimal]($Priority / 8)) $Facility = [Enum]::ToObject([Syslog_Facility], $FacilityInt) [int]$SeverityInt = $Priority - ($FacilityInt * 8 ) $Severity = [Enum]::ToObject([Syslog_Severity], $SeverityInt) $DateTime = Get-Date -Format yyyyMMddTHHmmss $MessageString = "$DateTime $MessageString $Facility $Severity" # $MessageString = $MessageString -Replace "<.*>","" #Write-Host $MessageString $MessageString >> syslog.log } [Threading.Thread]::Sleep(500) }
テスト実行するときは、powershell で .\syslog.ps1
これをタスクスケジューラで動かしておく。
スタートアップ時にして、セキュリティオプションで「ユーザーがログオンしているかどうかに関わらず実行する」を選択しておくにすると起動後に正常に動かなかった。正攻法ではないが、1時間毎に実行するという設定で動かすことにした。
プログラムの開始のところは
- プログラム/スクリプト
C:\Windows\System32\cmd.exe
- 引数の追加
/c powershell .\syslog.ps1
- 開始(オプション)
C:\Users\Administrator\Desktop\syslog
とした
文字列を分析して異常があるかどうか確認しようとした。PowerShellをコーディングするのが難しかったので、以下のように外部プログラムを呼ぶことにした。ルーターからのデータはスペースを含むので文字列を""
で囲って1つの引数として外部プログラムに渡している。
$program = "check.exe" $Argument = "`"" + $MessageString + "`"" Start-Process -FilePath $program -ArgumentList $Argument -NoNewWindow -Wait