作業日記@HatenaBlog

各種の作業メモ

swatch の導入

概要

jail で運用している複数の apache サーバに対し、不正アクセス攻撃があるのでこれを防ぐ。
各 jail 内の apache サーバは、ホストの apache から proxy で代理アクセスされているので、ホストの apache に対し監視設定をする。

導入

インストール
# portinstall security/swatch
設定ファイル

rc.conf に以下を追記。

# vi /etc/rc.conf
swatch_enable="YES"
swatch_rules="1"
swatch_1_flags="--tail-file=/var/log/httpd-error.log --config-file=/usr/local/etc/swatchrc --awk-field-syntax --restart-time 01:00 --daemon --pid-file=/var/run/swatch_1.pid"
swatch_1_user="root"
swatch_1_pidfile="/var/run/swatch_1.pid"
  1. swatch_enable="YES" swatch を実行可能状態に
  2. swatch_rules="1" ルールは1種類。複数指定の場合は "1 2 3" のようにする。
  3. swatch_1_flags="..."
    • --tail-file 監視対象ファイル
    • --config-file どのように処理するかを記述したファイル。デフォルト位置は ~/.swatchrc
    • --awk-field-syntax 処理ルールに $0 $1 などを使えるようにする
    • --restart-time 指定時間に swatch を再起動させる。 HH:MM
    • --daemon デーモンで起動
    • --pid-file デーモンモードで起動する場合のプロセス ID の記述ファイル。swatch_*_pidfile と同じファイルを指定する。
  4. swatch_1_user="root" swatch の実行ユーザ指定
  5. swatch_1_pidfile="/var/run/swatch1.pid" プロセス ID ファイルの指定

複数ルールを作りたい場合は次のように記述する。

swatch_rules="1 2 3"
 
swatch_1_flags="..."
swatch_1_user="..."
swatch_1_pidfile="..."
 
swatch_2_flags="..."
swatch_2_user="..."
swatch_2_pidfile="..."
 
swatch_3_flags="..."
swatch_3_user="..."
swatch_3_pidfile="..."

 

設定ファイル

apache のエラーログを常時監視し、特定のキーワードをフックしたときスクリプトを起動させる。
 

エラーログの例

/var/log/httpd-error.log に記録された不正アクセスの例

[Sun Jan 01 12:34:56 20xx] [error] [client PPP.QQQ.RRR.SSS] Invalid method in request \x01\x01\x05

このとき Invalid method in request をキーワードに、PPP.QQQ.RRR.SSS を pf のブラックリストへ自動登録する。
 

設定ファイルを作る。
# cd /usr/local/etc/
# touch swatchrc
# vi swatchrc
watchfor /Invalid method in request/ ←キーワード
	exec "/root/bin/AddBlock.sh $8" ←実行するスクリプト

 

AddBlock.sh スクリプトを書く

上記エラーログより IP アドレスに該当する箇所は第 8 引数であるが PPP.QQQ.RRR.SSS] のように、末尾に ] があるため、スクリプトでこれを削除する。

# cd /root/bin ← /root に bin ディレクトリが無い時は mkdir bin する。
# touch AddBlock.sh
# vi AddBlock.sh

AddBlock.sh スクリプトのソース

#!/bin/sh
 
BADHOST=`echo $1 | sed -e 's/\]//'`
 
if [ $BADHOST = "127.0.0.1" ]
then
	exit 0
fi
 
set `echo ${BADHOST} | sed -e 's/\./ /g'`
octet1=$1
octet2=$2
 
if [ $octet1 -eq 192 -a $octet2 -eq 168 ]
then
	exit 0
else
	/sbin/pfctl -t badhosts -T add ${BADHOST}
	echo ${BADHOST} >> /etc/pf_conf/pf.badhosts
	exit 0
fi

ソース記述後に以下を実行

# chmod 555 AddBlock.sh
# rehash

 

pf.conf の設定

/etc/pf.conf に以下を追記。
badhosts という名のテーブルを作成し、不正アクセスしてきた IP アドレスをそこへ自動登録する。

# vi /etc/pf.conf
table  persist file "/etc/pf_conf/pf.badhosts"
block in log quick on $ext_if from  to any

pf.badhosts の作成

# mkdir /etc/pf_conf
# cd /etc/pf_conf
# touch pf.badhosts
# chmod 600 pf.badhosts 

 

/usr/local/etc/rc.d/swatch の修正

初期のシェルスクリプトでは stop するとエラーとなり pidfile を認識しないため修正した。
このサイトが参考になった。

# /usr/local/etc/rc.d/swatch stop
swatch not running? (check /var/run/swatch_1.pid).

procname の個所をコメントアウトすると正常に stop する。

# vi /usr/local/etc/rc.d/swatch
 
procname=/usr/local/bin/perl
↓
#procname=/usr/local/bin/perl

 

起動

# /usr/local/etc/rc.d/swatch start

 

各 jail のアクセス制御について

各 jail 内の apache サーバは、ホストの apache から proxy で代理アクセスしており、そのログは一括して /var/log/ に記録されている。
ログの記述は /usr/local/etc/apache22/extra/httpd-vhosts.conf に従う。
ログ出力の例

  1. jail1 のログ /var/log/jail1_error.log
  2. jail2 のログ /var/log/jail2_error.log

これらを個別に /etc/rc.conf 内の swatch 設定箇所へ記述する。

swatch_enable="YES"
swatch_rules="1 2 3"
swatch_1_flags="--tail-file=/var/log/httpd-error.log --config-file=/usr/local/etc/swatchrc --awk-field-syntax --restart-time 01:00 --daemon --pid-file=/var/run/swatch_1.pid"
swatch_1_user="root"
swatch_1_pidfile="/var/run/swatch_1.pid"
 
swatch_2_flags="--tail-file=/var/log/jail1_error.log --config-file=/usr/local/etc/swatchrc --awk-field-syntax --restart-time 01:00 --daemon --pid-file=/var/run/swatch_2.pid"
swatch_2_user="root"
swatch_2_pidfile="/var/run/swatch_2.pid"
 
swatch_3_flags="--tail-file=/var/log/jail2_error.log --config-file=/usr/local/etc/swatchrc --awk-field-syntax --restart-time 01:00 --daemon --pid-file=/var/run/swatch_3.pid"
swatch_3_user="root"
swatch_3_pidfile="/var/run/swatch_3.pid"

 

エラー

portupgrade -a で ports のアップグレードを繰り返していたところ、 perl 由来のエラーが出るようになったので CPAN モジュールを追加する。

追加モジュール
Date::Calc
Date::Format
Date::Manip
File::Tail
追加方法
# perl -MCPAN -e shell 
cpan> install Date::Calc