naoki86star

インターネットの片隅でなにかしら書いてみる

(グローバルIP, 国コード, ASN)なカスタムmaxminddbを作る

今回やってみたこと

 グローバルIPアドレス(v4のみ)からCountry-CodeとASNを参照できるカスタムmaxminddbファイルを作成する。GeoIP2LiteのASN用とCountry用を一緒にする感じ。
 clojure でgrpc接続実装が可能であることを覚えたので、これを使ってASN参照処理を書いてみた。

動機

 今年に入ってgeolite2のファイルのダウンロードの条件が厳しくなった
 以前、maxminddbファイルの自作ができることを知っていた。

 ちょっとしたきっかけで、ひとつのダウンローダブルなIPフリーデータベースを見かける。まずこれでCountry-Code(CC)のmaxminddbファイルは作成できてしまうな、そう思った。

 vultr.comのBGP接続したテーブルからprefixで参照かけてas-pathのオリジンをそのIPの所有者であるASNとみなすことでASNを参照しよう、それを利用してlite.ip2location.comのCCに加える形でASNのmaxminddbファイルを作成してみよう、という試み。

失敗した作戦

 IP2LOCATION-LITE-DB1.CSVに記されるIP-prefixを元にして、listPathでそれぞれのAsPathを参照してASNを決めようとしたこと。すなわち、CC分布を示すIPprefixからASNを参照しようとしたこと。これだとCC分布のIPprefixは総じて経路よりもネットワークマスクが短いので、より長いprefixを参照する必要があるだろうそれでいける、と思った。が、加えて一部同一ASNで国をまたいでいるケースがあって、より短いprefix参照もしてみようとしたが、ロジックがきれいにかけなかった。

作戦変更

 BGPテーブルのprefix-ASNの関係をすべて参照し、それぞれのprefixに対してIP2LOCATION-LITEから国コードを参照する。

  • フルルート持ったgobgpdからpath参照して[ [ prefix asn ] ]のリスト作成

-> AsPathAttributeの最後の要素をASNとして参照する
-> x.0.0.0/8の単位で、255回分割で listPath (/w longer)を呼び出す
-> AttomicAggregate属性のprefixは得られたASNを参照しない*1

  • IP2LOCATION-LITE-DB1.CSVからprefix範囲対国コードのリスト作成

-> prefix検索のためにprefix先頭1octetでhash-map化
-> IP2LOCATION-LITE-DB1.CSVダウンロードにはsign-upが必要

結果
  • 受信メッセージ数分(引くいくらか除外分)のレコードがmmdbファイルに格納された

メジャーなprefix/ASNを引くとおおむねあっていそう

  • 非広報のアドレスはASN不明 になる-> BGPテーブル元なのでそうなる
  • BGPテーブルはvultr.com Tokyoロケーションのbgp接続サービスのもので、悪いAsPathが入ってきたらそのprefixでは当然誤った値になってしまう

CountryCodeとASNを同時に参照することが多いのでこの自作も少しはメリットあるかもと最初思った。GeoLITE2のダウンロードのだとCountryCodeとASNのmmdbファイルが別なので2回.getを呼ぶことになる。使う場合の実装もちょびっとだけ楽になる。

vultr.comのBGP接続サービスのfullルートみていると謎なprefixデータがいくらかあるのを発見、/32 prefixとかプライベートASNがオリジンとかがある、birdcで直接参照してもそうなっている。これらは取り除いておく*2

最終的には、インターネット上で接続元としての値なりとかで実際に観測されるIPに対してはそこそこ利用できそう。

IP2Location(TM)LITEを利用してるということで、利用許諾、かかる制約条件には留意している。

今回覚えたこと
  • clojureでのblock comment の書き方(ないと思っていた)

*1:よく理解できていないけどもAggregateというからにはその先にさらに実体ASNがいると考えたAtomicAggregate、短いネットワーク長prefixに多くついている

*2:一つの推測として、private ASN接続しているからが故なのかもしれない