IT備忘録

LINUX関連 .NET関連 DB関連 正規表現 その他 情報

参考サイト:http://www.usupi.org/sysad/156.html

われわれシステム管理者は、 悪いひとが侵入してこないよう阻止することを生業のひとつとしていますが、 侵入されたらいち早く気づいて対処することも、同じくらい必要なことだと思います。

たとえば、身に覚えがないのに、/etc 以下のファイルが知らぬ間に変更されていたり、 ファイルがなくなっていたりしますと、限りなく怪しい!ということになりますよね。

しかし、自分で定期的に確認するのは大変ですし、 ls -lR などの結果をメールで送るように仕込んでも、前との違いを見極めるのは、 やはり面倒です。それよりも、/etc 以下などで、 ファイルを作ったり消したり変更したりなどされた瞬間に、 そのことを知ることができれば、作業をもっと簡単にできます。

というわけで今回は、dnotify というものを使って、 ディレクトリ以下の状態の変化をいち早く知る方法を、ご紹介したいと思います。

dnotify というのは、ディレクトリや、 そのディレクトリ内のファイルに対して行われた操作を、 ユーザアプリケーションに通知する機能です。
Linux カーネル 2.4.19 以降で、dnotify が追加されているようです。

そして、dnotify という同じ名称のプログラムがあり、 dnotify の機能を簡単に使うことができます。
ですので、まずは、dnotify を入れるところから始めてみましょう。

Ubuntu など Debian 系のディストリビューションを使用されている貴兄は、 すでにパッケージがありますので、apt-get するだけです。

# apt-get install dnotify (root 権限で行う場合)
$ sudo apt-get install dnotify (一般ユーザで行う場合)
そうでない貴兄は、Debian のパッケージのソースをもとに、 パッケージを作ってください。
Fedora や CentOS など RPM な貴兄のための作成例を、以下に示します。

まず、ソース・アーカイブを、以下などから入手してください。

http://packages.qa.debian.org/d/dnotify.html
http://ftp.debian.org/debian/pool/main/d/dnotify/dnotify_0.18.0.orig.tar.gz

アーカイブの中に、spec ファイルの雛型がありますので、以下のようにして、 spec ファイルを作成します。

$ tar xvfz dnotify_0.18.0.orig.tar.gz dnotify-0.18.0/dnotify.spec.in
$ sed -e 's/@PACKAGE@/dnotify/;s/@VERSION@/0.18.0/' \
-e 's/Copyright:/License:/;/Serial:/d' \
dnotify-0.18.0/dnotify.spec.in > ~/rpmbuild/SPECS/dnotify.spec
$ rm -rf dnotify-0.18.0
作成したら、アーカイブを所定の位置へ移動させ、 rpmbuild コマンドに RPM パッケージを作っていただきます。

$ mv dnotify_0.18.0.orig.tar.gz ~/rpmbuild/SOURCES/dnotify-0.18.0.tar.gz
$ rpmbuild -bb ~/rpmbuild/SPECS/dnotify.spec
$ sudo rpm -i ~/rpmbuild/RPM/i386/dnotify-0.18.0-1.i386.rpm
もし、 gcc がないとか rpmbuild がないとか make がないなどと言われてしまいましたら、 それらのパッケージをインストールしてから、rpmbuild を再度実行してください。

# yum install rpm-build
# yum install gcc
# yum install make
dnotify がインストールできましたら、早速動作確認してみましょう。

まず、確認用のディレクトリを作成します。
以下では、/tmp/usutest を、確認用として作成しています。

$ mkdir /tmp/usutest
そして、以下のように、dnotify コマンドを実行します。

$ dnotify -CD /tmp/usutest -e ls -l {}
実行すると待ち状態になりますので、別の端末から、 /tmp/usutest の下にファイルを作成してみましょう。

$ touch /tmp/usutest/a
すると、dnotify コマンドを実行中の端末に、以下が出力されます。

