2017年4月3日月曜日

Raspberry Pi 3で中国からのアクセスをブロックする

WEBサーバを公開するときに気になるのが不正アクセス。Raspberry Piの場合は、WEBサイト改ざんや進入だけでなく、ただでさえ非力なので余計な負荷がかかるのも避けたい。そこで、特に不正アクセスが多いと言われている中国からのアクセスをRaspberry Pi 3で遮断してみる。

OSはRaspbianのバージョンJessie。


実際にどうするかというと、ファイヤーウォールで中国を発信元とするIPアドレスを遮断する。必要になるのが、中国に割り当てられているIPアドレス。インターネット上のIPアドレスを管理している団体は世界に5つあって、アジア太平洋地域を管轄しているのがAPNIC。この団体のFTPサイトで、管轄下の国に割り当てているネットワークセグメントのリストを公開している。このリストから中国に割り当てられているネットワークセグメントを抽出し、ファイヤーウォールの設定に使う。ファイヤーウォールの設定はfirewalldとipsetを使う。Raspberry Pi 3でのfirewalld設定についてはRaspberry Piでfirewalldを使うを参照。


中国に割り当てられているネットワークセグメントの抽出


APNICのFTPサイトからネットワークセグメントのリストをダウンロードする。


ダウンロードしたファイルの中身はこんな感じ。「|」区切りのリストで、2列目から、国、プロトコル、ネットワーク、IPアドレス数・・・となっている。


リストで「CN」が中国で、今回はIPv4のみ抽出するので、目的の行だけを抽出するのはawkコマンドで以下のようになる。


ちなみに全部で7775行ある。1つ1つ手で設定するなんて無理。


さらに、後でファイヤーウォールの設定でipsetというIPアドレスなどを管理するためのユーティリティを使うが、このときにCIDR表記(192.168.1.0/24など)でネットワークセグメントを追加する。そのため、抽出したリストの「1.0.0.0|256」を「1.0.0.0/24」のように変換する必要がある。変換するために以下のシェルスクリプトを用意した。

#!/bin/bash

fname="delegated-apnic-extended-latest"

calc_exponent () {

    dividend=$1
    exponent=0
    while [ $dividend -ge 2 ] ; do
        dividend=$(( dividend / 2 ))
        exponent=$(( exponent + 1 ))
    done

    echo $exponent
}

awk "/ipv4/ && /CN/" $fname | while read line
do
    net=$( echo $line | cut -d '|' -f 4 )
    mask=$(( 32 - $( calc_exponent $( echo $line | cut -d '|' -f 5 ) ) ))
    echo "${net}/${mask}"
done

APNICからダウンロードしたファイルと同じディレクトリに上記スクリプトを作成し実行すると、CIDR表記のリストができる。



ファイヤーウォール設定


firewalld + ipset でアクセス制限を参考に設定。

まずはipsetのインストール。


セット名CNLISTでセットを作成。


ネットワークセグメントを追加するには「ipset add CNLIST 192.168.1.0/24」のようなコマンドを実行する。上記のシェルスクリプトの下から2行目を「echo "ipset add CNLIST ${net}/${mask}"」に書き換えてcnlist.shというファイルに出力する。


作成したcnlist.shの中身を確認。


cnlist.shをスクリプトとして実行する。これで中国のIPアドレスがCNLISTセットに追加される。


CNLISTセットの確認。


CNLISTセットのネットワークセグメントからのアクセスを拒否する設定をfirewalldで行う。


firewalldの設定確認。


これで中国からのアクセスを遮断する設定はできたが、ipsetの設定は再起動すると消えてしまう。再起動時に自動設定するようにする。


OS起動時の自動設定


まずは、作成したipsetのセットをCNLISTというファイルに保存する。


OS起動時に作成したCNLSTでipsetの設定を行うスクリプトを作成する。


以下のスクリプトを保存する。
#!/bin/bash

IPSET=/sbin/ipset
DIR=/etc/ipset
CONF=CNLIST

cd $DIR
$IPSET destroy
$IPSET restore -f $CONF



続いて、firewalldの起動スクリプトを編集する。


firewalld起動前に作成したconf_ipset.shを実行してipsetの設定を行うようにする。「ExecStartPre=/etc/ipset/conf_ipset.sh 」を「ExecStart=/usr/sbin/firewalld --nofork --nopid」の前に追記する。


リブートして、ipsetの設定がされていればOK。


0 件のコメント:

コメントを投稿