背景
IPアドレスというのはIANA (Internet Assigned Numbers Authority)でどうするか決められます。
まずは地域で細かく分けられ更にNIR (National Internet Registry)で地域ごとに別れます。
そこからISP (Internet Service Provider)が一般ユーザーや企業に対してIPアドレスを提供します。
IPアドレスを管理している団体によっては様々な情報が詰まっていて、それが集まっているのがMaxmindのデータベース、つまりGeoIP2のデータベースです。
今回はIPアドレスからデータベースの情報を抜き出してみるアプリを作ってみました。
作ってみる
データベースは無料で入手できますが、登録が必要です。
まずは以下からサインアップしてください。
メールアドレスにパスワード設定のメールが来るのでパスワードを設定します。
するとメニューからデータベースファイルがダウンロードできます。
使えるデータベースはこれだけありますが、
- GeoLite2 ASN
- GeoLite2 ASN: CSV Format
- GeoLite2 City
- GeoLite2 City: CSV Format
- GeoLite2 Country
- GeoLite2 Country: CSV Format
今回は以下の2つを解凍して、GeoLite2-ASN.mmdb
とGeoLite2-City.mmdb
を使います。
- GeoLite2 ASN
- GeoLite2 City
Pythonで作るとgeoipのデータベースのライブラリがあるのでそれを使います。
import geoip2.database
import gradio as gr
from fastapi import FastAPI
asn_db='./GeoLite2-ASN.mmdb'
city_db='./GeoLite2-City.mmdb'
def get_asn(ip_address:str):
with geoip2.database.Reader(asn_db) as reader:
return reader.asn(ip_address)
def get_city(ip_address:str):
with geoip2.database.Reader(city_db) as reader:
return reader.city(ip_address)
def main(ip_address):
asn=get_asn(ip_address)
city=get_city(ip_address)
return {
"AS管理組織":asn.autonomous_system_organization,
"大陸":city.continent.names['ja'],
"国":city.country.names['ja'],
"緯度":city.location.latitude,
"経度":city.location.longitude,
"精度":city.location.accuracy_radius,
"登録国":city.registered_country.names['ja'],
"細分":list(map(lambda x:x.names['ja'] or x.names['en'],city.subdivisions)),
"IPアドレス":city.traits.ip_address,
}
app = FastAPI()
io = gr.Interface(fn=main, inputs="text", outputs="json")
app = gr.mount_gradio_app(app, io, path="/")
遊んでみる
とりあえずGoogleを試してみる
まずはIPアドレスを出してから
nslookup google.com
;; communications error to 127.0.0.53#53: timed out
Server: 127.0.0.53
Address: 127.0.0.53#53
Non-authoritative answer:
Name: google.com
Address: 142.251.222.46
Name: google.com
Address: 2404:6800:4004:818::200e
返ってきたIPアドレスを両方入れてみると…?
どうやらIPv4とIPv6でサーバーが違うみたいですね
DRの観点からでしょうか
AWSのアドレスで試してみる
大阪(ap-northeast-3)リージョンのアドレス:
AWSのデータセンターの場所というのはリークされているとはいえ登録上は都庁や市役所の近くにあるのは興味深いですね
おまけ
pythonanywhereでデプロイしようとしたらだめでした。
仕方なくrenderにデプロイ。