中国、韓国、台湾からのアクセスを排除する(2:IPアドレスリスト取得部分)


メインスクリプトの勉強が完了したので、サブスクリプトに入ります。
サブスクリプトは二つのものからなっており、一つはIPアドレスリスト(つまりcidr.txt)を入手するスクリプトで、もう一つはIPアドレスリストの更新チェック(及びiptablesの自動更新)スクリプトです。

で、まずはIPアドレスリストの取得スクリプトから勉強していきます。以下に、このスクリプトを公開しているBLOGからスクリプトを転記します(ここも便宜上ナンバリングをします)。

01: # IPアドレスリスト取得関数定義
02: IPLISTGET(){
03:     # http://nami.jp/ipv4bycc/から最新版IPアドレスリストを取得する
04:     wget -q http://nami.jp/ipv4bycc/cidr.txt.gz
05:     gunzip cidr.txt.gz
06:     # 最新版IPアドレスリストが取得できなかった場合
07:     if [ ! -f cidr.txt ]; then
08:         if [ -f /tmp/cidr.txt ]; then
09:             # バックアップがある場合はその旨をroot宛にメール通知して処理を打ち切る
10:             echo cidr.txt was read from the backup! | mail -s $0 root
11:             exit 1
12:         else
13:             # バックアップがない場合はその旨をroot宛にメール通知して処理を打ち切る
14:             echo cidr.txt not found!|mail -s $0 root
15:             exit 1
16:         fi
17:     fi
18:     # 最新版IPアドレスリストを /tmpへバックアップする
19:     /bin/mv cidr.txt /tmp/cidr.txt
20: }

コメント部分の解説は割愛するとして、まず最初は02行目と20行目です。これはもういいですね。ここでIPLISTGET関数を定義します。
この関数の内容が03行目~19行目にかかれているわけです。

04行目:
wgetコマンドを使って、http://nami.jp/ipv4bycc/cidr.txt.gzをダウンロードします。オプションでつけられている「-q」は、メッセージを表示しない、という意味です。

05行目:
gunzipコマンドを使って、ダウンロードしたgzファイルを展開します。

07行目:
ifは入れ子になっています。この行のif+条件文に対して、真の場合に返す値は08~16行目を実行します。この大きなifの方には偽の場合はありません。
さて、その条件ですが、「-f」によって、以下に続くファイルが存在するかどうかの確認を行います。そして「!」は否定を意味しますので、
if [ ! -f cidr.txt ]; then は、もしcidr.txtというファイルが(カレントディレクトリに)存在しないならば、then以下にすすめ(つまり真の場合=08~16行目にすすめ)という意味になります。
だから06行目のコメントは「# 最新版IPアドレスリストが取得できなかった場合」となっているわけですね。

08行目:
ここも条件式になっています。つまり元々の位置に(最新の)cidr.txtがなかった場合は、この行の条件式を実行することになります。その条件式は、/tmp/cidr.txtがある場合は、です。

10行目:
まずechoコマンドで文字列「cidr.txt was read from the backup!(cidr.txtはバックアップから読み込まれました!)」を作成し、それをパイプでmailコマンドに引き渡します(つまりechoで作成した文字列がメール本文になります)。
mailコマンドの「-s」オプションはサブジェクト、つまり件名を指定するオプションですが、そこに特殊変数$0を指定しています。特殊変数は「シェルスクリプト自身の名前を取得できる」んだそうで、実際に
$ echo cidr.txt was read from the backup! | mail -s $0 root
を試してみると、root宛にbashというサブジェクトでこのメール本文が届いていました。
※このスクリプトはメールを送信して処理を打ちきります。
ここで送信されている文字列「cidr.txt was read from the backup!(cidr.txtはバックアップから読み込まれました!)」の意味は、メインスクリプトが/tmp/cidr.txtからネットワークアドレスを読み込んで処理を行うスクリプトになっているため、バックアップ=古いcidr.txtから情報を読み込んで処理をしてしまっていますよ、と理解します(最初これに気づかず、このスクリプトで/tmp/cidr.txtからcidr.txtを生成しているのかと勘違いして訳がわからなくなっていた・・・)

11行目:
入れ子になっているif条件式のうち、真の場合を終了します。

12行目:
入れ子になっているif条件式のうち、偽の場合を開始します。

14行目:
10行目と同じ構造です。送信するメール本文の内容が異なります(偽の場合は/tmp/cidr.txtがなかったら、という条件となるため)。

15行目:
偽の場合を終了します。

16行目:
入れ子になっている方のifを閉じます。

17行目:
大きい方のifを閉じます。既に触れたように、大きい方のifには偽の場合は存在しません。
ここでのifは、カレントディレクトリにcidr.txtが無く(この条件が真である場合)、かつ/tmp/cidr.txtがあるならば(入れ子のifの真)このバックアップからcidr.txtを読み込むよ、というメールをrootに送り、、/tmp/cidr.txtもないならば(入れ子のifの偽)バックアップがないよ、というメールをrootに送る、ということです。
カレントディレクトリにcidr.txtが無いという条件の偽の場合とはすなわち、カレントディレクトリにcidr.txtが「ある」ということですから、そのまま処理を進めることが出きるということですからね。
06行目コメント以下に続くifは、rootにメールを送ると言う操作を行うものであり、バックアップからcidr.txtをどうこうするという類のものではないことに注意!

19行目:
最新のIPアドレスリストが取得できたならば(カレントディレクトリにcidr.txtができたならば)、そのcidr.txtを/tmp/cidr.txtにバックアップします(こうすることでバックアップは常に最新のIPアドレスリストになる)。
もし最新のそれが取得できていなかったらifに進み、処理が打ちきられるのでこの行は実行されないわけです。

これでIPアドレスリストを入手するスクリプトが完成しました。
極論すれば、このスクリプトを毎日実行し、かつメインスクリプトを毎日実行すれば常に(日にち単位での)最新IPアドレスリストに基づいて中国、韓国、台湾からのアクセスを除外することができる(はず)です。

しかし、これを毎日サーバで走らせるのは酷?だからなのか、実際にはこの二つのスクリプトの他に、IPアドレス更新チェックスクリプトが容易されています。
次はそれを見ていく予定です。

boota
boota
いろんなモノに、いろんな意味で、ヲタ。なのかも?

コメントする

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です

日本語が含まれない投稿は無視されますのでご注意ください。(スパム対策)