【Python】GeoLite2でIPアドレスから国を確認する

10 min

こんにちは。ナミレリです。みなさん、MacでPythonは使っていますか?

アクセスログのIPアドレスから国をサクッと調べたいときってありますよね。そこで今回は無料のGeoLite2を使ってPythonでIPアドレスから国を確認するプログラムを作ってみます。

この記事はこんな人にオススメ

  • IPアドレスから国を確認したい
  • 複数のIPアドレスから一気に国を確認したい
  • しかも無料で簡単に確認したい
この記事のMac環境
  • M2 MacBook Air 13.6 インチ
  • macOS Ventura 13.0.1
  • pyenv 2.3.8
  • miniforge3-4.10.3-10(Python 3.9.15)
Parallels Desktop 20 for Macの無料トライアル もありますので、ぜひダウンロードして試してみてください。M1/M2/M3のMac上で快適にMacやUbuntu、Windowsが動作します。
NEW Parallels Desktop 20 for Mac

Parallels Desktop 20 for Macは、M1/M2/M3のMac上で快適にMacやUbuntu、Windowsが動作します。

14日間の無料トライアルもありますので、ぜひダウンロードして試してみてください。

そもそもGeoLite2ってなに?

GeoLite2とはアメリカのMAXMIND社が提供する無料のIPジオロケーションのデータベースです。IPジオロケーションとはIPアドレスからデータベースを検索することを言います。

このGeoLite2は無料ですが、無料ではないGeoIP2というサービスもあります。こちらはより正確なデータ(緯度経度等でしょうか)で毎週データベースのアップデートがされるようです。

今回はプライベートなサーバに対して凄い勢いでアタックをするIPアドレスの国を確認したい程度で完璧な正確性は求めないので無料版のGeoLite2を使ってみます。

また、GeoLite2はデータをダウンロードして使用する方法と、APIへアクセスして使う方法があります。APIを使う場合は1日1,000回が上限のようなので、今回はデータをダウンロードして使用します。

IPアドレス割り振りの仕組みを理解し自前で作ることもできます

ちなみにGeoLite2を使わずとも各国に割り振られたIPアドレス公開されているのでそれを使えば今回の目的は達成できます。下の記事ではGeoLite2を使わずにpandasを使ってIPアドレスの国を確認していますので是非ご覧ください。

では世界的なIPアドレス割り振りの仕組みを簡単に紹介していきます。

IPアドレス割り振りの仕組み

世界のIPアドレスはICANNによってい管理されています。IPアドレスだけではなく新しいTLD(トップレベルドメイン)、AS番号の管理、ルートDNSの維持管理なども行っています。ICANNとは「Internet Corporation for Assigned Names and Numbers」の略です。

IPアドレスは、このICANNが世界に5つある地域インターネットレジストリ(Regional Internet Registry:RIR)に割り振り、このRIRがさらに各国に割り振り管理されています

地域名称
北アメリカAmerican Registry for Internet NumbersARIN
ヨーロッパ、 中東 、中央アジアRIPE Network Coordination CentreRIPE NCC
アジア・太平洋地域Asia-Pacific Network Information Centre APNIC
南アメリカ とカリブ海地域Latin American and Caribbean Internet Address Registry LACNIC
アフリカAfrican Network Information CentreAfriNIC
表:世界に5つある地域インターネットレジストリ

アジア圏のRIRはAPNIC(Asia-Pacific Network Information Centre)です。このAPNICから日本であればJPNIC(Japan Network Information Center)に割り振りが行われます。

地域インターネットレジストリ(RIR)が公開しているIPアドレス割り振りデータ

前述の世界に5つある地域インターネットレジストリ(RIR)が各国に割り振りしたIPアドレスを公開しています。

アジア・太平洋地域の各国にIPアドレスを割り振るAPNICのサーバから世界に5つあるRIRのデータがダウンロードできます。ファイル名には規則性があります。

(北アメリカのARINのextendedではないフォーマットのデータが見つかりませんでした。)

