ハッカーからの攻撃に対して、千手観音のような活躍をみせるSwatchの応用編
前回の投稿でSwatchの基本的な使い方を解説しました。
このページではiptablesでアクセスを遮断したり、攻撃に使われたIPに関する情報をメールに追加したりと、外部スクリプトと連携する方法を解説します。
合わせてSwatchの設定を一元管理する方法。一連の処理をテスト・調整する方法も解説します。
また、投稿の最後には実際に運用している設定の例を掲載しています。
このページで紹介するスクリプトは以下のサイトで紹介されている方法を元に手を加えたものです。この場を借りてお礼申し上げます。 http://centossrv.com/swatch.shtml
目次
Swatchによって実行されるスクリプトを作成
swatch.logのログローテーションを設定
BIND用の設定ファイルを作成
Swatchの起動スクリプトを作成
動作テスト用にスクリプトを変更
テスト方法1「実際にBINDのバージョンを問い合わせる」
テスト方法2「対象のログを自分で追加する」
実際に運用している設定の例
BINDのlogに対する設定ファイル
メールのlogに対する設定ファイル
SSLのlogに対する設定ファイル
iptablesのlogに対する設定ファイル
nginxのログに対する設定ファイル(WordPress用)
Swatchによって実行されるスクリプトを作成
まずはSwatchでパターンに一致した際に実行するスクリプトを作成します。
# vi /usr/local/bin/swatch_action.sh
#!/bin/bash PATH=/bin:/sbin:/usr/bin # 出力を英語に統一(-dを使う都合上) LANG=C # 規制IPアドレス情報メール通知先設定 # ※メール通知しない場合は下記をコメントアウト mail=root # ログを標準入力から取得 read LOG # ログからIPアドレスを抽出(オリジナルだと抽出できない場合があるため変更) IPADDR=`echo $LOG|cut -d " " -f $1` IPADDR=`echo "$IPADDR"|grep -o -E '([0-9]{1,3}\.){3}[0-9]{1,3}'` # IPアドレスをピリオドで分割 addr1=`echo $IPADDR|cut -d . -f 1` addr2=`echo $IPADDR|cut -d . -f 2` addr3=`echo $IPADDR|cut -d . -f 3` addr4=`echo $IPADDR|cut -d . -f 4` # IPアドレスがプライベートIPアドレスの場合は終了 if [ "$IPADDR" = "127.0.0.1" ]; then exit elif [ $addr1 -eq 10 ]; then exit elif [ $addr1 -eq 172 ] && [ $addr2 -ge 16 ] && [ $addr2 -le 31 ]; then exit elif [ $addr1 -eq 192 ] && [ $addr2 -eq 168 ]; then exit fi # IPアドレスがホワイトリストに一致する場合は終了 # この例では100.100.0.0/16を想定(環境によって適宜変更してください) if [ $addr1 -eq 100 ] && [ $addr2 -eq 100 ] && [ $addr3 -lt 256 ] && [ $addr4 -lt 256 ]; then exit fi # 不正アクセスログメッセージをIPアドレス別ログファイルに記録 echo $LOG >> /var/log/swatch/$IPADDR # IPリストにIPが含まれている場合は終了 # file=`cat /root/test_ip` file=`cat /root/deny_ip` echo "$file" | grep "$IPADDR" if [ $? -eq 0 ]; then exit fi # IPアドレス別ログファイルから累積不正アクセス数取得 cnt=`cat /var/log/swatch/$IPADDR | wc -l` # 該当IPアドレスからの累積不正アクセス数が3以上の場合 # IPリストへ書き出し、1週間後ブロック解除、メールでの通知 if [ $cnt -ge 3 ] ; then # 該当IPアドレスをdeny_ipに登録 # echo "$IPADDR" >> /root/test_ip echo "$IPADDR" >> /root/deny_ip # 上記リストに追加したIPを1週間で削除するスケジュールを予め登録 # echo "sed -i "/$IPADDR/d" /root/test_ip" | \ echo "sed -i "/$IPADDR/d" /root/deny_ip" | \ at now+1weeks > /dev/null 2>&1 # アクセス規制IPアドレス情報をメール通知 [ "$mail" != "" ] && (cat /var/log/swatch/$IPADDR ; \ echo ; whois $IPADDR) | \ mail -s "$IPADDR $cnt lock!" $mail echo "`date` $IPADDR $cnt lock!" # 引数でlockと指定された不正アクセスの場合 # IPリストへ書き出し、即ブロック、1ヵ月後ブロック解除、メールでの通知 elif [ $# -eq 2 -a "$2" = "lock" ]; then # 該当IPアドレスを拒否する設定をiptablesに追加 # (オリジナルだと削除する設定もあるがcronで毎日deny_ipを拒否するため不要) iptables -I INPUT -s $IPADDR -j DROP # 該当IPアドレスをdeny_ipに登録 # echo "$IPADDR" >> /root/test_ip echo "$IPADDR" >> /root/deny_ip # 上記リストに追加したIPを4週間で削除するスケジュールを予め登録 # echo "sed -i "/$IPADDR/d" /root/test_ip" | \ echo "sed -i "/$IPADDR/d" /root/deny_ip" | \ at now+4weeks > /dev/null 2>&1 # アクセス規制IPアドレス情報をメール通知 [ "$mail" != "" ] && (cat /var/log/swatch/$IPADDR ; \ echo ; whois $IPADDR) | \ mail -s "$IPADDR $cnt lock!" $mail echo "`date` $IPADDR $cnt lock!" else echo "`date` $IPADDR $cnt" fi
それぞれの役割をコメントで解説しているので、bashの基礎を学んだ方なら理解できると思います。
「$1」や「$2」といった引数がありますが、これは後ほど作成する設定ファイルで定義します。後ほど詳しく解説するので、わからない場合読み飛ばしてください。
16~17行目、オリジナルの方法だと数字以外で始まる場合や、区切り文字が変則的だと上手く取得できないことがあったのでsedコマンドを使った方法から、grepコマンドを使う方法に変更しています。
38~40行目、設定を誤って自分のIPが拒否されてしまわないようにホワイトリストを設定しています。リストに一致した場合にはスクリプトを終了させます。ISPに割り当てられているIP等を登録しておくと安心です。
47~52行目、ログでマッチしたIPを「/root/deny_ip」に書き出し、そのリストにIPが存在する場合はスクリプトを終了させます。
こうすることでDos攻撃など同じIPで短時間に連続した攻撃があった場合でも、アクションの重複を防ぐことができます。
ここでIPを書き出す「/root/deny_ip」は過去の投稿「iptablesの設定ファイルをシェルスクリプトを利用して動的に作成」の中で、このリストにあるIPを拒否するというスクリプトを作成しました。
同じように動作させたい場合は参照してください。
59~103行目、ここが実際に実行されるアクションです。オリジナルのものは同じIPが3回カウントされた場合か、引数にlockとある場合に同じ処理を指定ましたが、当サイトの解説ではそれぞれ別の処理を指定ます。
拒否IPリストの「/root/deny_ip」にIPを書き出して、一定の時間が経過したらリストから削除。そのIPに関する情報を調べてメールで送信する。
「/root/deny_ip」によるIPの拒否はCronによって毎日一度だけ実行されます。
対して引数にlockとあるものはiptablesで拒否リストに即登録されます。
このように引数によって複数のアクションを登録しておけば、攻撃の種類によって対応を分けることができます。
以上、スクリプトを作成したら、続いてIPを保存する「deny_ip」と、テストの時に利用する「test_ip」を作成。続けてSWATCHアクションスクリプトへ実行権限付加。
# echo -n > /root/deny_ip # echo -n > /root/test_ip # chmod 700 /usr/local/bin/swatch_action.sh
swatch.logのログローテーションを設定
コチラはオリジナルのものをそのまま利用させていただきます。
解説のコメントを追加したので理解できると思います。「rsyslogのログローテーションについて」知りたい方は過去の投稿を参照してください。
# mkdir /etc/swatch ← SWATCH設定ファイル格納ディレクトリ作成 # vi /etc/logrotate.d/swatch ← SWATCHログ切替え設定ファイル作成
/var/log/swatch/swatch.log { missingok # ログファイルがなくてもエラーを出さない notifempty # logファイルが空の時はrotateしない sharedscripts # postrotateまたはprerotateで記述したコマンドを実行 postrotate # ここからendscriptまでを実行 /etc/rc.d/init.d/swatch restart > /dev/null || true # ログの書き換えに際してswatchを再起動 endscript }
BIND用の設定ファイルを作成
このページではBINDのログを想定して設定ファイルを作成します。
BINDのロギングについては「BINDのlogを適切に設定して攻撃の予兆を察知しよう」でまとめたので参照してください。
BINDのバージョンの問い合わせはハッカーが脆弱性のあるバージョンであるか調査する際に使います。
# logfile /var/log/named/default.log # BINDのバージョン照会を検知したら該当ホストからのアクセスを24時間規制 watchfor /query \'VERSION\.BIND\/TXT\/CH\' denied/i pipe "/usr/local/bin/swatch_action.sh 6 lock" throttle=00:00:10
1行目、対象となるログファイルを指定します。この書式は後に作成するスクリプトで利用するため同じ書式で記述してください。
6行目、上の行にあるログに一致するパターンを記述。
7行目、「pipe “~”」で先ほど作成したスクリプトを指定。それに続いてスペース区切りで「6」と「lock」が追加されています。
このようにスペース区切りで記述することで実行するスクリプトに引数を渡すことができます。「6」を取り出す場合は「$1」。「lock」を取り出す場合は「$2」となります。
ちなみに第1引数の「6」はログの行頭からスペース区切りでいくつ目のフィールドにIPアドレスがあるかを指定するためのものです。ログによっては複数のIPが記述されている場合があるので、アクセスを規制するIPを指定する必要があります。
8行目、throttleはで実行する間隔を指定しています。10秒以内に何度もログが出力されても、10秒に1回しか実行しないという意味です。
ログの形式を検査する
BINDのバージョンを問い合わせたり、ポートスキャンを行ったりという攻撃の予兆はありきたりのものです。そこで手っ取り早くネット上のログや、別サーバが攻撃された際のログを参考にして設定を書きたいところですが、注意が必要です。
ディストリビューションやソフトのバージョンによってログの形式に揺れがあるためです。
自分のサーバからdigコマンドを利用しても同じように表示されないので、windows上からdigコマンドを利用してBINDのバージョンを調べます。
「windowsでdigコマンドを利用する方法」は以前の投稿を参照してください。
Windows上のコマンドプロンプトで以下のコマンドを打てばBINDのバージョンを調べることができます。「ns.example.com」の部分は自分で構築したDNSサーバに合わせてください。
# dig @ns.example.com chaos txt version.bind
続いてlinux側に戻り、どのようにlogに書きだされるのかを調べてみます。
# cat /var/log/named/default.log
オリジナルの例では以下の様なログを想定してパターンを定義していました。
Oct 21 05:20:12 centos named[14130]: client XXX.XXX.XXX.XXX#55199: query 'VERSION.BIND/TXT/CH' denied
しかし実際にdigコマンドを利用してアクセスしてみると以下のように出力されていました。
12-Aug-2014 08:07:43.478 security: info: client XXX.XXX.XXX.XXX#58874: query 'version.bind/TXT/CH' denied
「swatch_action.sh」の後にあるIPのあるフィールドを示す数字ですが、今回のテストでは「7つ目の項目」ではなく、「6つ目の項目」にIPが記述されています。
また一致するパターンで「VERSION\.BIND」と大文字で指定されていましたが、テストの結果は「version.bind」なので、このままではパターンに一致しません。
そこでパターンの項目に「i」を付けて大文字小文字どちらでも一致するように変更しました。
以上のように環境によって表現に揺れがあるので、できれば実際のログを参照して設定を行うようにしてください。
Swatchの起動スクリプトを作成
Swatchプロセスを起動するには以下のように設定ファイルと対象となるログファイルを指定する必要がありました。
swatch -c 設定ファイル -t 対象ログファイル &
また、終了時にはプロセスナンバーを調べて1つずつ停止しなくてはなりません。
監視するログが増えたり、サーバを再起動するごとにコマンドを打つのは現実的ではありません。そこでSwatchの起動スクリプトを作成して、一括で起動・終了を行えるようにします。
# vi /etc/rc.d/init.d/swatch
#!/bin/bash # # swatch # # chkconfig: 2345 90 35 # description: swatch start/stop script # Source function library. . /etc/rc.d/init.d/functions PATH=/sbin:/usr/local/bin:/bin:/usr/bin mkdir -p /var/log/swatch start() { # Start daemons. ls /var/run/swatch_*.pid > /dev/null 2>&1 if [ $? -ne 0 ]; then echo -n "Starting swatch" pno=0 for conf in /etc/swatch/*.conf do pno=`expr $pno + 1` WATCHLOG=`grep "^# logfile" $conf | awk '{ print $3 }'` swatch --config-file $conf --tail-file $WATCHLOG \ --script-dir=/tmp --awk-field-syntax --use-cpan-file-tail --daemon \ --pid-file /var/run/swatch_$pno.pid \ >> /var/log/swatch/swatch.log 2>&1 RETVAL=$? [ $RETVAL != 0 ] && return $RETVAL done echo [ $RETVAL = 0 ] && touch /var/lock/subsys/swatch return $RETVAL else echo "swatch is already started" fi } stop() { # Stop daemons. ls /var/run/swatch_*.pid > /dev/null 2>&1 if [ $? -eq 0 ]; then echo -n "Shutting down swatch" for pid in /var/run/swatch_*.pid do kill $(cat $pid) rm -f $pid done echo rm -f /var/lock/subsys/swatch /tmp/.swatch_script.* else echo "swatch is not running" fi } status() { ls /var/run/swatch_*.pid > /dev/null 2>&1 if [ $? -eq 0 ]; then echo -n "swatch (pid" for pid in /var/run/swatch_*.pid do echo -n " `cat $pid`" done echo ") is running..." else echo "swatch is stopped" fi } case "$1" in start) start ;; stop) stop ;; restart) stop start ;; status) status ;; *) echo "Usage: swatch {start|stop|restart|status}" exit 1 esac exit $RETVAL
起動スクリプトの詳細を追うと長くなってしまうので、一般的な設定は飛ばして、ポイントだけ紹介します。
1.Swatch用のログファイルを保存する「/var/log/swatch」というディレクトリを作成しています。
そして起動時に「/etc/swatch/」にある拡張子が「.conf」のファイルを全て実行。
監視するログファイルは「WATCHLOG=」の行で定義しています。このなかで「# logfile」の行を参照しているので、各設定ファイルで「# logfile xxx」の記述を省略せず記載しないと正しく動作しないので注意してください。
停止時に「/var/run/」にある「swatch_*.pid」というプロセスを全て終了させています。
続けてSWATCH起動スクリプトへ実行権限を付加します。
# chmod +x /etc/rc.d/init.d/swatch
SWATCH起動します。
# /etc/rc.d/init.d/swatch start
Starting swatch
もし以下のように表示される場合は「/etc/swatch/」ディレクトリに「.conf」という拡張子のファイルが作成されていません。
Starting swatchgrep: /etc/swatch/*.conf: No such file or directory
正しく起動できたら「/var/run」に「swatch_*.pid」というプロセスが起動しているか調べます。(*の部分は数字)
# cd /var/run # ls -l
プロセスが起動しない場合はswatchのログファイル「/var/log/swatch/swatch.log」を見てください。私の場合は以下のエラーが出ていました。
Can't locate File/Tail.pm in @INC (@INC contains: /usr/local/lib64/perl5 /usr/local/share/perl5 /usr/lib64/perl5/vendor_perl /usr/share/perl5/vendor_perl /usr/lib64/perl5 /usr/share/perl5 .) at /tmp/.swatch_script.16445 line 90.
これはPerlのライブラリ「File/Tail.pm」が存在しないとエラーが出ています。
yumを利用して調べてみます。
CentOS6.5では公式から見つけられなかったのでepelリポジトリを追加して調べます。
# yum --enablerepo=epel provides '*File/Tail.pm'
perl-File-Tail-0.99.3-8.el6.noarch : Perl extension for reading from continously
: updated files
目的のファイルが「perl-File-Tail」にあるようなのでインストールします。
# yum --enablerepo=epel install perl-File-Tail
(省略)
Dependencies Resolved
================================================================================
Package Arch Version Repository Size
================================================================================
Installing:
perl-File-Tail noarch 0.99.3-8.el6 epel 23 k
Transaction Summary
================================================================================
Install 1 Package(s)
(省略)
これで無事インストール完了。再び起動します。
# /etc/rc.d/init.d/swatch start
そして再びプロセスが作成されているか調べます。
# cd /var/run # ls -l -rw-r--r-- 1 root root 6 Aug 13 10:52 swatch_1.pid
どうやら無事に起動できているようなので、SWATCH起動スクリプトをcheconfigへ登録します。
# chkconfig --add swatch
SWATCH自動起動を有効にして、確認をします。
# chkconfig swatch on # chkconfig --list swatch swatch 0:off 1:off 2:on 3:on 4:on 5:on 6:off ← ランレベル2~5のonを確認
以上で起動スクリプトの設定は全て終了です。
これで次回からは「/etc/swatch/」に作成した設定ファイルを一括で起動したり、停止することができるようになりました。
# /etc/rc.d/init.d/swatch start ← 起動 # /etc/rc.d/init.d/swatch stop ← 停止 # /etc/rc.d/init.d/swatch restart ← 再起動
動作テスト用にスクリプトを変更
BINDの例でテストが重要な事が理解していただけたと思います。
これから全体のテストを行いますが、テストの際に実際にファイアーウォールで遮断されると困るので、スクリプトをテスト用に変更します。
基本的にはIPの出力先を実際に利用する「deny_ip」から「test_ip」に変更して、「iptables -I INPUT -s $IPADDR -j DROP」をコメントアウトしているだけです。
長くなるので変更箇所だけ記載します。
# vi /usr/local/bin/swatch_action.sh 46~47行目 file=`cat /root/test_ip` # file=`cat /root/deny_ip` 62~63行目 echo "$IPADDR" >> /root/test_ip # echo "$IPADDR" >> /root/deny_ip 66~67行目 echo "sed -i "/$IPADDR/d" /root/test_ip" | \ # echo "sed -i "/$IPADDR/d" /root/deny_ip" | \ 83行目 # iptables -I INPUT -s $IPADDR -j DROP 86~87行目 echo "$IPADDR" >> /root/test_ip # echo "$IPADDR" >> /root/deny_ip 90~91行目 echo "sed -i "/$IPADDR/d" /root/test_ip" | \ # echo "sed -i "/$IPADDR/d" /root/deny_ip" | \
テスト方法1、実際にBINDのバージョンを問い合わせる
外部サーバからdigコマンドを利用すると簡単にテストができます。Windows上でコマンドプロンプトから実行します。digコマンドのWindowsへのインストールは以前の投稿を参照してください。
またBINDのログは「/var/log/named/default.log」に書きだされていると仮定しています。
Windowsのコマンドプロンプトで以下のように入力します。(example.comの部分はサイトに合わせて変更してください)
# dig @ns.example.com chaos txt version.bind
正しく動作していれば初回テスト時に以下のアクションが実行されます。
- 1.「/var/log/swatch/swatch.log」に一致したログが書きだされる。
- 2.「/var/log/swatch」にIPアドレス名のファイルが作成され、ログが出力される。
- 3.「/root/test_ip」にIPが出力される。
- 4.「at」に「/root/test_ip」に追加したIPを1週間後に削除するプログラムが追加される。(# aqで参照できる。)
- 5.ログとIPの情報が設定したメールアドレスに送信される。
全て正しく実行されたことを確認したら、もう一度BINDの問い合わせを実行してください。
既に「/root/test_ip」にIPが追加されているため、登録の有無を確認するスクリプト以降は実行されません。そのため「/root/test_ip」にIPがダブって登録されたり、同じIPに関するメールは届きません。
このように設定することでDOS攻撃など連続した攻撃が発生した祭に、無駄にサーバリソースを消費することが無くなります。
もし「/var/log/swatch/swatch.log」に以下の様なログが表示されるようなら、ログに出力されたIPのフィールドを正しく指定できていません。
/usr/local/bin/swatch_action.sh: line 35: [: -eq: unary operator expected
以上で一連のログの監視とIPリストへの書き出し、メールでの通知が動作することが確認できました。
テスト方法2、対象のログを自分で追加する
上記のように自分で簡単にテストできるログの場合はいいのですが、ブルートフォース攻撃やDos攻撃のログを再現するために自分のサーバ対してテストを行うのは問題があります。
実際にサーバへ影響が出ればハッキング行為となんら変わりが無いからです。
そのような場合は想定される攻撃が起きた際のログを自分で作成してテストします。
上記の例で解説します。「動作テスト用にスクリプトを変更」を修正後作業してください。
監視用のログファイルを「/root/test.log」に変更するという修正です。
# echo -n > /root/test.log ← テスト用のlogファイルを作成 # vi /etc/swatch/named-default.conf ← 続いてログファイルの修正
# logfile /root/test.log ## logfile /var/log/named/default.log(こっちが本番用) # BINDのバージョン照会を検知したら該当ホストからのアクセスを24時間規制 watchfor /query \'VERSION\.BIND\/TXT\/CH\' denied/i pipe "/usr/local/bin/swatch_action.sh 6 lock" throttle=00:00:10
以上設定が終わったらSwatchを再起動して実際にログを追加してみます。
# vi /root/test.log
12-Aug-2014 00:00:00.000 security: info: client 100.100.100.100#58874: query 'version.bind/TXT/CH' denied
追加が終わったら保存してください。
無事に「/root/test_ip」に「100.100.100.100」というIPが追加されていればテストは成功です。
実際に運用している設定の例
サーバが違えば、構成や規模・対象としているログも千差万別のため、logファイルを睨みながら1つ1つ設定するのが王道です。
そうは言っても「異常なlogが出力されてからでは遅い」という考え方もあるので設定の例を紹介します。
BINDのlogに対する設定ファイル
上記の例ではBINDにバージョン紹介をしたらアクセス規制しました。
今度はDNS AMP対策で、BIND側でオープンリゾルバ対策をしているにもかかわらず、外部から名前解決を問い合わせた場合アクセスを規制します。
# vi /etc/swatch/named-default.conf
# logfile /var/log/named/default.log # BINDのバージョン照会を検知したら該当ホストからのアクセス規制 # 対象ログ # 12-Aug-2014 00:00:00.000 security: info: client xxx.xxx.xxx.xxx#58874: query 'version.bind/TXT/CH' denied watchfor /query \'VERSION\.BIND\/TXT\/CH\' denied/i pipe "/usr/local/bin/swatch_action.sh lock" throttle=00:00:10 # BINDへ外部外部から名前解決の問い合わせを受けた場合アクセス規制(DNS AMP対策) # 対象ログ # 14-Aug-2014 00:00:00.000 security: info: client xxx.xxx.xxx.xxx#35688: query (cache) 'isc.org/ANY/IN' denied watchfor /query \(cache\).*\/ANY\/IN\' denied/i pipe "/usr/local/bin/swatch_action.sh lock" threshold=track_by="/query/",type=threshold,count=5,seconds=300
アクションで「threshold」を利用し、「type」で「threshold」を指定しているので、最初のカウントから300秒位内に、5回カウントされたら、「swatch_action.sh」が実行されます。
注意点として、「threshold」はIP別にカウントするわけでなく、パターンにマッチした場合にカウントします。そのため4回は1.1.1.1というIPでマッチして、最後の1回は2.2.2.2でマッチした場合、スクリプトに渡されるログは2.2.2.2のものになります。厳密に運用したい場合はswatch_action.shでIP別にカウントして振り分ける必要があります。 「track_by=」でエスケープが必要な場合は「""」で囲むと動作しません。
このようにSwatch側の制御と、外部スクリプト(swatch_action.sh)を組み合わせればしきい値を柔軟に設定することができます。
メールのlogに対する設定ファイル
メールはPostfixとDovecotを想定しています。
postfix側の設定で「smtpd_client_connection_rate_limit」を設定する事もできますが、より上流で制御したほうが負荷が軽く済みます。
# postfix認証失敗を5分間に5回の失敗を3回したらアクセス規制 # 対象ログ # Aug 12 00:00:00 example.com postfix/smtpd[30277]: warning: unknown[xxx.xxx.xxx.xxx]: SASL LOGIN authentication failed: authentication failure watchfor /postfix.*authentication failure/ pipe "/usr/local/bin/swatch_action.sh 7" threshold=track_by="/authentication failure/",type=threshold,count=5,seconds=300 # dovecot認証失敗を5分間に5回の失敗を3回したらアクセス規制 # 対象ログ # Aug 15 00:00:00 example.com dovecot: pop3-login: Disconnected (auth failed, 1 attempts): user=<hoge>, method=PLAIN, rip=xxx.xxx.xxx.xxx, lip=xxx.xxx.xxx.xxx, TLS: Disconnected watchfor /dovecot.*TLS: Disconnected/ pipe "/usr/local/bin/swatch_action.sh 14" threshold=track_by="/Disconnected/",type=threshold,count=5,seconds=300
SSLのlogに対する設定ファイル
不正ログインのブルートフォース攻撃などが記録される「/var/log/secure」。
根本的な対処はSSLのポート変更、認証を許可するIPの制限、認証を鍵認証に変更するといった対策です。以上の対策を行っていれば何度ログインを施行しても破られることはありませんが、攻撃の意図をもったIPを把握するには役立ちます。
# vi /etc/swatch/secure.conf
# logfile /var/log/secure # 登録していないユーザー名でのログインはアクセス規制 # 対象ログ # Aug 26 00:00:00 example.com sshd[23540]: Invalid user hoge from xxx.xxx.xxx.xxx watchfor /Invalid user.*from/ pipe "/usr/local/bin/swatch_action.sh 10 lock" threshold=track_by="/Invalid user/",type=threshold,count=5,seconds=300 # ログイン時にパスワードを間違えた場合はアクセス規制 # そもそも鍵認証なのでパスワードを入力する行為自体が不正アクセスの証拠 # 対象ログ # Aug 26 00:00:00 example.com sshd[23522]: Failed password for hoge from xxx.xxx.xxx.xxx port 58532 ssh2 watchfor /Failed password.*from/i pipe "/usr/local/bin/swatch_action.sh 11 lock" threshold=track_by="/Failed password/i",type=threshold,count=5,seconds=300
iptablesのlogに対する設定ファイル
iptablesでログを出力し、rsyslogでログの管理をしていることが前提となります。
iptablesの設定方法については「iptablesの設定ファイルをシェルスクリプトを利用して動的に作成」。
rsyslogについては「rsyslogを利用したログファイル作成と、logrotateを利用したログのローテーション」を参照してください。
ping攻撃用
Pingは短時間に大量にアクセスされることがあるので、thresholdのlimitモジュールで1分に1度しか実行されないように制限しています。
# vi /etc/swatch/iptables-ping-ataack.conf
# logfile /var/log/iptables-ping-ataack.log # ping攻撃をしたIPをアクセス規制 # 対象ログ # Jun 16 00:00:00 example.com kernel: [IPTABLES PINGATTACK] : IN=eth0 OUT= MAC=00:16:3e:4a:04:86:f8:72:ea:d8:34:ff:08:00 SRC=xxx.xxx.xxx.xxx DST=xxx.xxx.xxx.xxx LEN=60 TOS=0x00 PREC=0x00 TTL=1 ID=14824 PROTO=ICMP TYPE=8 CODE=0 ID=14702 SEQ=33478 watchfor /IPTABLES PINGATTACK.*/ pipe "/usr/local/bin/swatch_action.sh 12 lock" threshold=track_by="/IPTABLES PINGATTACK/",type=limit,count=1,seconds=60
input-drop用
input-dropはサーバで利用していないポートへのアクセスなどが記録されている。
このログではポートスキャンを察知することができる。thresholdのlimitで処理する数を10秒に1度に制限します。
# vi /etc/swatch/iptables-input-drop.conf
# logfile /var/log/iptables-input-drop.log # サービスを提供していないPortにアクセスするIPをアクセス規制 # 対象ログ # Jun 16 00:00:00 example.com kernel: [IPTABLES DROP INPUT] : IN=eth0 OUT= MAC=00:16:3e:4a:04:86:f8:72:ea:d8:34:ff:08:00 SRC=xxx.xxx.xxx.xxx DST=xxx.xxx.xxx.xxx LEN=69 TOS=0x00 PREC=0x00 TTL=80 ID=63007 PROTO=UDP SPT=27838 DPT=53 LEN=49 watchfor /IPTABLES DROP INPUT.*/ pipe "/usr/local/bin/swatch_action.sh 13" threshold=track_by="/IPTABLES DROP INPUT/",type=threshold,limit=1,seconds=10
DNS Amp攻撃とキャッシュポイズニング(カミンスキー攻撃)用
こちらもBINDで根本的な対策をしたうえで設定する。
DNS Amp攻撃に対してはオープンリゾルバ対策。キャッシュポイズニングはソースポートランダマイゼーションとDNSSECの導入。
またBINDのログを適切に出力していることが前提となる。
# vi /etc/swatch/iptables-dnsamp.conf
# logfile /var/log/iptables-dnsamp.log # DNS Ampもしくはカミンスキー攻撃用に5分で30アクセス以上は遮断 # iptablesのrecentで60秒に10回以上のアクセスはブロックしているがそれでもアクセスが続くようならdeny_ipに入れて長期間遮断するための設定 # 対象ログ # Aug 19 00:00:00 example.com kernel: [IPTABLES DNSAMP] : IN=eth0 OUT= MAC=00:16:3e:4a:04:86:f8:72:ea:d8:34:ff:08:00 SRC=xxx.xxx.xxx.xxx DST=xxx.xxx.xxx.xxx LEN=69 TOS=0x00 PREC=0x00 TTL=79 ID=62983 PROTO=UDP SPT=58015 DPT=53 LEN=49 watchfor /IPTABLES DNSAMP.*/ pipe "/usr/local/bin/swatch_action.sh 12 lock" threshold=track_by="/IPTABLES DNSAMP/",type=threshold,count=30,seconds=300
nginxのログに対する設定ファイル(WordPress用)
大人気のWordPressはブルートフォース攻撃の対象になりやすいので対策します。
ログイン時にアクセスするwp-login.phpだけでなく、xmlrpc.phpも不正アクセスの原因になるので合わせて対策します。
また、ブルートフォース攻撃で負荷が異常にかかることもあるため、thresholdのlimitで処理する数を10秒に1度に制限します。
この設定はnginxでアクセスログを出力していることが前提となります。
# vi /etc/swatch/nginx-oxynotes.com_access.conf
# logfile /var/log/nginx/oxynotes.com_access.log # WordPressのブルートフォース攻撃対策。 # 対象ログ # xxx.xxx.xxx.xxx - - [27/Aug/2014:00:00:00 +0900] "GET /wp-login.php HTTP/1.1" 200 1400 "-" "Mozilla/5.0 (Windows NT 6.0) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/36.0.1985.143 Safari/537.36" "-" watchfor /wp\-login\.php/ pipe "/usr/local/bin/swatch_action.sh 1 lock" threshold=track_by=/wp\-login\.php/,type=threshold,limit=1,seconds=10 # 対象ログ # xxx.xxx.xxx.xxx - - [27/Aug/2014:00:00:00 +0900] "GET /xmlrpc.php HTTP/1.1" 200 71 "-" "Mozilla/5.0 (Windows NT 6.0) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/36.0.1985.143 Safari/537.36" "-" watchfor /xmlrpc\.php/ pipe "/usr/local/bin/swatch_action.sh 1 lock" threshold=track_by=/xmlrpc\.php/,type=threshold,limit=1,seconds=10
以上でSwatchの応用編は終了です。
日々新しい攻撃方法が開発されているので、たまにはログファイルを開いて正しく防御できているか確認してください。