2011/09/16 CentOS5.5





rsyslogで条件式を設定する

ここではrsyslogの実践的なconf記述を記します。
インストールについては別項「rsyslogをインストールする」を参照してください。

rsyslog.confの例
rsyslog.confの記述と式のルール


rsyslog.confの例(デフォルトのコメントアウト部は省いてあります)
#$ModLoad immark   # provides --MARK-- message capability
$ModLoad imuxsock # provides support for local system logging (e.g. via logger command)
$ModLoad imklog   # kernel logging (formerly provided by rklogd)

$template customformat,"%timegenerated% %HOSTNAME% %syslogtag%%msg%\n"
$template logFileName,"/var/log/syslog/%fromhost%/messages_%fromhost%_%$year%%$month%%$day%.log"
$template mailFileName,"/var/log/syslog/%fromhost%/mail_%fromhost%_%$year%%$month%%$day%.log"

# Log anything (except mail) of level info or higher.
# Don't log private authentication messages!
#*.info;mail.none;authpriv.none;cron.none                -/var/log/messages
*.info;mail.none;authpriv.none;cron.none                -?logFileName;customformat
*.info;mail.none;authpriv.none;cron.none                @remoteserver

# The authpriv file has restricted access.
authpriv.*                                              /var/log/secure

# Log all the mail messages in one place.
#mail.*                                                  -/var/log/maillog
mail.*                                                  -?mailFileName;customformat

$ModLoad ommail

$ActionMailSMTPServer mailserver.address
$ActionMailFrom admin@example.local
$template mailsubject,"Syslog Warning"
$template mailbody,"%fromhost%\r\n%msg%"
$ActionMailSubject mailsubject
$ActionExecOnlyOnceEveryInterval  -1

$ActionMailTo admin-ml@example.local
if $fromhost-ip == '192.168.1.100' and $msg contains 'System Warning' then :ommail:;mailbody

$ActionMailTo admin-ml@example.local
if $fromhost-ip != '127.0.0.1' and $msg contains 'authenticated failure' and $syslogfacility-text == 'daemon' then :ommail:;mailbody

$ActionMailTo administrator@example.local
if $fromhost-ip =='192.168.1.254' and $syslogfacility-text == 'syslog' and $syslogseverity-text == 'crit' then :ommail:;mailbody

# Log cron stuff
cron.*                                                  -/var/log/cron

# Everybody gets emergency messages
*.emerg                                                 *

# Save news errors of level crit and higher in a special file.
uucp,news.crit                                          -/var/log/spooler

# Save boot messages also to boot.log
local7.*                                                /var/log/boot.log

# UDP Syslog Server:
$ModLoad imudp.so  # provides UDP syslog reception
$UDPServerRun 514 # start a UDP syslog server at standard port 514


rsyslog.confの記述と条件式のルール
条件判断で使用するプロパティ値や変数などは、本家に解説があります。
変数の解説

また条件判断に使用するパラメータもありますが、数は多くありません。
条件判断の項目

contains
ログに指定文字が「含まれるか」。大文字小文字を区別しない場合はcontains_i
isequal
ログが指定文字と「等しいか」
startswith
ログが指定文字で「始まっているか」。大文字小文字を区別しない場合はstartswith_i
regex
ログを正規表現で評価します
ereregex
ログを拡張正規表現でします
isempty
プロパティが空かを評価します。



rsyslog.confの考え方は、上から順に条件判断をしていきます。
条件に一致すれば、アクションを実行します。そして引き続き次の条件判断へ移ります。

例えば
・ローカルのログはmessagesへ出力
・リモートから受信したログはremote_messageへ保存
・リモートから受信したログを含めて、全てのログを別のリモートサーバへ再転送
・192.168.1.100から受信したログだけはmessage_192.168.1.100へ保存

この条件を以下のように記述したとします。

*.info;mail.none;authpriv.none;cron.none                -/var/log/messages
*.*                @remoteserver
:fromhost-ip, isequal, "192.168.1.100" /var/log/message_192.168.1.100
:fromhost-ip, !isequal, "127.0.0.1" /var/log/remote_message

これでは望むようには動作しません。
条件が一致しても、次の行が引き続き評価されるからです。

ローカルログは正しく出力しますが、リモートから受け取ったログも同じようにmessageへ出力してしまいます。
リモートサーバへの転送は全てのリモートログとローカルログについて行われます。これは希望通りです。
次にリモートサーバ192.168.1.100から受信したログなら、message_192.168.1.100へ出力します。
最後にローカル以外(リモートログ)なら、remote_messageへ出力します。ここに192.168.1.100も含まれてしまいます。
つまり全ての条件判断の行を通過していきます。

結果的にmessagesにはローカルとリモートのログが混ざって出力されます。
192.168.1.100から送られてきたログも、messages、message_192.168.1.100、remote_messageへ出力されます。
これではログが無駄に肥大化してしまいます。

上記条件を満たすには、以下のようになります。

*.*               @remoteserver
:fromhost-ip, isequal, "192.168.1.100" /var/log/message_192.168.1.100
& ~
:fromhost-ip, !isequal, "127.0.0.1" /var/log/remote_message
& ~
*.info;mail.none;authpriv.none;cron.none                -/var/log/messages


この場合は意図した通りに動作します。
&マークは直前の式と同じ条件(必ず一致します)、チルダは「破棄」を意味します。

全てのログをリモートサーバへ転送。
送信元IPが192.168.1.100の場合だけmessage_192.168.1.100へ出力します。
「& ~」は直前の条件、この場合は「:fromhost-ip, isequal, "192.168.1.100" ~」を表し、送信元192.168.1.100に一致したログを破棄(~)します。
次に送信元が127.0.0.1以外、つまりリモートサーバからの送信ログはremote_messageへ出力します。
192.168.1.100のログはすでに破棄されているので、含まれません。
「& ~」は直前の条件、この場合は「:fromhost-ip, !isequal, "127.0.0.1" ~」を表し、送信元がリモートサーバのログは破棄します。
最後にmessagesへの出力。ただしリモートログは全て破棄されているので、出力されるのはローカルログのみです。

当初の条件を厳密にクリアすることが出来ました。
同じことをするのに、他にもいろんな記述が考えられます。

loggerコマンドでファシリティやプライオリティを指定してテストし、出力を確認します。

#logger -p user.info "test"

なお、記述ミスや文法ミスに気を付けましょう。
confの文法チェックをするには以下のようにします。
#rsyslogd -N 1

ちなみにチェック時に「WARNING: rsyslogd is running in compatibility mode」と出力されるのは気にしなくていいです。
これがチェックが互換性モード(ver3)で実施されているというだけなので、サービス起動のパラメータファイル(sysconfig/rsyslog)が正しく書き込まれていれば、実害はありません。
どうしても気になるのなら、コマンドの末尾に「-c5」を加えます。
#rsyslogd -N 1 -c5








prev.gif