地域FTP(最新IPアドレスデータ)
北アメリカARINhttps://ftp.apnic.net/stats/arin/delegated-arin-extended-latest
ヨーロッパ、 中東 、中央アジアRIPE NCChttps://ftp.apnic.net/stats/ripe-ncc/delegated-ripencc-latest
アジア・太平洋地域APNIChttps://ftp.apnic.net/stats/apnic/delegated-apnic-latest
南アメリカ とカリブ海地域LACNIChttps://ftp.apnic.net/stats/lacnic/delegated-lacnic-latest
アフリカAfriNIChttps://ftp.apnic.net/stats/afrinic/delegated-afrinic-latest
表:世界に5つある地域インターネットレジストリの最新データ

crulなどでダウンロードしファイルサイズを見てみると下のようになります。


curl \
-O https://ftp.apnic.net/stats/arin/delegated-arin-extended-latest \
-O https://ftp.apnic.net/stats/ripe-ncc/delegated-ripencc-latest \
-O https://ftp.apnic.net/stats/apnic/delegated-apnic-latest \
-O https://ftp.apnic.net/stats/lacnic/delegated-lacnic-latest \
-O https://ftp.apnic.net/stats/afrinic/delegated-afrinic-latest


ls -lh
total 52608
-rw-r--r--  1 u  staff   388K 12 11 11:59 delegated-afrinic-latest
-rw-r--r--  1 u  staff   3.5M 12 11 11:59 delegated-apnic-latest
-rw-r--r--  1 u  staff    11M 12 11 11:59 delegated-arin-extended-latest
-rw-r--r--  1 u  staff   2.0M 12 11 11:59 delegated-lacnic-latest
-rw-r--r--  1 u  staff   7.2M 12 11 11:59 delegated-ripencc-latest

ファイルのフォーマット

ファイルのフォーマットは|で区切られたCSVで以下の通りです。

registry|cc|type|start|value|date|status


grep ipv4 delegated-apnic-latest | tail -10
apnic|KR|ipv4|223.255.208.0|4096|20100802|allocated
apnic|ID|ipv4|223.255.224.0|2048|20100809|allocated
apnic|AU|ipv4|223.255.232.0|1024|20100812|allocated
apnic|CN|ipv4|223.255.236.0|1024|20110311|allocated
apnic|HK|ipv4|223.255.240.0|1024|20100803|allocated
apnic|IN|ipv4|223.255.244.0|1024|20100804|allocated
apnic|HK|ipv4|223.255.248.0|1024|20151105|allocated
apnic|CN|ipv4|223.255.252.0|512|20110414|allocated
apnic|SG|ipv4|223.255.254.0|256|20110408|assigned
apnic|AU|ipv4|223.255.255.0|256|20110811|assigned

項目意味
registryapnic地域インターネットレジストリ(RIR)
ccJPISO 3166の国コード
typeipv4ipv4, ipv6, asnのどれかが入ります
start223.252.112.0開始のIPアドレス(ネットワークアドレス)
value4096IPアドレスの個数
date20100727割り当てた年月日(YYYMMDD形式)
statusallocatedallocated, assignedのどちらかのステータス
extensionsA918B936extendedフォーマットのみ
表:世界に5つある地域インターネットレジストリの最新データ

ここまでの説明のように各国に割り振られたIPアドレスはこのように公開されているので、それを使い自前で構築することもできます。詳しくは下記の記事をご覧ください。

GeoLite2にサインアップ

前置きが長くなりましたが、GeoLite2を利用するためにまずはアカウント登録が必要になります。下記のURLからアカウント登録します。

GeoLite2のアカウント登録画面

様々なサービス登録のためのEメールアドレスはMacの「メールを非公開」を使うと便利ですね。「メールを非公開」機能とは一意のランダムなメールアドレスを生成して管理できます。

GeoIPデータベースをダウンロードする

APIでアクセスする方法もありますが、今回はローカルにデータベースをダウンロードして使います。サイトにログインし、サイドバーのメニュー[Download Files]をクリックします。今回は国を確認したいので「GeoLite2 Country」のGZIPをダウンロードすれば良いのですが、「GeoLite2 City」でも取得できる情報を確認したいので両方ダウンロードしました。

