snortのログによるディスクフル、/tmpのオーバーフロー

※実際には12/18のネタです。

■「/tmp」が「overflow」と出た。
 ⇒vmplayer が起動しなくなり、vmplayer自体を再起動してもbusyとなった為、
  以下の症状を発見

$ df -h | grep "100\%\|overflow"
/dev/sda1             9.2G  8.7G  5.4M 100% /
overflow              1.0M  1.0M     0 100% /tmp

■原因はsnortのログが溜まっていてパーティションの容量を使い切っていた事だった。
 以下は1MB以上のファイルを一覧、一番大きいサイズのファイルだけを表示。

$ sudo env LANG=C find /var -size +1024k -ls | \
   sort -k 1 | awk '{print $1 " " $11}' | tail -1
245265 /var/log/snort/tcpdump.log.1323598209

■snortの停止

$ sudo /etc/init.d/snort stop
Stopping Network Intrusion Detection System : snort (eth0 ...done).

■ログディレクトリのサイズの確認

$ sudo du -hs /var/log/snort/
5.9G    /var/log/snort/

$ su
# ls -l /var/log/snort/* | awk '{print $3 ":" $4}' | sort | uniq
root:adm
snort:adm

■rootユーザが所有しているalertファイルが一つだけあった。

# ls -l /var/log/snort/* | grep root | awk '{print $8}'
/var/log/snort/alert.1322042758

■「tcpdump.*」は含まれていないので、まずはそちらを削除

# rm /var/log/snort/tcpdump.log.*
# df -h | grep "100\%\|overflow"
overflow              1.0M  1.0M     0 100% /tmp

■rootユーザ所有のファイルを残して「alert.*」を削除(最新のalertは残る)
 ※内容には問題が無かったので後に削除した。

# ls alert.* | grep -v alert.1322042758 | xargs rm -f

■snortの結果はシステムメールで送られるが「/tmp」が使えないので開けない
 ※スプールメールを読んで、「1000000dd」等の
  有り得ない適当な大きさの行を指定して削除するか、
  vimの「*L,*C」で表示される「Line(L)」分の行を削除する。

$ mail
mail: /tmp/mail.XXXXUfCRwr: No space left on device
$ vim /var/spool/mail/`whoami`

$ df -h | grep "100\%\|overflow"
overflow              1.0M 1008K   16K  99% /tmp

■「/tmp」配下をバックアップ。
 「/tmp」の複数の起動スクリプトが関連しているので、
 スクリプトを追ったが、システムの再起動を行った方が早く、
 間違いも無いと判断した。

 参考:/tmpのファイルがいつの間にか消えてしまう
 http://www.atmarkit.co.jp/flinux/rensai/linuxtips/342deltmpdirfile.html

$ tar zcvf ~/tmplog.tar.gz /tmp/

# sudo find /etc | grep tmp
/etc/rcS.d/S12mountoverflowtmp
/etc/default/tmpfs
/etc/init.d/mountoverflowtmp

$ grep -i usage /etc/init.d/mountoverflowtmp
        echo "Usage: mountoverflowtmp [start|stop]" >&2

$ head -12 /etc/init.d/mountoverflowtmp
#! /bin/sh
### BEGIN INIT INFO
# Provides:          mountoverflowtmp
# Required-Start:    mountall-bootclean
# Required-Stop:     umountfs
# Default-Start:     S
# Default-Stop:
# Short-Description: mount emergency /tmp.
# Description:       Mount a tmpfs on /tmp if there would
#                    otherwise be too little space to log in.
### END INIT INFO

$ grep -B 1 -A 1 tmp /etc/init.d/mountall-bootclean.sh
  start|"")
        # Clean /tmp, /var/lock, /var/run
        . /lib/init/bootclean.sh

$ sudo shutdown -r now && exit

■原因の発生箇所だけ抜き出す。

$ su root -c 'find /var/log | \
       for list in `xargs`;do \
          test -f "$list" && grep -i overflow "$list" > /dev/null 2>&1 && echo "$list"; \
       done'
パスワード:
/var/log/vmware-installer
/var/log/syslog
/var/log/daemon.log
/var/log/apt/term.log
/var/log/auth.log

■vmplayer起動中の症状だったのは間違いない。
 ※「vmware-USBArbitrator」に「mountoverflowtmp」の記述がある。

$ grep overflow /var/log/vmware-installer
insserv: There is a loop between service vmware-USBArbitrator and mountoverflowtmp if started
insserv:  loop involving service mountoverflowtmp at depth 7

■根本の原因はsnortのログなわけだ。
 ※システムメールにもあったが、「syslog」で確認。

$ sudo grep -i "overflow" --color /var/log/syslog | awk -F\: '{print $4}' | sort | uniq -c
     16      Challenge-Response Overflow Alert
     16      DNS Client rdata txt Overflow Alert
     16      Server Version String Overflow Alert

■vmwareのデーモンの復旧
 ※システムを再起動しても「vmware-USBArbitrator」が起動していなかった。

$ grep -i "bin\|lib\|usage" /etc/init.d/vmware-USBArbitrator
#!/usr/bin/env bash
    "$BINDIR"/vmware-usbarbitrator
   pid=`pgrep -f "$BINDIR"/vmware-usbarbitrator`
         echo "Usage: $BASENAME {start|stop|restart}"
$ ps -ef | grep usbarb | grep -v grep
$ sudo /etc/init.d/vmware-USBArbitrator start
$ ps -ef | grep usbarb | grep -v grep
root      2958     1  0 01:56 ?        00:00:00 /usr/bin/vmware-usbarbitrator

$ sudo /etc/init.d/vmware restart

■バックアップしたtmplogにも問題が無かったので、削除。

$ rm ~/tmplog.tar.gz

■ログの取り方を変える
 ※外向きを「any」では無く「内部ネットワーク以外」にする。
 ※内部ネットワークの監視は使用頻度の低い別のDebianサーバに任せる。

■snortの停止

$ sudo /etc/init.d/snort stop

■設定変更

$ sudo vim /etc/snort/snort.eth0.conf

★変更前

var HOME_NET any
var EXTERNAL_NET any

★変更後

var HOME_NET [172.168.34.0/24,172.168.164.0/24,172.168.10.0/24]
var EXTERNAL_NET !$HOME_NET

■snortの再開

$ sudo /etc/init.d/snort

■外部アクセスが無いので、サイズが0になった。

# env LANG=C ls -l | grep -v total | awk '{print $9 " use " $5 " bytes"}'
alert use 0 bytes
tcpdump.log.1324143272 use 0 bytes

■念の為、1時間置きにサイズをシステムメールで報告するように設定

# whereis -b ls
ls: /bin/ls

# whereis -b env
env: /usr/bin/env

0 * * * * /usr/bin/env LANG=C /bin/ls -l /var/log/snort