物理の駅 Physics station by 現役研究者

テクノロジーは共有されてこそ栄える

Yahama RTX1200 ルーター からの syslogをWindows + PowerShellで受ける

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ホスト)を動かしているサイトがあったのでこれで動く。

level69.net

ただ、日付はほしいので上記コードに追加した。以下を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