LANDISK HACKING DIARY
Since2005/8/17
TOPへ戻る

   INDEX
 
1. syslog-ng のインストールと設定
2. 筆者のsyslog-ng.conf
3. options の変更
4. 転送元サーバー(Fedora Core3)にsyslog-ngを導入する
5. 参考文献




 
   syslog-ng のインストールと設定

 

 


apt-get してインストールする。と、ざっくりいきたいところだけど、シミュレーションすると syslog-ng をインストールする代わりに、sysklogd と klogd をアンインストールしてしまうみたいだ。/etc/syslog.conf を全くいじっていない場合は、置き換えられても問題ないようにはできている。だが、カスタマイズしている場合は、取得できないログが発生する可能性があるので、基幹部分のサーバーなどにインストールする場合は、予めテスト環境を作成し、検証しておいた方が良いだろう。なお、新規にdeb パッケージをインストールしようとしたが、sysklogd とconflict し、インストールすることはできなかった。

landisk:~# apt-get install syslog-ng

■/etc/syslog-ng/syslog-ng.conf の編集

/etc/syslog-ng/syslog-ng.conf を開いてみてみると、なにやら物凄く難解な構文がずらずらと…めまいがしてきそうです。syslog-ng には以下の5つの設定を行います。

 source ログの受信に関する設定
 filter フィルタ処理に関する設定
 destination ログの出力に関する設定
 log source、destination、filterの対応付け
 options 各種オプション

⇒syslog-ng マニュアル

■source(ログ受信に関する設定) の設定

デフォルトでは以下のようになっています。通常はデフォルトのままで問題ありません(と、私が言い切るのもどうかと思いますが…)。「udp();」はログを他のマシンから受信しない場合は先頭に#をつけてコメントしてください。

source src { unix-stream("/dev/log"); internal(); file("/proc/kmsg" log_prefix("kernel: "));udp(); };

見やすく改行すると…

source src {
      unix-stream("/dev/log");
      internal();
      file("/proc/kmsg" log_prefix("kernel: "));
      udp();
};

とりあえず、これがなにを意味するのかわからないことには不安でたまりません。sourceの記述形式は以下の通りです。identifier は、syslog-ng 内で一意となる名前を指定する。debian の場合は、/proc/kmsg よりカーネルログを取得し、log_prefixによって、メッセージの先頭に"kernel: "を追加して、従来のsyslogdと同じ出力形式にする。

source <identifier> { source-driver(params); source-driver(params); …… };

以下はsource-driverの意味です。

 internal syslog-ng内部で生成されるメッセージを出力
 unix-stream SOCK_STREAMモードで指定したUNIXソケットを開き、ログメッセージを受信
(LinuxベースのOSの場合)。BSD系UNIXは「unix-dgram」。
 file 指定されたファイルを開き、メッセージを読む
 pipe、fifo 指定した名前パイプをオープンして、ログメッセージを読む


■filter (フィルタ処理)の設定

デフォルトでは以下のようになっている。これも…ほぼデフォルトで問題ないでしょう(笑)。

# Here's come the filter options. With this rules, we can set which
# message go where.

filter f_authpriv { facility(auth, authpriv); };
filter f_syslog { not facility(auth, authpriv); };
filter f_cron { facility(cron); };
filter f_daemon { facility(daemon); };
filter f_kern { facility(kern); };
filter f_lpr { facility(lpr); };
filter f_mail { facility(mail); };
filter f_user { facility(user); };
filter f_uucp { facility(uucp); };

filter f_news { facility(news); };

filter f_debug { not facility(auth, authpriv, news, mail); };
filter f_messages { level(info .. warn)
and not facility(auth, authpriv, cron, daemon, mail, news); };
filter f_emergency { level(emerg); };

filter f_info { level(info); };
filter f_notice { level(notice); };
filter f_warn { level(warn); };
filter f_crit { level(crit); };
filter f_err { level(err); };

filter f_cnews { level(notice, err, crit) and facility(news); };
filter f_cother { level(debug, info, notice, warn) or facility(daemon, mail); };

filter ppp { facility(local2); };

とりあえず、どのような意味があるのかぐらいは知っておきたい。filterでは、出力するログメッセージのフィルタが行われ、上記で記述されている条件に合致したログメッセージに対して、destinationでログの出力先を決定させる。filterの記述形式 は以下のとおり。

filter <identifier> { expression; };

expression の値は以下のとおり。

 facility 指定したfacilityに合致するログメッセージが対象となる。
