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.

backend/api/ooniapi/probe_services.py at d943f03f829aad7e07f6bce92a8d5a6e56d68470 · ooni/backend · GitHub

  1. extract_probe_ipaddr()でプローブのIPアドレスを取得
  2. lookup_probe_cc()で国コードを取得
  3. 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

  1. 現在の月のタイムスタンプを生成
  2. DB-IPのURLを構築(ASNとCC用)
  3. is_already_updated()で既に更新済みかチェック download_geoip.py:138-140
  4. is_latest_available()で最新データの可用性をチェック download_geoip.py:142-144
  5. 必要に応じて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)]