total 0
-rw-r--r-- 1 usu adm 0 Apr 29 12:30 a
ちなみに、他のファイルを作ったり消したりしても、その瞬間に、 同様の出力が得られます。いろいろ試してみてください。



お試し実行ができたところで、一般的な使いかたをご紹介しましょう。
dnotify コマンドの書式は、以下の通りです。

dnotify オプション ディレクトリ... [-e コマンド]
まず、オプションで、通知してほしい操作の内容を指定します。
以下に、主なオプションとその意味を示します。

-C ファイルが生成されたとき
-D ファイルが削除されたとき
-M ファイルが変更されたとき
-A ファイルがアクセスされたとき
-R ファイル名が変更されたとき
-B ファイルの属性(モードや所有者など)が変更されたとき
-a 上記のすべて
先ほどの例では、-CD と指定しましたので、 ファイルの生成と削除の際に通知するよう指定していました。

そして、監視したいディレクトリを指定します。
先ほどの例では /tmp/usutest だけを監視しましたが、複数指定することもできます。

そして最後に、通知されたときに実行されるコマンドを、 -e オプションで指定します。 {} の部分は、対象のディレクトリ名に置換されます。
ちなみに、-e オプションを省略すると、echo {} が実行されます。

使いかたが、なんとなくわかりましたでしょうか。
それでは、以降で、監視の自動化を試みたいと思います。

まず、以下の単純なシェルスクリプトを作成しましょう。

#!/bin/sh
LANG=C /bin/ls -l $1 | /usr/bin/Mail -s "[notice] $1" $USER
これを、たとえば ~/dnotify-test.sh というファイル名で保存したら、 以下のように実行してみてください。

$ chmod +x ~/dnotify-test.sh
$ dnotify -CD /tmp/usutest -e ~/dnotify-test.sh {}
そして、先ほどと同様、/tmp/usutest にファイルを作成(もしくは削除)しますと、 自分宛に以下のようなメールが飛んできます。

To: usu@usupi.org
Subject: [notice] /tmp/usutest

total 4K
-rw-r--r-- 1 usu adm 0 Apr 29 12:30 a
-rw-r--r-- 1 usu adm 5 Apr 29 15:23 b
対象のディレクトリを ls -l した結果を、メールで通知するようにしています。



これを、/etc に対して行えば、監視に使えそうです。
ただ、/etc 直下だけでなく、/etc/ssh などの下も監視したいですよね。
そんなときには、-r オプションを指定します。
-r オプションを指定しますと、 そのディレクトリ以下すべてを監視してくれます。
たとえば、以下のように、/tmp/usutest/dir というディレクトリを作成してから、 -r オプションつきで dnotify を実行します。

$ mkdir /tmp/usutest/dir
$ dnotify -CDMRr /tmp/usutest -e ~/dnotify-test.sh {}
そして、/tmp/usutest/dir 以下を変更などしますと、

$ touch /tmp/usutest/dir/a
やはり、同様にメールが飛んできます。
(/tmp/usutest/dir の ls -l の結果であるところが、ややミソです。)

To: usu@usupi.org
Subject: [notice] /tmp/usutest/dir

total 0K
-rw-r--r-- 1 usu adm 0 Apr 29 15:35 a
さて、あとは、システムの起動とともに、自動的に動いてくれれば、 目的を達成できそうです。

いくつか方法が考えられますが、 ここでは init を使って実現してみたいと思います。
以下の1行を、/etc/inittab の最後に追加してみてください。

dn:235:respawn:/usr/bin/dnotify -CDMRBr /etc -e /home/usu/dnotify-test.sh {}
そして、init に SIGHUP シグナルを送って、気づいてもらいます。