facility(faciliy[,facility])の形式。
 level 指定したpriorityに合致するログメッセージが対象となる。
priority()level(pri[,pri1..pri2[,pri3]])の形式。
 filter 別のフィルターを呼び出す。
 host 指定したホスト名(正規表現可)に合致するログメッセージが対象となる。
host(ホスト名)の形式。

例1) filter f_authpriv { facility(auth, authpriv); };
    Facility が auth と authpriv を対象とする場合。

例2) filter f_syslog { not facility(auth, authpriv); };
    Facility が auth と authpriv を除いたもの全て。

例3) filter f_messages { level(info .. warn) and not facility(auth, authpriv, cron, daemon, mail, news); };
    priority が info から warn までを対象とする場合で、auth,authpriv,cron,daemon,mai,news のFacility は含まない。


■destinations (ログの出力に関する設定)の設定

上記で設定したfilter 条件のログ出力先を指定します。以上のfilter と destinations をまとめてみました。ここでは、debian 風のログ出力形式をある程度、継投しつつ、尚且つ、Red Hat 風のログ出力形式に変えてみる(単にログは1箇所に集中させて記録したいという筆者の好み)。こんな感じかな〜。debian のログ出力形式って無駄に多いなぁ〜。

filter f_authpriv { facility(auth, authpriv); };
filter f_syslog { not facility(auth, authpriv); };
filter f_cron { facility(cron); };
filter f_kern { facility(kern); };
filter f_mail { facility(mail); };
filter f_user { facility(user); };
filter f_uucp { facility(uucp); };
filter f_news { facility(news); };

filter f_messages { level(info .. emerg)
and not facility(authpriv, cron, mail, user); };

filter f_emergency { level(emerg); };
filter f_info { level(info); };
filter f_notice { level(notice); };
filter f_warn { level(warn); };
filter f_crit { level(crit); };
filter f_err { level(err); };

destination authlog { file("/var/log/auth.log" owner("root") group("adm") perm(0640)); };
destination syslog { file("/var/log/syslog" owner("root") group("adm") perm(0640)); };
destination cron { file("/var/log/cron.log" owner("root") group("adm") perm(0640)); };
destination kern { file("/var/log/kern.log" owner("root") group("adm") perm(0640)); };
destination mail { file("/var/log/mail.log" owner("root") group("adm") perm(0640)); };
destination user { file("/var/log/user.log" owner("root") group("adm") perm(0640)); };
destination uucp { file("/var/log/uucp.log" owner("root") group("adm") perm(0640)); };

destination newscrit { file("/var/log/news/news.crit" owner("root") group("adm") perm(0640)); };
destination newserr { file("/var/log/news/news.err" owner("root") group("adm") perm(0640)); };
destination newsnotice { file("/var/log/news/news.notice" owner("root") group("adm") perm(0640)); };



■log の設定

最後に、ログの設定を行います。source、destination、filterで定義した各ルール名(<identifier>)の対応付けを行うだけなので簡単だと思います。

log { source(src); filter(f_authpriv); destination(authlog); };
log { source(src); filter(f_syslog); destination(syslog); };
log { source(src); filter(f_cron); destination(cron); };
# log { source(src); filter(f_daemon); destination(daemon); };
log { source(src); filter(f_kern); destination(kern); };
# log { source(src); filter(f_lpr); destination(lpr); };
log { source(src); filter(f_mail); destination(mail); };
log { source(src); filter(f_user); destination(user); };
log { source(src); filter(f_uucp); destination(uucp); };
# log { source(src); filter(f_mail); filter(f_info); destination(mailinfo); };
# log { source(src); filter(f_mail); filter(f_warn); destination(mailwarn); };
# log { source(src); filter(f_mail); filter(f_err); destination(mailerr); };
log { source(src); filter(f_news); filter(f_crit); destination(newscrit); };
log { source(src); filter(f_news); filter(f_err); destination(newserr); };
log { source(src); filter(f_news); filter(f_notice); destination(newsnotice); };
# log { source(src); filter(f_debug); destination(debug); };
log { source(src); filter(f_messages); destination(messages); };
log { source(src); filter(f_emergency); destination(console); };

#log { source(src); filter(f_cnews); destination(console_all); };
#log { source(src); filter(f_cother); destination(console_all); };

# log { source(src); filter(f_cnews); destination(xconsole); };
# log { source(src); filter(f_cother); destination(xconsole); };

# log { source(src); filter(ppp); destination(ppp); };
 
