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部分を参考にしていただければ対応できるはずです。

コメントを残す