Logwatch in Debian Squeeze

カテゴリ: Linux

作業ログのつもりで置いている blog だけれど、結局全然書いてない。。

Debian Squeeze (6.0.6) の動いているマシンに logwatch を入れてログ監視をしているのだが、
pam_unix の解析でおかしな挙動をしていたのでデバッグをした。そのログ。

妙な挙動

 ################### Logwatch 7.3.6 (05/19/07) #################### 
        Processing Initiated: Sat Dec  1 06:25:04 2012
        Date Range Processed: yesterday
                              ( 2012-Nov-30 )
                              Period is day.
        Detail Level of Output: 0
        Type of Output/Format: mail / text
        Logfiles for Host: xxxx
  ################################################################## 

 --------------------- pam_unix Begin ------------------------ 

 su:
    Sessions Opened:
       root -> root: 1 Time(s)

 ---------------------- pam_unix End -------------------------

たしかにこの日は一般ユーザから su で root になったので、
root へのセッションが開いたのは正しい。
でも root から root って何なんだ。

デバッグ

logwatch の Perl スクリプトは /usr/share/logwatch/scripts/services 以下にある。
いまは pam_unix サービスが問題になっているので、これをいじる。

$ cp /usr/share/logwatch/scripts/services/pam_unix /etc/logwatch/scripts/services/

このPerl スクリプトの中で “su” や “Sessions Opened” なんかの文字列で検索すると、
こんな記述がみつかった。

184  } elsif (($service eq 'su') or ($service eq 'sudo') or ($service eq 'su-l')) {
185     if ( my ($logname, $uid, $ruser, $user) = ($line =~ /^authentication failure; logname=(\S*)\s+uid=(\d+) (?:.*ruser=(\S*)\s+)?.*user=(\S*)$/)) {
186        $line = ($logname or $ruser)."($uid) -> $user";
187        $data{$service}{'Authentication Failures'}{$line}++;
188     } elsif ($line =~ /session closed for user/) {
189        # ignore this line
190     } elsif (my ($nam, $byid) = ($line =~ /session opened for user (.+) by (.+)$/)) {
191        #resolve uid to name if possible
192        $byid =~ s/\(uid=(\d+)\)/$1/;
193        my $onam = getpwuid($byid) or $byid;
194        $data{$service}{'Sessions Opened'}{"$onam -> $nam"}++;

試しに print 文を挿入して $byid や $onam の値を見てみると、
$byid は正しく一般ユーザが取り出せているのに対して $onam が root になってしまっていた。
$byid は、上記の 192 行目の置換以前ではログから正規表現で抜き出したままの
“hoge (uid=1000)” のような文字列になっていて、
それを 192 行目の置換で “hoge1000″ のような文字列に変換している。
これを getpwuid() 関数に渡すと、”hoge1000” という uid のユーザはいないので、
問答無用で root の情報が返ってくる。
それで一般ユーザが root として表示されてしまっていた。

解決するには、uid の整数値文字列のみ抜き出すように、問題の置換を修正してやればいい。

$ diff /usr/share/logwatch/scripts/services/pam_unix /etc/logwatch/scripts/services/pam_unix
192c192
<          $byid =~ s/\(uid=(\d+)\)/$1/;
---
>          $byid =~ s/(.*)\(uid=(\d+)\)/$2/;

これで解決。

2012/12/01 (土)

コメント