完成〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜!!

繰り返しになるけど、以上で設定した項目を綺麗に見やすく、且つ、自分なりにまとめてみた。う〜ん、最初は暗号のようだったsyslog-ng.conf も解析してしまえば簡単ですね。なお、筆者のルータは、ファシリティコードが user に固定されているので、オリジナルなフィルタを作成しても user ファシリティコードからしかログは出力されませんでした(local1〜7 とかをルータに割り当てることはできませんでした)。dhcp,samba,cron のログは必要ないので/var/log/messages には記録せず、別ファイルに保存している。また、必要のない特定の文字列に関してはファイルに出力しないようにしてある(/dev/null)。ssh のログイン記録(Accepted publickey〜・・・)は、確認のためによく見たりするので、/var/log/messages に吐くようにしてある(デフォルト)。

# -----------------------------------------------------------------OPTIONS

options {
	long_hostnames(off);
	sync(0);
	stats(86400);
	log_fifo_size (1000);
	keep_hostname (yes);	
	time_reopen (10);
	use_dns (yes);
	use_fqdn (no);
	dir_perm(0755);
	perm(0644);
	owner(root);
	group(adm);
	create_dirs (no);
};


# -----------------------------------------------------------------SOURCE

source src {
	unix-stream("/dev/log");
	unix-stream("/var/bind/dev/log");  # chrootしているデーモンからのログを収集する
	internal();
	file("/proc/kmsg" log_prefix("kernel: "));
	udp(ip("0.0.0.0") port(514));
};

# -----------------------------------------------------------------DESTINATION

destination authlog     { file("/var/log/auth.log"); };
destination syslog      { file("/var/log/syslog"); };
destination cron        { file("/var/log/cron.log"); };
destination kern        { file("/var/log/kern.log"); };
destination mail        { file("/var/log/mail.log"); };
destination uucp        { file("/var/log/uucp.log"); };
destination user        { file("/var/log/router.log"); };

destination newscrit    { file("/var/log/news/news.crit"); };
destination newserr     { file("/var/log/news/news.err"); };
destination newsnotice  { file("/var/log/news/news.notice"); };

destination console     { usertty("root"); };
destination console_all { file("/dev/tty8"); };
destination xconsole    { pipe("/dev/xconsole"); };

destination messages    { file("/var/log/messages"); };
destination d_dhcpd     { file("/var/log/dhcpd.log"); };
destination d_crond     { file("/var/log/cron.log"); };
destination d_samba     { file("/var/log/samba/log.smbd"); };
destination d_trash     { file("/dev/null"); };


# -----------------------------------------------------------------FILTER

filter f_authpriv { facility(auth, authpriv); };
filter f_syslog   { not facility(auth, authpriv, user, cron, kern, mail); };
filter f_cron     { facility(cron); };
filter f_kern     { facility(kern); };
filter f_mail     { facility(mail); };
filter f_uucp     { facility(uucp); };
filter f_news     { facility(news); };
filter f_user     { facility(user); };

filter f_messages { level(info .. emerg)
		and not	facility(authpriv, cron, mail, user)
		and not filter("f_origin"); };

filter f_info      { level(info); };
filter f_notice    { level(notice); };
filter f_warn      { level(warn); };
filter f_crit      { level(crit); };
filter f_err       { level(err); };
filter f_emergency { level(emerg); };

##### ORIGINAL FILTER #####
filter f_origin { filter(f_dhcpd) or filter(f_crond) or filter(f_samba); };
filter f_dhcpd  { level(info..emerg) and program("dhcpd") or match("dhclient.*"); };
filter f_samba  { level(info..emerg) and program("smbd"); };
filter f_crond  { match("CRON") or match("crond\(.*\)"); }; 
filter f_trash  { match("last.*message.*repeated.*"); };


# -----------------------------------------------------------------LOG

log { source(src); filter(f_authpriv); destination(authlog); };
log { source(src); filter(f_syslog); destination(syslog); };
log { source(src); filter(f_cron); filter(f_crond); destination(cron); };
log { source(src); filter(f_kern); destination(kern); };
log { source(src); filter(f_mail); destination(mail); };
log { source(src); filter(f_uucp); destination(uucp); };
log { source(src); filter(f_user); destination(user); };
log { source(src); filter(f_news); filter(f_crit); destination(newscrit); };
log { source(src); filter(f_news); filter(f_err); destination(newserr); };
log { source(src); filter(f_news); filter(f_notice); destination(newsnotice); };
log { source(src); filter(f_messages); destination(messages); };
log { source(src); filter(f_emergency); destination(console); };