なお、ダウンロードすると使用許諾契約に同意したことになりますのであらかじめ目を通しておきましょう。MaxMind End User License Agreement

GeoLite2のダウンロード画面

データにはデータベース(MMDB)形式とCSV形式があり、GZIPでダウンロードするとMMDB形式のデータベースがダウンロードできます。今回は効率的に検索したいのでMMDB形式をダウンロードします。ちなみにMMDB形式とはMaxMindのMM、DataBaseのDBの略です。

「GeoLite2 Country」のダウンロードされたtar.gzを展開すると下記のファイルが入っています。GeoLite2-Country.mmdbのファイルサイズは約5.4MBです。

GeoLite2 Country


ls -lh
total 11048
-rw-r--r--@ 1 u  staff    55B 12  9 07:43 COPYRIGHT.txt
-rw-r--r--@ 1 u  staff   5.4M 12  9 07:43 GeoLite2-Country.mmdb
-rw-r--r--@ 1 u  staff   398B 12  9 07:43 LICENSE.txt

「GeoLite2 City」のダウンロードされたtar.gzを展開すると下記のファイルが入っています。GeoLite2-City.mmdbのファイルサイズは約65MBです。

GeoLite2 City


ls -lh
total 132384
-rw-r--r--@ 1 u  staff    55B 12  9 07:43 COPYRIGHT.txt
-rw-r--r--@ 1 u  staff    65M 12  9 07:43 GeoLite2-City.mmdb
-rw-r--r--@ 1 u  staff   398B 12  9 07:43 LICENSE.txt
-rw-r--r--@ 1 u  staff   116B 12  9 07:43 README.txt

GeoLite2をPythonで使ってみる

ダウンロードした「GeoLite2 Country」や「GeoLite2 City」をローカル環境で使って、IPアドレスから国を確認してみます。

pipgeoip2モジュールをインストール

Pythonから簡単に操作できるようになるgeoip2モジュールをインストールします。

下記のコマンドでpipgeoip2モジュールをインストールします。


pip install geoip2

GeoLite2 Cityを試してみる

まずは「GeoLite2 City」のMMDB(MaxMindのMM、DataBaseのDBの略)を使ってみます。調べるIPアドレスにはGoogle Public DNSにしてみます。

3行目には「GeoLite2 City」のMMDBのPATHを、4行目には調べたいIPアドレスを設定します。


import geoip2.database

db_path = '/path/to/GeoLite2-City.mmdb'
ip = '8.8.8.8'

with geoip2.database.Reader(db_path) as reader:
	response = reader.city(ip)
	print("country.iso_code:", response.country.iso_code)
	print("country.name:", response.country.name)
	print("subdivisions.most_specific.name:", response.subdivisions.most_specific.name)
	print("subdivisions.most_specific.iso_code:", response.subdivisions.most_specific.iso_code)
	print("city.name:", response.city.name)
	print("postal.code:", response.postal.code)
	print("location.latitude:", response.location.latitude)
	print("location.longitude:", response.location.longitude)
	print("traits.network:", response.traits.network)

実行すると下のように表示されます。


python ./geoLite2_city.py 
country.iso_code: US
country.name: United States
subdivisions.most_specific.name: None
subdivisions.most_specific.iso_code: None
city.name: None
postal.code: None
location.latitude: 37.751
location.longitude: -97.822
traits.network: 8.8.0.0/19

この例では値がないNoneも多いですが、自分のグローバルIPで試したところ詳細に確認することができました。

GeoLite2 Countryを試してみる

次に「GeoLite2 Country」でやってみます。

3行目にはMMDBのPATHを「GeoLite2 Country」のPATHにし、7行目のreader.cityメソッドをreader.countryメソッドに置き換えます。


import geoip2.database

db_path = '/path/to/GeoLite2-Country.mmdb'
ip = '8.8.8.8'

with geoip2.database.Reader(db_path) as reader:
	response = reader.country(ip)
	print("country.iso_code:", response.country.iso_code)
	print("country.name:", response.country.name)