# kill -HUP 1
# ps uww -C dnotify
USER PID %CPU %MEM VSZ RSS TTY STAT START TIME COMMAND
root 9363 0.0 0.2 1572 416 ? Ss 15:46 0:00 \
/usr/bin/dnotify -CDMRBr /etc -e /home/usu/dnotify-test.sh {}
上記のように、dnotify が動作していることを確認してください。
ただ、これですと、監視していることがバレバレですね。
まあ、今のところは、目をつぶっていただけますと幸いです。

さて、ほんとにこれで大丈夫か、動作確認してみましょう。
以下では、例としてパスワードを変更しています。

# passwd usu
Changing password for user usu.
New UNIX password: (パスワードを入力)
Retype new UNIX password: (パスワードを再入力)
passwd: all authentication tokens updated successfully.
すると、2通来ますが、メールで通知されることが確認できます。



2通届くのもやや面倒ですが、もっと面倒なのは、 ls -l /etc の出力結果をメールで送られても、変更内容がよくわからない、 ということです。

ですので、前回の状態(ls -l)を残しておいて、変化があったときだけ、 その差分をメールするようにしてみました。

#!/bin/sh
LANG=C
export LANG
ESCNAME="`echo $1 | /usr/bin/tr / _`"
PREVFILE="/usr/local/etc/dnotify/$ESCNAME"
TEMPFILE="/usr/local/etc/dnotify/tmp-${ESCNAME}-$$"
DIFFFILE="/usr/local/etc/dnotify/diff-${ESCNAME}-$$"
trap "rm -f $TEMPFILE $DIFFFILE" 0 1 2 3 9 11 15
/bin/ls -l $1 > $TEMPFILE
if [ -f $PREVFILE ]; then
/usr/bin/diff -u $PREVFILE $TEMPFILE > $DIFFFILE
if [ "`/usr/bin/wc -c $DIFFFILE|/bin/awk '{print $1}'`" -gt 0 ]
then
/bin/cat $DIFFFILE | /usr/bin/Mail -s "[notice] $1" $USER
fi
else
/bin/cat $TEMPFILE | /usr/bin/Mail -s "[notice] $1" $USER
fi
mv $TEMPFILE $PREVFILE
/usr/local/etc/dnotify というディレクトリ以下を使用するようにしています。 ですので、以下の手順であらかじめ作成してください。

# mkdir /usr/local/etc/dnotify
# chmod 700 /usr/local/etc/dnotify
そして、試しに、/etc/usutest というファイルを作成してみますと…

# touch /etc/usutest
以下のようなメールが飛んできました。
まだまだ見やすいとは言いがたいですが、 ls -l の出力結果よりはわかりやすくなったのではないかと思います。

Subject: [notice] /etc

--- /usr/local/etc/dirnotify/_etc ...年月日は略...
+++ /usr/local/etc/dirnotify/tmp-_etc-15387 ...年月日は略...
...中略...
@@ -151,6 +151,7 @@
-rw-r--r-- 1 root root 807103 Jan 7 2007 termcap
drwxr-xr-x 5 root root 224 Sep 25 2008 udev
-rw-r--r-- 1 root root 127 Mar 15 2007 updatedb.conf
+-rw-r--r-- 1 root root 0 May 3 22:44 usutest
-rw-r--r-- 1 root root 1488 May 10 2007 vimrc
-rw-r--r-- 1 root root 1488 May 10 2007 virc
drwxr-xr-x 3 root root 4096 Oct 15 2008 vz
以上、dnotify を使ったディレクトリの監視方法を、ご紹介しました。

 リンク

Apache 2.0とTomcat 5.0の連携
dnotifyを利用する場合
SQLのテクニックを記
Oracleのテクニックを記
VARCHAR2をNUMBERに変換する際、桁数で怒られるときに桁数を無視するfunction
tracの設定メモ
inotifyを利用する場合
監視サーバーの設
SSLキー作
監視サーバーの設
[IT備忘録]のサイト内にある文章の正確性については一切責任を持ちません。
実開発の際には、技術的内容は十分確認した上で作業してください。

(C) 2010 IT備忘録 All rights reserved.