log { source(src); filter(f_samba); destination(d_samba); };
log { source(src); filter(f_dhcpd); destination(d_dhcpd); };
log { source(src); filter(f_trash); destination(d_trash); };



■syslog-ng の起動

起動させる前に、構文チェックを行う。なにも出力されなければOK!

landisk:~# syslog-ng -s
landisk:~# ps aux | grep syslog-ng
root 18742 0.0 1.3 2100 872 ? Ss 03:56 0:00 /sbin/syslog-ng

■ログのローテーション

ログのローテーションは、syslog-ng をインストールすれば自動で行われている。/etc/logrotate.d/syslog-ng というファイルがあるので設定を変更したい場合は編集しておこう。


■ユーザ権限で起動させる

セキュリティを高めるために、syslog-ng をユーザ権限で起動させます。

landisk:~# adduser --shell /bin/false --home /dev/null --disabled-login --disabled-password syslog

起動スクリプトを編集します。但し、この方法でやる場合は、/var/log 以下にワンクッション、ディレクトリを作成しないと書き込み権限がないために、ログに出力されないでしょう。

landisk:~# vi /etc/init.d/syslog-ng
SYSLOGD="-u syslog -g syslog"
・・・
start-stop-daemon --start --quiet --exec /sbin/syslog-ng -- $SYSLOGD
・・・
start-stop-daemon --start --quiet --exec /sbin/syslog-ng -- $SYSLOGD

landisk:~# ps aux | grep syslog-ng
syslog 19559 0.5 1.1 1768 720 ? Ss 06:51 0:00 /sbin/syslog-ng -u syslog -g syslog



 
     options の変更
   
起動時のオプションをカスタマイズしてみる。デフォルトでは以下のようになっている。long_hostnames というのは、ログに記録されるホスト名を短くするものである。通常ならば、source <identify> の identity の部分+ホスト名と記録されるようになっている(例:local@server1)。それを単純にホスト名だけを記述するようにしたのが、long_hostnames(off) である。sync は、ログをファイルに書き込む前にバッファするメッセージ数の指定する。sync(0) にしておくことで、ログが発生したらバッファせずに即座にファイルに書き込むようになる。指定するのは行数でデフォルトは2048行。

options { long_hostnames(off); sync(0); };

syslog-ng は10分間隔でバッファ出力に失敗したログの数を出力する。sync(0)でログをバッファに保存しない場合は、stats(0)をセットする。

options { long_hostnames(off); sync(0); stats(0); };


■Source の変更

ログの受信を特定のIPアドレスを持つNICからのみに制限したい場合は、udp()内でip()を指定する。これは、ログを受信するLAN内に存在するIPアドレスを制限するというものではなく、NIC を2枚挿しなどにして、それぞれのNICのIPアドレスが異なる場合などに、どちらか一方のNIC のログだけを受信したいという場合に指定する(たぶん)。

udp(ip("192.168.0.10") port(514));



 
     転送元サーバー(Fedora Core3)にsyslog-ng を導入する
   
Fedora Core 3に syslog-ng を導入してみます。以下のサイトに、libol と syslog-ng のRPMがあるようなので活用します。各OSのバージョンに対応したものが置いてあるので自分の環境にあったものをダウンロードしてきてください。なお、ソースの入手先ははこちらから。debian になれると、ソースからインストールするのは面倒になりますね…。いかんいかん。なお、ソースパッケージ内に、syslog2ng という実行ファイルが入っており、/etc/syslog.conf を /etc/syslog-ng.conf に変換してくれます。

⇒syslog-ng
⇒libol

# rpm -ivh libol-0.3.16-1.fc3.i386.rpm
# rpm -ivh syslog-ng-1.6.8-1.fc3.i386.rpm

楽をしてソースパッケージをダウンロードしてきて、syslog2ng で/etc/syslog.conf を /etc/syslog-ng.conf に変換してしまいます。すでに、syslog-ng サーバが存在する場合、その転送設定まで自動で作成してくれるので大変便利です。変換したら、見やすくなるように編集しておく(デフォルトでもかなり見やすいですが)。

# ./syslog2ng /etc/syslog.conf > /root/syslog-ng.conf

