2014年03月30日

PowerShellでSYLOGを受信する

 ネットワーク機器やサーバーの動作確認をしたいときなど、WindowsでSYSLOGサーバーを起動させたくなることがあります。Vectorなどでダウンロードしてくるという方法もありますが、PowerShellを使えばWindowsの標準機能だけで動作させることができます。

 SYLOGはUDPを使ってアスキー文字列を送信しているだけなので、他のプロトコルと比べて非常に簡単にサーバーを作ることができます。
$udp = New-Object Net.Sockets.UdpClient -ArgumentList 514
$sender = $null

while($true) `
{
  if($udp.Available) `
  {
    $buffer = $udp.Receive([ref]$sender)
    $sender.ToString()+[Text.Encoding]::UTF8.GetString($buffer)
  }
  [Threading.Thread]::Sleep(500)
}

 これを実行するとSYSLOGを受信するたびに、受信したデータと送信元情報を表示します。
192.168.0.1:54677<141>[00:00:00:00:00:00] ABCDEFGHIJKLMN ntpclient: SUCCESS: set time : Sun Mar 30 17:27:37 2014
 途中の<141>はSYSLOGのプロトコルに規定されている部分で、FacilityやSeverityを表しています。141を8で割った余りは5ですが、これはSeverity(深刻度)を表しています。このログは5なので「通知」を意味します。141を8で割った商は17ですが、これはFacilityを表していてます。Facilityはログの種類を表していて、Facilityの17はlocal1です。ちゃんとしたSYSLOGサーバーならFacilityの値によって出力先のログファイルを分けることができます。

 <141>より前の部分は送信元のIPアドレスとポート番号です。送信されてきたUDPデータグラムのIPヘッダー部分に書かれていた情報をここで表示しています。

 <141>より後の部分は実際のSYSLOGのメッセージです。

 FacilityとSeverityの値をそれぞれ以下の表に示します。

Facility
コードFacility
0カーネル
1ユーザー・レベル
2電子メール
3システム・デーモン
4セキュリティー・認証
5syslogd内部生成
6ラインプリンター
7ネット・ニューズ
8UUCP
9クロック・デーモン
10セキュリティー・認証
11FTP(ファイル転送)
12NTP(時刻合わせ)
13監査
14警戒
15クロックデーモン
16local0
17local1
18local2
19local3
20local4
21local5
22local6
23local7

Severity
コードSeverity
0Emergency
1Alert
2Critical
3Error
4Warning
5Notice
6Informational
7Debug


 ここからはスクリプトを解説していきます。

 まず、最初の行は.NET Frameworkのクラス呼び出しであり、System.Net.Sockets.UdpClientクラスのオブジェクト(実体)を生成しています。このとき、-ArgumentList 514の指定は解放するポート番号を意味しています。
$udp = New-Object Net.Sockets.UdpClient -ArgumentList 514

 2行目は送信元を格納するための変数を用意しています。
$sender = $null

 while($true)は無限ループを意味するので、Ctrl+Cなどユーザー操作で終了させられるまで{ }の中身をくり返します。
while($true) { (中略) }

 $udp.Availableは、受信したUDPデータグラムがあるときに$trueになります。UDPデータグラムを読むだけなら後述する$udp.Receiveを実行すれば良いのですが、受信していない状態で$udp.Receiveを実行すると受信待ちになり、受信するまではCtrl+Cを入力しても終了できなくなります。そこで、受信したかどうか判定してから読み込むようにします。
if($udp.Available) { (中略) }

 $udp.Receiveの行では、受信したUDPデータグラムを読み込みます。読み込んだ内容は返却値として得られるので$bufferに格納され、送信元のIPアドレスやポート番号は引数の$senderに格納されます。$udp.Receive()で行われる処理は$senderの値変更を含んでいるので、$senderには[ref]をつけなければなりません。
$buffer = $udp.Receive([ref]$sender)

 次の行は、送信元IP、ポート番号、および受信したUDPデータグラムを表す文字列です。$senderは送信元のIPとポート番号を表すデータなので、$sender.ToString()で、ポート番号を表す文字列が得られます。その後ろは、受信したUDPデータグラムである$bufferをUTF8の文字列とみなして、その文字列を出力することを意味します。+で、その前後の文字列を連結します。
$sender.ToString()+[Text.Encoding]::UTF8.GetString($buffer)

 この行は、500ミリ秒待つことを意味します。これを入れないと、受信していない間は空っぽの無限ループを実行することになってしまうので少し待ってから受信するようにしています。
[Threading.Thread]::Sleep(500)
web拍手 by FC2
posted by 北条利彦 at 19:54 | Comment(0) | TrackBack(0) | PowerShell | このブログの読者になる | 更新情報をチェックする
この記事へのコメント
コメントを書く
お名前:

メールアドレス:

ホームページアドレス:

コメント:

認証コード: [必須入力]


※画像の中の文字を半角で入力してください。

この記事へのトラックバック
×

この広告は90日以上新しい記事の投稿がないブログに表示されております。