ASNとは
ひとつの組織や管理者の方針でまとめられている大きなネットワークのまとまりのこと。ISPや大企業のネットワークなどをASといい、独自のルーティングポリシーを持つ。
IANA経由で地域インターネットレジストリが重複しないように割り当てる。BGP (Border Gateway Protocol) はインターネットの経路情報をやり取りするプロトコル。
OONIでの実装
OONI Probeが/api/v1/check-inを呼び出すと、API内でprobe_geoip関数が呼ばれる。Probeは自分で GeoIP を行い、その結果を JSON に入れて送ってきます。
ただし、Probe は VPN や回避ツール経由で動作している可能性がある。その場合、probe が認識している IP と、サーバーから見える IP が異なることがある。Probe が VPN/Tor を使っていたら、サーバーは「VPN出口ノードのIP」を見るが、Probe は「自分の実際のネットワーク(ローカルISP)」を見ている。Probe が "ZZ" や "AS0"(不明)ならサーバー側で補完し、具体的な値を送っているならそのまま使う。
Don’t override probe_cc or asn unless the probe has omitted these # values. This is done because the IP address we see might not match the # actual probe ipaddr in cases in which a circumvention tool is being used. # TODO: eventually we should have the probe signal to the backend that it # wants the lookup to be done by the backend and have it pass the public IP # through a specific header.
extract_probe_ipaddr()でプローブのIPアドレスを取得lookup_probe_cc()で国コードを取得lookup_probe_network()でASNとネットワーク名を取得
結果はAS{番号}形式のASNと組織名としてreturnされる。新しいマイクロサービスではfast APIの@repeat_everyデコレータを使用して1時間ごとにGeoIPデータベースの更新をチェックしている。
backend/ooniapi/services/ooniprobe/src/ooniprobe/main.py at d943f03f829aad7e07f6bce92a8d5a6e56d68470 · ooni/backend · GitHub
- 現在の月のタイムスタンプを生成
- DB-IPのURLを構築(ASNとCC用)
is_already_updated()で既に更新済みかチェック download_geoip.py:138-140is_latest_available()で最新データの可用性をチェック download_geoip.py:142-144- 必要に応じて
update_geoip()を呼び出してダウンロードと更新を実行 download_geoip.py:146
ダウンロードされたasn_urlとcc_urlのデータはdb-ip.comからダウンロードされ、/var/lib/ooniapi/ディレクトリに保存される。結果はMaxMind互換形式のファイルとして保存される。
asn.mmdb: ASN情報用cc.mmdb: 国コード情報用
ooniapi/services/ooniprobe/src/ooniprobe/dependencies.pyで、geoip2を使って依存を表現している。
def get_cc_reader(settings: SettingsDep):
db_path = Path(settings.geoip_db_dir, "cc.mmdb")
return geoip2.database.Reader(db_path)
CCReaderDep = Annotated[geoip2.database.Reader, Depends(get_cc_reader)]
def get_asn_reader(settings: SettingsDep):
db_path = Path(settings.geoip_db_dir, "asn.mmdb")
return geoip2.database.Reader(db_path)
ASNReaderDep = Annotated[geoip2.database.Reader, Depends(get_asn_reader)]