編集したのは以下のようになります。自分で一から作成した syslog-ng.conf より賢く見えます。基本はログサーバの設定と変わりありませんが、変更点は2点。ログーサーバではないので「udp(ip(0.0.0.0) port(514));」はコメントアウトしておく。もう1点は最下行のログ転送サーバの指定です。ログを172.16.50.30 へ転送するよ、という意味になっている。なお、以下の例では、ログサーバーにもログを転送し、ローカルでもログを保存しておくようにしてあります。

# ------------------------------------------------------------------------------ OPTIONS
options {
	sync (0);
	stats(86400);
	time_reopen (10);
	log_fifo_size (1000);
	long_hostnames (off);
	use_dns (yes);
	use_fqdn (no);
	create_dirs (no);
	keep_hostname (yes);
	dir_perm(0755);
	perm(0644);
};

# ---------------------------------------------------------------------------- SOURCE
source local {
         pipe ("/proc/kmsg" log_prefix("kernel: ")
	unix-stream("/dev/log");
	#udp(ip(0.0.0.0) port(514));
	internal();
};

# *.info;mail.none;authpriv.none;cron.none ----------------------------------- /var/log/messages

filter f_1 { not facility(cron); };
filter f_2 { level(info..emerg); };
filter f_3 { not facility(mail); };
filter f_4 { not facility(authpriv); };
destination d_1 { file("/var/log/messages" create_dirs(yes)); };
log { source(local); filter(f_1); filter(f_2); filter(f_3); filter(f_4); destination(d_1); };

# authpriv.* ----------------------------------------------------------------- /var/log/secure

filter f_5 { facility(authpriv) and level(debug..emerg); };
destination d_2 { file("/var/log/secure" create_dirs(yes)); };
log { source(local); filter(f_5); destination(d_2); };

# mail.* --------------------------------------------------------------------- -/var/log/maillog

filter f_6 { facility(mail) and level(debug..emerg); };
destination d_3 { usertty("-/var/log/maillog"); };
log { source(local); filter(f_6); destination(d_3); };

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

filter f_7 { facility(cron) and level(debug..emerg); };
destination d_4 { file("/var/log/cron" create_dirs(yes)); };
log { source(local); filter(f_7); destination(d_4); };

# *.emerg -------------------------------------------------------------------- *

filter f_8 { level(emerg); };
destination d_5 { usertty("*"); };
log { source(local); filter(f_8); destination(d_5); };

# uucp,news.crit ------------------------------------------------------------- /var/log/spooler

filter f_9 { facility(uucp,news) and level(crit..emerg); };
destination d_6 { file("/var/log/spooler" create_dirs(yes)); };
log { source(local); filter(f_9); destination(d_6); };

# local7.* ------------------------------------------------------------------- /var/log/boot.log

filter f_10 { facility(local7) and level(debug..emerg); };
destination d_7 { file("/var/log/boot.log" create_dirs(yes)); };
log { source(local); filter(f_10); destination(d_7); };

# *.* ------------------------------------------------------------------------ @172.16.50.30

filter f_11 { level(debug..emerg); };
destination d_8 { udp("172.16.50.30" port(514)); };
log { source(local); filter(f_11); destination(d_8); };



編集を終えたら、sysklogd を停止させ、syslog-ng を起動させるだけだ。念のため、syslog-ng -s で構文チェックを行っておく。

# syslog-ng -s
# /etc/init.d/syslog stop
# /etc/init.d/syslog-ng start

起動時に以下のようなメッセージがでた場合は、/etc/default/syslog-ng.conf を編集して、CONSOLE_LOG_LEVEL=0 と KERNEL_RINGBUF_SIZE=16392 をアンコメントしておこう。

# /etc/init.d/syslog-ng restart
CONSOLE_LOG_LEVEL is of unaccepted value.
KERNEL_RINGBUF_SIZE is of unaccepted value.

Stopping system logging: syslog-ng.
Starting system logging: syslog-ng.

# vi /etc/default/syslog-ng.conf

CONSOLE_LOG_LEVEL=0 //先頭の # をコメントアウトする
KERNEL_RINGBUF_SIZE=16392 //先頭の # コメントアウトする

# /etc/init.d/syslog-ng restart


 
     参考文献
   
@it 「止められないUNIXサーバのセキュリティ対策」

第7回 UNIXサーバの運用管理で欠かせないログ管理
第8回 syslogによるログの一元管理
第9回 安全性の高いログ・サーバへの乗り換えのススメ(1)
第10回 安全性の高いログ・サーバへの乗り換えのススメ(2)





TOPへ戻る
 
Copyright © KORO All Rights Reserved.