6月 05 2007
Fedoraサーバへの不正侵入を防ぐ
今回は、サーバ管理の技術的な話題です。iptables と swatch を使い、不正侵入を試みたマシンをアクセス禁止にする方法を解説します。サーバのOSはFedora Core 6です。他のLinuxマシンにも応用できるはずです。
参考にさせていただいたのは次の記事です。
まず、「セキュリティレベルとファイアウォールの設定」を使い、基本的なファイアウォール設定を行います。すると、次のような内容で /etc/sysconfig/iptables ファイルが作成されます。
# Firewall configuration written by system-config-securitylevel # Manual customization of this file is not recommended. *filter :INPUT ACCEPT [0:0] :FORWARD ACCEPT [0:0] :OUTPUT ACCEPT [0:0] :RH-Firewall-1-INPUT - [0:0] -A INPUT -j RH-Firewall-1-INPUT -A FORWARD -j RH-Firewall-1-INPUT -A RH-Firewall-1-INPUT -i lo -j ACCEPT -A RH-Firewall-1-INPUT -p icmp --icmp-type any -j ACCEPT -A RH-Firewall-1-INPUT -p 50 -j ACCEPT -A RH-Firewall-1-INPUT -p 51 -j ACCEPT -A RH-Firewall-1-INPUT -p udp --dport 5353 -d 224.0.0.251 -j ACCEPT -A RH-Firewall-1-INPUT -p udp -m udp --dport 631 -j ACCEPT -A RH-Firewall-1-INPUT -p tcp -m tcp --dport 631 -j ACCEPT -A RH-Firewall-1-INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT -A RH-Firewall-1-INPUT -m state --state NEW -m tcp -p tcp --dport 21 -j ACCEPT -A RH-Firewall-1-INPUT -m state --state NEW -m tcp -p tcp --dport 22 -j ACCEPT -A RH-Firewall-1-INPUT -m state --state NEW -m tcp -p tcp --dport 80 -j ACCEPT -A RH-Firewall-1-INPUT -m state --state NEW -m tcp -p tcp --dport 25 -j ACCEPT -A RH-Firewall-1-INPUT -j REJECT --reject-with icmp-host-prohibited COMMIT
これを先頭部分と末尾部分に分け、間にスクリプトが生成するアクセス禁止ルールが入れられるようにします。それぞれ、/etc/sysconfig/iptables.head、/etc/sysconfig/iptables.tail として保存します。
- /etc/sysconfig/iptables.head
# Firewall configuration written by system-config-securitylevel # Manual customization of this file is not recommended. *filter :INPUT ACCEPT [0:0] :FORWARD ACCEPT [0:0] :OUTPUT ACCEPT [0:0] :RH-Firewall-1-INPUT - [0:0] -A INPUT -j RH-Firewall-1-INPUT -A FORWARD -j RH-Firewall-1-INPUT
- /etc/sysconfig/iptables.tail
-A RH-Firewall-1-INPUT -i lo -j ACCEPT -A RH-Firewall-1-INPUT -p icmp --icmp-type any -j ACCEPT -A RH-Firewall-1-INPUT -p 50 -j ACCEPT -A RH-Firewall-1-INPUT -p 51 -j ACCEPT -A RH-Firewall-1-INPUT -p udp --dport 5353 -d 224.0.0.251 -j ACCEPT -A RH-Firewall-1-INPUT -p udp -m udp --dport 631 -j ACCEPT -A RH-Firewall-1-INPUT -p tcp -m tcp --dport 631 -j ACCEPT -A RH-Firewall-1-INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT -A RH-Firewall-1-INPUT -m state --state NEW -m tcp -p tcp --dport 21 -j ACCEPT -A RH-Firewall-1-INPUT -m state --state NEW -m tcp -p tcp --dport 22 -j ACCEPT -A RH-Firewall-1-INPUT -m state --state NEW -m tcp -p tcp --dport 80 -j ACCEPT -A RH-Firewall-1-INPUT -m state --state NEW -m tcp -p tcp --dport 25 -j ACCEPT -A RH-Firewall-1-INPUT -j REJECT --reject-with icmp-host-prohibited COMMIT
次に、不正ログイン検知後に iptables を自動修正するシェルスクリプトを作成し、/usr/local/sbin/sshstop.sh として保存します。chmod +x で実行可能にしておきましょう。
- /usr/local/sbin/sshstop.sh
#!/bin/sh
# Set Variables
THRESHOLD=4
IPTABLES="/etc/sysconfig/iptables"
IPTABLES_HEAD="/etc/sysconfig/iptables.head"
IPTABLES_TAIL="/etc/sysconfig/iptables.tail"
IPTABLES_BAN="/etc/sysconfig/iptables.ban"
FTP_BAN="/etc/sysconfig/ipftp.ban"
DATE=`date "+%s"`
IPTABLES_TMP="/tmp/iptables.${DATE}"
IPBAN_TMP="/tmp/ipban.${DATE}"
FTPBAN_TMP="/tmp/ftpban.${DATE}"
MODIFIED=0
# Find SSHD Failure
if [ ! -f $IPTABLES_BAN ] ; then touch $IPTABLES_BAN; fi
cp $IPTABLES_BAN $IPBAN_TMP
IP=''
tail -1000 /var/log/secure|grep "authentication failure"|grep sshd \
|awk '{ z = split($14,arr,"="); print arr[2]; }'|sort|uniq -c|
while read COUNT HOST
do
if [ $COUNT -ge $THRESHOLD ]
then
IP=`/usr/bin/dig +short $HOST | sed 's/\n//'`
if [ -z "$IP" ] ; then IP=$HOST; fi
#echo $COUNT $IP
IPEXISTS=`grep "$IP" $IPTABLES_BAN | sed 's/n//'`
if [ -z "$IPEXISTS" ] ; then
echo "-A RH-Firewall-1-INPUT -p tcp -m tcp -s $IP --dport 22 -j REJECT" \
>> $IPBAN_TMP
fi
fi
done
# Find VSFTPD Failure
if [ ! -f $FTP_BAN ] ; then touch $FTP_BAN; fi
cp $FTP_BAN $FTPBAN_TMP
IP=''
tail -1000 /var/log/secure|grep "authentication failure"|grep vsftpd \
|awk '{ z = split($14,arr,"="); print arr[2]; }'|sort|uniq -c|
while read COUNT HOST
do
if [ $COUNT -ge $THRESHOLD ]
then
IP=`/usr/bin/dig +short $HOST | sed 's/n//'`
if [ -z "$IP" ] ; then IP=$HOST; fi
#echo $COUNT $IP
FTPEXISTS=`grep "$IP" $FTP_BAN | sed 's/n//'`
if [ -z "$FTPEXISTS" ] ; then
echo "-A RH-Firewall-1-INPUT -p tcp -m tcp -s $IP --dport 21 -j REJECT" \
>> $FTPBAN_TMP
fi
fi
done
# Create New IPTABLES and Restart iptables
cat $IPTABLES_HEAD $IPBAN_TMP $FTPBAN_TMP $IPTABLES_TAIL > $IPTABLES_TMP
if ! cmp $IPTABLES $IPTABLES_TMP
then
cp $IPBAN_TMP $IPTABLES_BAN
cp $FTPBAN_TMP $FTP_BAN
cp $IPTABLES_TMP $IPTABLES
echo "-------------------------------------"
echo "[sshstop] has changed iptables"
echo "-------------------------------------"
/sbin/service iptables restart
echo "-------------------------------------"
echo $IPTABLES
echo "-------------------------------------"
cat $IPTABLES
fi
rm -f $IPTABLES_TMP $IPBAN_TMP $FTPBAN_TMP
exit
このコマンドを実行すると、ログに不正侵入が記録されていた場合、次のような記述が iptables に挿入され、iptables デーモンが再起動されます。
-A RH-Firewall-1-INPUT -p tcp -m tcp -s 208.44.210.5 --dport 22 -j REJECT -A RH-Firewall-1-INPUT -p tcp -m tcp -s 219.94.132.52 --dport 22 -j REJECT
次に、swatchの準備をします。サーバにインストールされていなかったら、yum コマンドでインストールします。
# yum -y install swatch
続いて、swatchの設定ファイルを /etc/swatchrc として作成します。
watchfor /authentication failure/
exec /usr/local/sbin/sshstop.sh
mail=root@home.junyx.net,subject=[swatch] Authentication Failure
では、swatch を次のコマンドで起動しましょう。
# swatch -c /etc/swatchrc -t /var/log/secure &
最後に、サーバの再起動時に swatchが自動起動されるように設定します。/etc/rc.d/rc.local に次の内容を追加し、保存してください。
if [ -f /usr/bin/swatch ]; then
(echo 'Starting Swatch service') > /dev/console
/usr/bin/swatch -c /etc/swatchrc -t /var/log/secure &
fi
これで、SSH と FTP の不正侵入を防止する設定が完了です。他のポートについても、sshstop.sh スクリプトのFTP部分を参考にしていただければ対応できるはずです。