グローバルIPアドレス国別割り当てのデータを生成するスクリプトを書いた
サーバーの保守をやっていると、接続元IPアドレスで国外からのアクセスかどうかを調べることが多々あります。1、2件調べるだけならwhois
コマンド使って確認すればいいんですけど、whois
の結果って表示書式がバラバラでかなり見にくいですよね。
それに、アクセスログから収集した多数のIPアドレスについて確認するとなると…。なかなか面倒な話です。IPアドレスと割り当て先の国の対応表でもあれば、うまいことマッチングさせられるので楽なんだけどなと思って、Google先生に問い合わせると、いろいろとご回答をいただきました。
- 世界の国別 IPv4 アドレス割り当てリスト
- IPアドレスから割当国を調べるDNSサービス稼働中
- 不正アクセスの発信地の国別統計をとろう!
- ipv4.fetus.jp : 国/地域別IPアドレス(IPv4アドレス)割り当て一覧
これらのページで公開されているリストを使ってしまうというのもいいのですが、RIRsから、日々更新されているデータがもとになっているっぽいので、プログラム書きの練習がてら、RIRs提供データから、国コードとIPアドレスの対応表を作成するスクリプトをPythonで書いてみました。
RIR statistics exchange formatからIPv4アドレスと国コードの対応表を作るPython3スクリプト
紆余曲折あって出来上がったのが、こちらのスクリプトです。Python3には、IPアドレスを扱うのに便利なipaddressというモジュールがあるということを発見して、これを使って書いてみました。
ちなみに、どうやらipaddressモジュールは、Python 2.x系では標準サポートされていないっぽい?です。
17行目の、rirsFile = 'rirsfiles'
で元となるRIR statisticsのデータファイルを指定してあげます。
18行目の、outFile = 'ipdata.csv'
で出力するcsvデータの保存先ファイルを指定してあげます。
各RIRが提供しているRIR statisticsのデータは、
- ftp://ftp.arin.net/pub/stats/arin/delegated-arin-extended-latest
- ftp://ftp.ripe.net/pub/stats/ripencc/delegated-ripencc-extended-latest
- ftp://ftp.apnic.net/pub/stats/apnic/delegated-apnic-extended-latest
- ftp://ftp.lacnic.net/pub/stats/lacnic/delegated-lacnic-extended-latest
- ftp://ftp.afrinic.net/pub/stats/afrinic/delegated-afrinic-extended-latest
からそれぞれ最新版がダウンロードできます。各RIRのローカル時刻で23:59時点の情報から生成されるデータのようです。毎日更新されているらしいです。IPv4以外の情報も混じっていますが、IPv4についての部分のみ抽出するようにしてあるので、前処理不要です。しいて言えば、5つのRIRからダウンロードしてきたデータを単純に結合しておくと、全部分をいっぺんにできます。
RIR statistics exchange formatについては、APNICのページに見やすく成型されたドキュメントがあります。→RIR statistics exchange format | APNIC
出力されるCSVファイル
上記スクリプトで生成されるcsvファイルは、以下から出力ファイルがダウンロードできるようにしてみました。データの正確性については保証できませんが、ご自由にごりようください。データは、毎日午前3時30分ごろに更新されます。上記スクリプトから生成されるのは、改行コードがLFのものだけですが、事後処理でCR+LF版も生成してあります。
- 改行コードLF(Linux)版:http://docs.sk-net.xyz/ipdata.csv
- 改行コードCR+LF(Windows)版:http://docs.sk-net.xyz/ipdata_rl.csv
自動化のしくみとか
- 最新版ファイルのダウンロード
- ダウンロードデータからcsvファイル作成
- Postgresqlへの読み込み
を自動化させようと思ってごにょごにょしてます。おおむね完成というところです。一応、Githubにレポジトリを作ってみたのでどうぞ。Pythonとshのコラボ仕様となっています。
Postgresに取り込んでいるのは、最初にやりたかった「アクセスログから収集した多数のIPアドレスについて確認」をするために、検索ならば、DBにデータ入れといたほうがいろいろとよかろうという、思い込みによるものです。
DBがPostgresqlなのは、データ型にipaddressに関する型があって、なんだか便利そうだったのでpostgresqlです。
記事書きながら一応調べなおしたら、mysqlには型はないけど、一応簡単に扱えるらしいですね...。→ SQLにおけるIPアドレスの比較 | Yakst
あれ・・・
マッチングに使うデータの生成まではできましたが、まだ当初目的「アクセスログから収集した多数のIPアドレスについて確認」を達成していません。もう一息。