前回に引き続き今回も、安全性がより考慮されたsyslogサーバのsyslog-ng(syslog-next generation)への切り替えについて述べる。
現行のsyslogdから切替える場合は、syslogdの設定内容をそのまま引き継ぐようにする。もちろん、一からsyslog-ngの設定を書き上げてもよいが、後々の運用管理において混乱が生じないようにするためには、現行syslogdの設定内容を引き継いだ方がよい。syslogdからsyslog-ngへの移行例(設定例)を以下に示す。
移行前:syslogdの設定(syslog.conf)
*.err;kern.*;auth.notice;authpriv.none;mail.crit /dev/console *.info;auth,authpriv,cron,ftp,kern,lpr,mail.none /var/log/messages kern.debug /var/log/messages auth,authpriv.info /var/log/authlog cron.info /var/cron/log ftp.info /var/log/xferlog lpr.info /var/log/lpd-errs mail.info /var/log/maillog *.emerg * *.notice root
上記syslog.confをsyslog-ngに移行した場合、以下のとおりとなる。
移行後:syslog-ngの設定(syslog-ng.conf)
source s_local { unix-dgram("/var/run/log"); internal(); }; destination d_console { pipe("/dev/console"); }; destination d_messages { file("/var/log/messages"); }; destination d_authlog { file("/var/log/authlog"); }; destination d_cron { file("/var/cron/log"); }; destination d_ftp { file("/var/log/xferlog"); }; destination d_lpr { file("/var/log/lpd-errs"); }; destination d_maillog { file("/var/log/maillog"); }; destination d_alluser { usertty("*"); }; destination d_root { usertty("root"); }; filter f_console { level(err..emerg) or facility(kern) and level(debug) or facility(auth) and level(notice..emerg) or facility(mail) and level(crit..emerg) and not facility(authpriv); }; filter f_messages { level(info..emerg) and not facility(auth,authpriv,cron,ftp,kern,lpr,mail) or facility(kern) and level(debug); }; filter f_authlog { facility(auth,authpriv) and level(info); }; filter f_cron { facility(cron) and level(info); }; filter f_ftp { facility(ftp) and level(info); }; filter f_lpr { facility(lpr) and level(info); }; filter f_maillog { facility(mail) and level(info); }; filter f_alluser { level(emerg); }; filter f_root { level(notice); }; log { source(s_local); filter(f_console); destination(d_console); }; log { source(s_local); filter(f_messages); destination(d_messages); }; log { source(s_local); filter(f_authlog); destination(d_authlog); }; log { source(s_local); filter(f_cron); destination(d_cron); }; log { source(s_local); filter(f_ftp); destination(d_ftp); }; log { source(s_local); filter(f_lpr); destination(d_lpr); }; log { source(s_local); filter(f_mail); destination(d_maillog); }; log { source(s_local); filter(f_alluser); destination(d_alluser); }; log { source(s_local); filter(f_root); destination(d_root); };
syslog-ngの設定が完了したら、後は現行のsyslogdを停止してからsyslog-ngを起動するだけだが、その前にsyslog-ngの起動オプションを知っておく必要がある。
syslog-ng 1.6.2には、以下のようなオプションが用意されている。
% syslog-ng -h Usage: syslog-ng [options] Accept and manage system log messages Options: -s, --syntax-only Only read and parse config file -d, --debug Turn on debugging messages -v, --verbose Be a bit more verbose -F, --foreground Don't fork into background -f '<'fname'>', --cfgfile='<'fname'>' Set config file name, default=/usr/local/etc/syslog-ng/syslog-ng.conf -V, --version Display version number (syslog-ng 1.6.2) -p '<'fname'>', --pidfile='<'fname'>' Set pid file name, default=/var/run/syslog-ng.pid -C '<'dir'>', --chroot='<'dir'>' Chroot to directory -u '<'user'>', --user='<'user'>' Switch to user -g '<'group'>', --group='<'group'>' Switch to group -y, --yydebug Turn on yacc debug messages
このうち重要となるのが、構文チェックの-s(--syntax-only)、実行ユーザー/グループを変更する-u(--user)、-g(--group)である。これらについては後述する。
syslog-ngを実際に起動する前に、syslog-ng.confの構文チェックを必ず行うこと。syslog-ngには、構文チェックを行うための便利なオプション(-s)が提供されているので、syslog-ngの設定変更時は、必ず-sオプションで事前確認するとよい。
% syslog-ng -s
例えば、syslog-ng.confの26行目の構文が間違えていた場合は、以下のように表示される。
% syslog-ng -s parse error at 26 Parse error reading configuration file, exiting. (line 26) %
syslog-ng.confが正しく設定されていれば、何も表示されない。
% syslog-ng -s %
前述の構文チェックをクリアできたら、後は現在稼働中のsyslogdを停止し、syslog-ngを起動するだけだ。以下に各OS別の切り替え手順をまとめる。
●FreeBSD 4.6-RELEASEの場合
起動スクリプトは、portsのものを利用する。
# cd /usr/ports/sysutils/syslog-ng/files # cp syslog-ng.sh.sample /usr/local/etc/rc.d/syslog-ng.sh
実行ユーザーを変更する場合は、起動スクリプトに「-u 実行ユーザー名」を追加する。以下の例では、実行ユーザー名をnobodyとしている。
変更前:
start) [ -x ${PREFIX}/sbin/syslog-ng ] && ${PREFIX}/sbin/syslog-ng && echo -n ' syslog-ng'
変更後:
start) [ -x ${PREFIX}/sbin/syslog-ng ] && ${PREFIX}/sbin/syslog-ng -u nobody && echo -n ' syslog-ng'
syslog-ngの準備完了。syslogdを停止する。
# ps -ax | grep syslogd 20258 ?? Is 0:20.21 /usr/sbin/syslogd # kill -TERM 20258
syslog-ngを即座に起動する。
# /usr/local/etc/rc.d/syslog-ng start
次回OS起動時に、syslogdではなくsyslog-ngを起動する場合は、/etc/rc.confに次の一行を追加する。
syslogd_enable="NO"
●NetBSD 1.6の場合
# cp /etc/rc.d/syslogd /etc/rc.d/syslogng # vi /etc/rc.d/syslogng
以下のとおりsyslogdをsyslogngに変更する。一部のパスはsyslog-ngにする。
# PROVIDE: syslogng name="syslogng" command="/usr/local/sbin/syslog-ng" required_files="/etc/syslog-ng/syslog-ng.conf" _sockfile="/var/run/syslog-ng.sockets" # vi /etc/rc.conf
/etc/rc.confに以下を追加する。
syslogng=YES syslogng_flags="-f /etc/syslog-ng/syslog-ng.conf"
実行ユーザーを変更する場合は、syslogng_flagsに「-u 実行ユーザー名」を追加する。以下の例では、実行ユーザー名をnobodyとしている。
syslogng_flags="-u nobody -f /etc/syslog-ng/syslog-ng.conf"
これでsyslog-ngの準備は完了。syslogdを停止する。
# /etc/rc.d/syslogd stop
syslog-ngを即座に起動する。
# /etc/rc.d/syslogng start Starting syslogng.
次回OS起動時に、syslogdを起動しないようにするため、/etc/rc.confに次の一行を追加する。
syslogd=NO
●Red Hat Linux 7.3の場合
ソースコードからインストールした場合は、syslog-ngのソースコードのcontrib以下にある起動スクリプト(init.d.RedHat-7.3)を利用する。
% cd /usr/local/src/syslog-ng-1.6.2 # cp contrib/init.d.RedHat-7.3 /etc/init.d/syslog-ng # chkconfig --add syslog-ng
起動スクリプトが有効(ランレベル2、3がon)になったことを確認する。
# chkconfig --list syslog-ng syslog-ng 0:off 1:off 2:on 3:on 4:on 5:on 6:off
実行ユーザーを変更する場合は、/etc/sysconfig/syslog-ngファイルのSYSLOGNG_OPTIONSに「-u 実行ユーザー名」を追加する。以下の例では、実行ユーザー名をnobodyとしている。
SYSLOGNG_OPTIONS="-u nobody"
syslog-ngの準備完了。syslogdを停止する。
# service syslog stop
即座にsyslog-ngを起動する。
# service syslog-ng start
次回OS起動時に、syslogdを起動しないようにする。
# chkconfig syslog off # chkconfig --level 2 syslog off # chkconfig --list syslog syslog 0:off 1:off 2:off 3:off 4:off 5:off 6:off
●Solaris 8の場合
ソースコードからインストールした場合は、syslog-ngのソースコードのcontrib以下にある起動スクリプト(init.d.solaris)を利用する。
% cd /usr/local/src/syslog-ng-1.6.2 # cp contrib/init.d.solaris /etc/init.d/syslog-ng # ln /etc/init.d/syslog-ng /etc/rc0.d/K40syslog-ng # ln /etc/init.d/syslog-ng /etc/rc1.d/K40syslog-ng # ln /etc/init.d/syslog-ng /etc/rc2.d/S74syslog-ng # ln /etc/init.d/syslog-ng /etc/rcS.d/K40syslog-ng
実行ユーザーを変更する場合は、/etc/init.d/syslog-ngファイルのOPTIONSに「- u 実行ユーザー名」を追加する。以下の例では、実行ユーザー名をnobodyとしている。
変更前:
OPTIONS="-f /etc/syslog-ng/syslog-ng.conf"
変更後:
OPTIONS="-u nobody -f /etc/syslog-ng/syslog-ng.conf"
syslog-ngの準備完了。syslogdを停止する。
# /etc/init.d/syslog stop
即座にsyslog-ngを起動する。
# /etc/init.d/syslog-ng start
次回OS起動時に、syslogdを起動しないようにする。
# mv /etc/rc2.d/S74syslog /etc/rc2.d/disable.S74syslog
syslog-ngの起動が正常に行われると、以下のようなログが出力される(通常は /var/log/messages)。
Mar 14 04:30:30 s_local@server1 syslog-ng[1395]: syslog-ng version 1.6.2 starting
もちろん、syslogdの場合と同じく、loggerコマンド*1を使った確認も忘れずに行うこと。
*1
【参考記事】
▼本連載:第7回「設定内容の確認(loggerコマンド)」の項
最近のUNIXでは、標準でnewsyslogやlogrotateなどを使用して、ログファイルのローテーションが行われている。syslogdからsyslog-ngへの切り替えを行った場合、それらログ・ローテーションに関する設定も変更する必要がある。
なぜなら、ログファイルのローテーションを実施する際に、稼働中のsyslogサーバのプロセスに対して、HUPシグナルを送る必要があるからだ。従来の場合は、syslogdが仮定されているため、それをsyslog-ng用に変更する。
●newsyslog(FreeBSD、NetBSDなどで標準)
newsyslogの設定ファイル(/etc/newsyslog.conf)にて、syslog-ngのプロセスID(PID)ファイルへのパスを明示的に指定する。以下に例を示す。
変更前:
/var/cron/log root:wheel 600 3 10 * Z /var/log/aculog uucp:dialer 640 7 * 24 Z /var/log/authlog 600 5 30 * Z …… 省略 ……
変更後:
/var/cron/log root:wheel 600 3 10 * Z /var/run/syslog-ng.pid /var/log/aculog uucp:dialer 640 7 * 24 Z …… 省略 ……
●logrotate(Red Hat Linuxなどで標準)
logrotateの設定ファイル(/etc/logrotate.conf)のpostrotate/endscriptにて、syslog-ngプロセスに対してHUPシグナルを送信する。以下に例を示す。
postrotate /sbin/kill -HUP /var/run/syslog-ng.pid endscript
通常は、optionsの値はデフォルト値で構わないが、必要に応じて変更するようにしよう。
●ホスト名の出力をsyslogdと同じにする
syslog-ngのデフォルトでは、出力されるログのホスト名にsourceの
Mar 14 04:40:30 s_local@server1 syslog-ng[1545]: STATS: dropped 0
上記では、server1というホスト名にs_localが付加されている。これを、syslogdと同じくserver1だけ出力したい場合は、long_hostnames(off)をセットする。
options { long_hostnames(off); };
●ファイルのパーミッションを変更する
syslog-ngのデフォルトでは、ログディレクトリ/ファイルの所有者やパーミッションは以下のとおりとなっている。
所有者(owner) | root |
---|---|
グループ(group) | root |
パーミッション(ディレクトリ) | 0700 (-rwx------) |
パーミッション(ファイル) | 0600 (-rw-------) |
この場合、後述のログのローテーション時にパーミッションをセットしていると不都合がおきる。なぜなら、syslog-ngの起動時に、こういった所有者やパーミッションを変更してしまうからだ。
従来(ログローテーション)と同じにしたい場合は、optionsやdestinationにて、dir_perm()、perm()、owner()、group()を指定する。以下に一例を示す。
options { dir_perm(0755); perm(0644); owner(root); group(wheel); }; destination d_authlog { file("/var/log/authlog"); perm(0600); };
上記では、それぞれ以下のとおり設定している。
また、ログファイルごとにパーミッションを変更したい場合は、destination内で指定すればよい。例では、/var/log/authlogファイルのパーミッションを0600(-rw-------)にセットしている。
上記のようにログファイルごとに変更したい場合は、destinationで指定する。そのほか、設定されていない場合は、optionsで設定した内容が適用される。
●syslog-ngの状態ログの出力間隔を変更する
syslog-ng自身が出力するログを眺めていると、以下のようなログが定期的に出力される。
Mar 14 04:40:30 s_local@server1 syslog-ng[1545]: STATS: dropped 0 Mar 14 04:50:30 s_local@server1 syslog-ng[1545]: STATS: dropped 0 Mar 14 05:00:30 s_local@server1 syslog-ng[1545]: STATS: dropped 0
これは、syslog-ngの状態を定期的にレポートするもので、バッファ出力に失敗したログの数(STATS:dropped失敗した数)が出力される。デフォルト値は、10分(600秒)間隔となっているが、間隔をもっと延ばしたい場合は、optionsのstatsパラメータを調整する。なお、後述のsync(0)でログをバッファに保存しない場合は、stats(0)をセットするとよい。
例:syslog-ngの状態監視を 24時間(86400秒)置きに実行する場合
options { stats(86400); };
●sync()パラメータでバッファに保持するメッセージ数を調整
sync()パラメータでは、ログをファイルへ出力前に、バッファに保持するメッセージ数(。行数)を指定する。デフォルトは2048。以下にsync()パラメータの設定例を示す。
options { sync(0); };
sync(0)を指定すると、ログをバッファに出力せず、そのままファイルなどに書き込むようにする。syslogdの挙動と同じにしたい場合に指定する。
●ガーベジコレクタの閾(しきい)値を調整
syslog-ngは、ガーベジコレクタ(garbage collector)の機能を持っているが、ガーベジコレクタの実行中は、ログメッセージを受け付けない。その場合、ログの受け渡しにunix-dgram()やudp()といった信頼性のないプロトコル(ソケット)を利用していると、ログを取りこぼす可能性が生じる。
syslog-ngでは、そういった取りこぼしを防ぐために、gc_idle_threshold()とgc_busy_threshold()のoptionsパラメータが提供されている。
gc_idle_threshold() | syslog-ngがアイドル状態(100ミリ秒の間にメッセージが発生しない状態)の場合、かつ割り当てたオブジェクトの数がgc_idle_threshold()で指定した数に到達した場合、ガーベジコレクタを実行する。デフォルトは100。 |
---|---|
gc_busy_threshold() | syslog-ngがビジー状態(100ミリ秒の間に入出力イベントが発生した状態)、かつ割り当てたオブジェクト数がgc_busy_threshold()で指定した数に到達した場合、ガーベジコレクタを実行する。デフォルトは3000。この値が大きいほど、ガーベジコレクタによるメッセージ受信に帯する割り込みがなくなる。 |
以下にgc_idle_threshold()とgc_busy_threshold()の設定例を示す。
options { gc_idle_threshold(50); gc_busy_threshold(5000); };
通常はデフォルト値で構わないが、ログが頻発するサーバの場合*2、gc_idle_threshold()を減らし、逆にgc_busy_threshold()の閾(しきい)値を増やす。
syslog-ngでは、「第8回 syslogによるログの一元管理」で説明したログ転送も同様に行える。
syslogdから切り替える場合は、(1)ログ・サーバ、(2)ログ転送元サーバの順に1台ずつ切り替えるとよいだろう。
(1)ログ・サーバをsyslog-ngに切り替える
まず、前述のsyslog-ngの基本的な設定までを行い、その後にログ受信に関する設定を以下のとおり行う。
●sourceの変更
udp()により、ログを受信するポートを514/udpで待機させる。
変更前:
source s_local { unix-dgram("/var/run/log"); internal(); };
変更後:
source s_local { unix-dgram("/var/run/log"); internal(); udp(); };
ネットワークインターフェイス(NIC)が複数あり、ログの受信を特定のIPアドレスを持つNICからのみに制限したい場合は、udp()内でip()を指定する。
例えば、192.168.0.10と172.16.1.100のNICがあり、ログの受信を192.168.0.10のNICからのみに制限したい場合は、以下のように設定する。
source s_local { unix-dgram("/var/run/log"); internal(); udp(ip("192.168.0.10") port(514)); };
設定を有効にする場合は、稼働中のsyslog-ngプロセスにHUPシグナルを送信するだけだ(syslogdとは違い再起動の必要がない)。
●destinationの変更
syslogdとは異なり、syslog-ngでは複数のsyslogサーバのログファイルを分けることができる。もし、ログを分けたい場合は、destinationを変更する必要がある。
例:ログ転送元サーバserver1、server2の/var/log/authlogを分ける。destination、filter、logを以下のとおり設定する。
destination d_authlog { file("/var/log/$HOST/authlog"); }; filter f_authlog_server1 { host(server1) and facility(auth,authpriv) and level(info..emerg); }; filter f_authlog_server2 { host(server2) and facility(auth,authpriv) and level(info..emerg); }; log { source(s_local); filter(f_authlog_server1); destination(d_authlog); }; log { source(s_local); filter(f_authlog_server2); destination(d_authlog); };
$HOSTは、syslog-ngが保持する変数で、ログ送信元のホスト名が保持されている。
なお、ディレクトリを自動作成しない設定(create_dirs(n))にしている場合は、あらかじめディレクトリを作成しておく必要がある。
# mkdir /var/log/server1 /var/log/server2
(2)ログ転送元をsyslog-ngに切り替える
ログ・サーバと同じく、前述のsyslog-ngの基本的な設定までを行い、その後にログ送信に関する設定を以下のように行う。
●destinationの追加
ログ転送用のdestinationを定義する。ログ・サーバが192.168.0.10の場合、以下のように設定する。
destination d_loghost { udp("192.168.0.10"); };
デフォルトでは、転送元ポート(localport)は任意のポートとなり、転送先ポート(port)は514となる。例えば、転送元ポートをsyslogdと同様に514にしたい場合は、以下のとおり設定する。
destination d_loghost { udp("192.168.0.10" localport(514)); };
●logの変更
追加したdestinationを各logに追加する。以下に例を示す。
log { source(s_local); filter(f_authlog); destination(d_authlog); destination(d_loghost); };
ログ転送の確認が完了し、ログの格納先を全てログ・サーバに切り替える場合は、以下のようにdestination(d_authlog)を取り除くだけだ。
log { source(s_local); filter(f_authlog); destination(d_loghost); };
syslog-ngでは、filter機能のprogram()、host()、match()を利用することで、ログ監査を自動化させることが可能だ。この機能は、従来のsyslogdにはなく、syslogdでそれを実現するには、swatch*3などの専用アプリケーションを別途導入する必要があった。
以下にログ監査の例を示す。
例:sshdに対するパスワードログイン失敗のログを捕捉した場合、管理者(root@example.com)にメール通知する。
sshdのパスワードログインに失敗した場合、以下のようなログメッセージが出力される。
Mar 26 07:50:00 atmarkit sshd[27576]: Failed password for kimu from 192.168.0.1 port 1030 ssh2
上記の場合、192.168.0.1からユーザーkimuによるパスワードログインに失敗した様子を示している。syslog-ngでこのログメッセージを捕捉し、管理者にメー ル送信をする場合は以下のように定義する。
destination d_mail-alert { program("/usr/local/bin/syslog-alert.sh"); }; filter f_sshd_failed_password { program("sshd") and match("Failed password "); }; log { source(s_local); filter(f_sshd-failed-password); destination(d_mail-alert); };
出力先の/usr/local/bin/syslog-alert.shは、メール通知のためのシェルスクリプトだ。ここで使用するシェルスクリプトの内容を以下に示す。
#!/bin/sh TO=root@example.com while read line do line=`echo $line | sed -e 's/^<[0-9]*>//'`; echo $line | /usr/bin/mail -s "alert mail" $TO done
上記のsedは、ログの行頭に付加される""の部分を取り除いている。つまり、オリジナルのログメッセージと同様にしている。
以上の設定が完了したら、syslog-ngに対してHUPシグナルを送信する。なお、上記シェルスクリプトの内容を変更した場合も、HUPシグナルを送信しないと反映されないので注意が必要だ。
正常に動作すると、以下のようなメールが管理者(root@example.com)に送られる。
From: nobody@example.com To: root@example.com Subject: alert mail Mar 26 07:50:00 atmarkit sshd[27576]: Failed password for kimu from 192.168.0.1 port 1030 ssh2
今回は、syslogサーバからセキュアなログ・サーバsyslog-ngへの切り替えに関して説明を行った。ログに関する設定は以上となる。次回は、ファイル改ざんの検出について説明する。
Copyright © ITmedia, Inc. All Rights Reserved.