iptablesのパケットログをPostgreSQLに保存する
iptablesのパケットログをPostgreSQLに保存したい。何を唐突に変な事を言い出すかと思うなかれ。絶対に需要はあるはずだ(無いかも)。
ちらっとぐぐってみるとCentOS6のiptables 1.4.7にはNFLOGという仕組みがあって、さらにnetfilter.orgで提供しているulogdなるものを使うとiptablesからのログを受け取ってPostgreSQLに吐き出せるらしい。
さっそく試してみる。なお、以下の例では全て/usr/localに入るので/usr以下にあるのが良い場合はconfigureの引数を適時変更されたい。
# wget ftp://ftp.netfilter.org/pub/ulogd/ulogd-1.24.tar.bz2 # wget ftp://ftp.netfilter.org/pub/ulogd/ulogd-2.0.2.tar.bz2 # wget ftp://ftp.netfilter.org/pub/libmnl/libmnl-1.0.3.tar.bz2 # wget ftp://ftp.netfilter.org/pub/libnetfilter_acct/libnetfilter_acct-1.0.2.tar.bz2 # wget ftp://ftp.netfilter.org/pub/libnetfilter_conntrack/libnetfilter_conntrack-1.0.3.tar.bz2 # wget ftp://ftp.netfilter.org/pub/libnetfilter_log/libnetfilter_log-1.0.1.tar.bz2 # wget ftp://ftp.netfilter.org/pub/libnfnetlink/libnfnetlink-1.0.1.tar.bz2
とりあえず以上のものが要るっぽい。上のFTPサイトにはlibnetfilter_queueとかもあったけどulogd-2.0.2のビルド時に要求されなかったため取ってこなかった。ulogd-1.24は、initスクリプトの雛形が2.0.2に無かったのでここから取るために取ってきた。無くても良い。
# tar xjf libmnl-1.0.3.tar.bz2 -C /usr/local/src # tar xjf libnetfilter_acct-1.0.2.tar.bz2 -C /usr/local/src # tar xjf libnetfilter_conntrack-1.0.3.tar.bz2 -C /usr/local/src # tar xjf libnetfilter_log-1.0.1.tar.bz2 -C /usr/local/src # tar xjf libnfnetlink-1.0.1.tar.bz2 -C /usr/local/src # tar xjf ulogd-1.24.tar.bz2 -C /usr/local/src # tar xjf ulogd-2.0.2.tar.bz2 -C /usr/local/src
構築環境はx86_64なのでソースからビルドするライブラリ達は/usr/local/lib64に入って欲しい。configureオプションをつける。i686環境の場合または別にlibに入ってもいい場合はこのオプションは不要。
# export PKG_CONFIG_PATH=/usr/local/lib64/pkgconfig # cd /usr/local/src/libnfnetlink-1.0.1 # ./configure --libdir=/usr/local/lib64 # make install
ライブラリは全部上のような感じ。libnfnetlinkが色々依存されてるので最初にビルドする。ところで、CentOS6提供のmysqlパッケージがある状態でulogd-2.0.2をconfigureするとMySQL plugin: yesとなるくせにmakeするとエラーになりやがる。configureのオプションに–without-mysqlを指定する。MySQLプラグインを使う場合はmysql-develを入れるとmakeも通るようになるようだ。後、PostgreSQLを使うのでpostgresql-develとpostgresql-serverをyumで入れる。
# yum postgresql-devel postgresql-server # cd /usr/local/src/ulogd-2.0.2 # ./configure --libdir=/usr/local/lib64 --without-mysql # make install
さて、お次は設定ファイルをコピーして手直しする。/usr/local/etcに生ファイルを置きたくないので/etcに置いてリンクを張ることにする。
# cp ulogd.conf /etc # cd /usr/local/etc # ln -s /etc/ulogd.conf .
もちろんconfigureで–sysconfdir=/etcとして/etc/ulogd.confを参照するようにしても良い。そっちの方がすっきりするかも知れない。ulogd.confは
#plugin="/usr/local/lib64/ulogd/ulogd_output_PGSQL.so"
と
#stack=log2:NFLOG,base1:BASE,ifi1:IFINDEX,ip2str1:IP2STR,mac2str1:HWHDR,pgsql1:PGSQL
という2行のコメントを外すととりあえずは動く。下の方の
[pgsql1] db="nulog" host="localhost" user="nupik" table="ulog" #schema="public" pass="changeme" procedure="INSERT_PACKET_FULL"
というところに合わせてPostgreSQLの環境を直す。pg_hba.confでlocalhost(IPv6が有効になっている場合は::1のnulog)への接続を有効にした後、nupikユーザを作り、そやつをオーナーにnulogデータベースを作成する。
nulogデータベースでcreate language plpgsqlを実行した後で/usr/local/src/ulogd-2.0.2/doc/pgsql-ulogd2.sqlを流す。これで準備はOK。動作テストは
# /usr/local/sbin/ulogd -v
で動かせるのでここでstartingの状態になればとりあえずは動いている事になる。先ほど有効にしたstack=log2は[log2]セクションでグループが1という事になっているので、iptablesでは以下のように設定する。
# iptables -t nat -I POSTGROUTING -s 192.168.1.0/24 -j NFLOG --nflog-group 1
これで、POSTROUTINGチェインを通り配送元が192.168.1.0/24であるパケットがPostgreSQLのnlog2というテーブルとtcpなどのテーブルに入る。今回はnlog2テーブルの内容だけ欲しいのでINSERT_PACKET_FULLというプロシージャーでINSERT_TCP_FULLなどを呼び出しているところを削ってしまった。
以上で、iptablesのログを時刻とともにデータベースに保存する事ができるようになった。後はinitスクリプトである。ulogd-1.24のulogd.initを/etc/init.d/ulogdとしてコピーし、ちょっと手直し。スクリプトの先頭でLD_LIBRARY_PATH=/usr/local/lib64するのと、実行ファイルが/usr/sbin/ulogdになっているので/usr/local/sbin/ulogdに変更する。LD_LIBRARY_PATHは/etc/ld.so.conf.d/に/usr/local/lib64という行が入ったlocal.confなどを作ってldconfigしても良い。
もちろん、POSTROUTINGのためにはipv4転送とかの設定も要るのでそちらも適切に設定を。ついでに、先ほどのulogd.confでは/var/log/ulogd.logというファイルが出力されるので、logrotateの設定も行っておくと良い。