国を指定して ipfilter.dat を作成する例2:maxmind.com のデータ GeoIP Country を利用した場合
2009-07-05 修正
前回は apnic.net のデータを使って ipfilter.dat を作成した。Wikipedia によると APNIC はアジアパシフィック地域におけるIPアドレス等を管理している非営利の地域インターネットレジストリ(RIR)だ。ここのデータが最も信頼できるわけだが、一方で一般企業によるIP範囲のリストもある。ということで、検証ついでに同条件で抽出てみる
前提条件
- 前回と同じ
- 違いは元データが maxmind.com の「GeoLite Country」であること
1.元データをダウンロード
- データは毎月初に更新される
wget -nd -nc http://geolite.maxmind.com/download/geoip/database/GeoIPCountryCSV.zip
- 短期間で何回もダウンロードしようとするとアクセスブロックされるので注意
2.解凍
unzip -u ./GeoIPCountryCSV.zip
3.データ概要
- 解凍後のファイルサイズは8メガ弱。約10万行でカンマ区切り
- 各フィールドについての資料(英語)はここ
フィールド | 意味 |
---|---|
1 | 開始IPアドレス |
2 | 終了IPアドレス |
3 | 10進数化した開始IPアドレス |
4 | 10進数化した終了IPアドレス |
5 | ISO 3166 ベースの国コード |
6 | 国名 |
"2.6.190.56","2.6.190.63","33996344","33996351","GB","United Kingdom" "3.0.0.0","4.17.135.31","50331648","68257567","US","United States" "4.17.135.32","4.17.135.63","68257568","68257599","CA","Canada" 中 略 "222.250.0.0","222.251.127.255","3740925952","3741024255","TW","Taiwan" "222.251.128.0","222.251.255.255","3741024256","3741057023","KR","Korea, Republic of" "222.252.0.0","222.255.255.255","3741057024","3741319167","VN","Vietnam"
4.ipfilter.dat 形式に変換
BEGIN { FS = ","; # OFS = ","; match_counter = 0; } /"CN","China"/ || /"HK","Hong Kong"/ || /"TW","Taiwan"/ || /"JP","Japan"/ { gsub( /"/, "" ); gsub( /,/, " ", $6); printf "%-s - %-s , %3s , [%s]%s\r\n", $1, $2, 57, $5, $6; ++match_counter; } END { printf "### The total number of matched records in the GeoIPCountry List: %d\r\n", match_counter; }
処理の流れとしては
- BEGIN ブロックで FS に読み込むファイルのセパレータを設定。カウンターを初期化
- /正規表現/ ブロックで抽出条件(今回の場合は中国 or 香港 or 台湾 or 日本)に一致したレコードのみを処理する(awk では or 条件を ¦¦ と書く)
- 二重引用符(ダブルクォーテーション)を削除
- 国名にカンマを含む場合はホワイトスペースに置換
- 入力ファイルのフィールドの順番を変更
- match_counter を加算(+1)
- END ブロックで処理した行数(match_counter)をコメント文として出力
下記のようにコマンドを実行する
gawk -f GeoIPCountry2ipfilter.awk GeoIPCountryWhois.csv
出力結果のサンプル
32.60.34.16 - 32.60.34.23 , 057 , [JP]Japan 32.60.34.192 - 32.60.34.207 , 057 , [JP]Japan 43.0.0.0 - 43.255.255.255 , 057 , [JP]Japan 中 略 222.231.64.0 - 222.231.255.255 , 057 , [JP]Japan 222.240.0.0 - 222.249.255.255 , 057 , [CN]China 222.250.0.0 - 222.251.127.255 , 057 , [TW]Taiwan ### The total number of matched records in the GeoIPCountry List: 3554
5.数値をゼロ埋めに変更する(例:1 ⇒ 001)
BEGIN { FS = " , "; # OFS = ","; match_counter = 0; } /^ *[^#]/ && /-/ && /,/ { if( split($1, IPFromTo, " - ") != 2 ){ print "[ERROR]Total number of IP field is invalid\r\n"; exit 2; } gsub(",", " ", $3); printf "%-s - %-s , %03d , %s\r\n", FillByZero(IPFromTo[1]), FillByZero(IPFromTo[2]), int($2), $3; ++match_counter; } END { if(match_counter > 0){ printf "### The total number of matched records: %d\r\n", match_counter; } } ############################## User-defined Functions ############################## function FillByZero(ip){ gsub(" ", "", ip); if( split(ip, IPs, ".") != 4 ){ print "[ERROR]Total number of IP field is invalid\r\n"; exit 4; } return sprintf("%03d.%03d.%03d.%03d", int(IPs[1]), int(IPs[2]), int(IPs[3]), int(IPs[4]) ); }
- BEGIN ブロックで FS に読み込むファイルのセパレータを設定。カウンターを初期化
- /正規表現/ ブロックでコメント行以外のレコードのみ処理する
- 第1フィールドを " - " で分割
- 第3フィールドにカンマを含む場合はホワイトスペースに置換
- printf で出力(IPアドレス部は FillByZero 関数でゼロ埋め)
- match_counter を加算(+1)
- END ブロックで処理した行数(match_counter)をコメント文として出力
下記のようにコマンドを実行する
gawk -f GeoIPCountry2ipfilter.awk GeoIPCountryWhois.csv | gawk -f FillByZero.awk
出力結果のサンプル
032.060.034.016 - 032.060.034.023 , 057 , [JP]Japan 032.060.034.192 - 032.060.034.207 , 057 , [JP]Japan 043.000.000.000 - 043.255.255.255 , 057 , [JP]Japan 中 略 222.231.064.000 - 222.231.255.255 , 057 , [JP]Japan 222.240.000.000 - 222.249.255.255 , 057 , [CN]China 222.250.000.000 - 222.251.127.255 , 057 , [TW]Taiwan ### The total number of matched records in the GeoIPCountry List: 3554
6.IPアドレスの範囲が連続しているレコードを連結してファイルサイズを減らす
gawk -f GeoIPCountry2ipfilter.awk GeoIPCountryWhois.csv | gawk -f FillByZero.awk | gawk -f ConnectRecords.awk >ipfilter.dat
- 20%強削減される。処理後の出力サンプルは下記の通り
032.060.034.016 - 032.060.034.023 , 057 , [JP]Japan 032.060.034.192 - 032.060.034.207 , 057 , [JP]Japan 043.000.000.000 - 043.255.255.255 , 057 , [JP]Japan 中 略 222.229.096.000 - 222.230.255.255 , 057 , [JP]Japan 222.231.064.000 - 222.231.255.255 , 057 , [JP]Japan 222.240.000.000 - 222.251.127.255 , 057 , [CN]China_[TW]Taiwan ### The total number of matched records: 3554 Compacted: 2737
できあがったデータを前回の APNIC ベースのデータと比べるとけっこう違いがあります。何故でしょう...(?_?) これについては後日改めて調べてみることにします
7.使い方
作成した ipfilter.dat を対応アプリに読み込ませます
まとめ
3行で ipfilter.dat が作成できた
wget -nd -nc http://geolite.maxmind.com/download/geoip/database/GeoIPCountryCSV.zip
unzip -u ./GeoIPCountryCSV.zip
gawk -f GeoIPCountry2ipfilter.awk GeoIPCountryWhois.csv | gawk -f FillByZero.awk | gawk -f ConnectRecords.awk >ipfilter.dat