#	print("subdivisions.most_specific.name:", response.subdivisions.most_specific.name)
#	print("subdivisions.most_specific.iso_code:", response.subdivisions.most_specific.iso_code)
#	print("city.name:", response.city.name)
#	print("postal.code:", response.postal.code)
#	print("location.latitude:", response.location.latitude)
#	print("location.longitude:", response.location.longitude)
	print("traits.network:", response.traits.network)

reader.countryにはないメソッドはコメントアウトしました。

実行すると下のように表示されます。


python ./geoLite2_country.py 
country.iso_code: US
country.name: United States
traits.network: 8.8.0.0/15

今回はIPアドレスから国を確認したいので「GeoLite2 Country」で十分です。

引数に複数のIPアドレスを指定できるようにする

sys.argvを使い引数に複数のIPアドレスを指定できるようにしてみます。


import geoip2.database
import sys

db_path = '/path/to/GeoLite2-Country.mmdb'
ips = sys.argv[1:]

with geoip2.database.Reader(db_path) as reader:
	for ip in ips:
		response = reader.country(ip)
		print(ip, end=",")
		print(response.country.iso_code, end=",")
		print(response.country.name, end=",")
		print(response.traits.network)

実行すると下のように表示されます。

IPアドレス, 国コード, 国名, CIDRの順番で出力しています。


python geoLite2_country_argv.py 8.8.8.8 8.8.4.4
8.8.8.8,US,United States,8.8.0.0/15
8.8.4.4,US,United States,8.8.0.0/15

ApacheのログからIPアドレスから国を確認してみる

catでログを指定しcutで1番目のフィールド(IPアドレス)を抜き出し、xargsで先程のプログラムに引数として与えています。様々な応用ができると思います。


cat <LOG> | cut -d ' ' -f 1 | xargs -L 1 python <PATH_to_geoLite2_country_argv.py>

データベースのアップデート(geoipupdate)

MMDB(MaxMindのMM、DataBaseのDBの略)をアップデートするコマンド(geoipupdate)も用意されています。MacではBrewでインストールできます。早速やってみましょう。

geoipupdateコマンドをインストールする


brew install geoipupdate


which geoipupdate
/opt/homebrew/bin/geoipupdate

GeoIP.confで設定する

設定ファイルは/opt/homebrew/etc/GeoIP.confです。最低限必要な設定をします。


vi /opt/homebrew/etc/GeoIP.conf

GeoIP.confの8行目にアカウントID、9行目にライセンスキー、18行目にMMDDがあるディレクトリを指定します。

8行目:AccountID YOUR_ACCOUNT_ID_HERE
9行目:LicenseKey YOUR_LICENSE_KEY_HERE
18行目:DatabaseDirectory /opt/homebrew/var/GeoIP

アカウントIDはログイン後に右上の[My Account]のプルダウンで確認できます。またライセンスキーは下のURLから確認できます。

https://www.maxmind.com/en/accounts/current/license-key

また、下のURLからGeoIP.confのサンプル使うこともできます。アカウントIDが既に入力されている状態です。

https://www.maxmind.com/en/accounts/current/license-key/GeoIP.conf

geoipupdateでアップデートする

-vをつけてgeoipupdateコマンドでアップデートしてみましょう。


geoipupdate -v

最後に

最後まで読んでいただきありがとうございます。今回の【Python】GeoLite2でIPアドレスから国を確認するはいかがでしたでしょうか。無料のGeoLite2を使ってPythonでIPアドレスから国を確認する方法を紹介しました。凄い勢いでアタックをするIPアドレスをgrepしてxargsで今回のプログラムに引数で渡すとdenyできて良いと思います。

MacやLinux、Pythonなど技術系のkindle本も豊富にあります。詳しくはこちらから。

Amazonの電子書籍読み放題サービス「Kindle Unlimited」でプライム会員を対象に、最初の3か月間を無料体験できるキャンペーンを実施中。マンガ、小説、ビジネス書、雑誌など500万冊から、好きな本を何冊でも読めるキャンペーンです。

初めてkindle unlimited 読み放題をご利用の方は30日間の無料で体験できます。
期間終了後は月額980円で、いつでもキャンセルできます。
200万冊以上が読み放題。お好きな端末で利用可能です。

定番おすすめ記事

カテゴリー:
関連記事