ジョートーTechなメモ

サーバとかAWS(Amazon Web Services)関係の設定などをメモ書きしていきます

EC2 にて特定の国からのアクセスを拒否する

EC2で運用しているWordpressに結構な頻度でスパムコメントの書き込みが発生していて、スパムコメントの対応が煩雑になってきました。また、スパムでサーバの負荷や帯域を使うのももったいない。

アクセス元を確認すると、特定の国からのアクセスがほとんどでした。

今まで、サーバ単体ではiptablesを使ったバッチ処理で国ごとIP制限をかけていましたが、AWSでは、FireWall関係は全てAWSコンソールの「Security Groups」で設定するというのがお作法なんですかね?

参考: iptables | サボり屋の技術メモ

 

ということで、簡易ではありますが .htaccess を使ってアパッチで制御してみることにしました。

 

いろいろ国別 IPv4 アドレス割り当てリストなどが公開されていますが、APNICのリストを取得してスクリプトで加工することにします。

Wordpress で元々設置される .htaccess にアクセス制限の処理を追記するようにします。

元の.htaccess

<IfModule mod_rewrite.c>
RewriteEngine On
RewriteBase /
RewriteRule ^index\.php$ - [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /index.php [L]
</IfModule>

これに、

order allow,deny
allow from all 

 を追加して、/usr/local/etc/htaccess_wordpress (ファイル名は任意)を作成します。

<IfModule mod_rewrite.c>
RewriteEngine On
RewriteBase /
RewriteRule ^index\.php$ - [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /index.php [L]
</IfModule>

order allow,deny
allow from all

 このファイルに、ブロックする国のIPリストを追記するスクリプトを下記のように作成しました。(/usr/local/bin/block_country.sh)

#!/bin/sh -f
#----------------------------------------------------------#
# 指定した国からのアクセスを拒否する
# ※COUNTRYLISTにスペース区切りでアクセスを拒否したいCountry Codeを指定
# ※各国割当てIPアドレス情報はAPNIC(http://www.apnic.net/)より最新版を取得
COUNTRYLIST='XX XX'
LIST_DIR='/usr/local/etc/ip_list'

if [ $# != 2 ]; then
    echo "block_country.sh <document root> <original .htaccess>"
    exit
fi
DOCUMENT_ROOT=$1
HTACCESS_ORG=$2
cat $HTACCESS_ORG > $DOCUMENT_ROOT/.htaccess
cd $LIST_DIR
wget -q http://ftp.apnic.net/stats/apnic/delegated-apnic-latest
for country in $COUNTRYLIST
do
    for ip in `cat $LIST_DIR/delegated-apnic-latest | grep "apnic|$country|ipv4|"`
    do
        FILTER_ADDR=`echo $ip |cut -d "|" -f 4`
        TEMP_CIDR=`echo $ip |cut -d "|" -f 5`
        FILTER_CIDR=32
        while [ $TEMP_CIDR -ne 1 ];
        do
                TEMP_CIDR=$((TEMP_CIDR/2)) <- 全角で書いてます
                FILTER_CIDR=$((FILTER_CIDR-1))<- 全角で書いてます
        done
        # .htaccess にアクセス拒否IPを設定
        echo "deny from $FILTER_ADDR/$FILTER_CIDR" >> $DOCUMENT_ROOT/.htaccess
    done
done

# apache再起動
/etc/init.d/httpd restart

# IPリストの削除
rm -f $LIST_DIR/delegated-apnic-latest

第1引数にアクセス権限かけたいドキュメントルートを入力させ、第2引数に先程の.htaccess の元を入力させます。

これを /etc/crontab に週1位で実行するように設定します。

00 6 * * 1 root /usr/local/bin/block_country.sh /var/www/wordpress /usr/local/etc/htaccess_wordpress > /dev/null 2>&1