Tech Racho エンジニアの「?」を「!」に。
  • インフラ

IPアドレスから地域特定するGeoIP系技術について調べてみた(追記あり)

morimorihogeです。昔は夏ってもっと仕事なくて暇だった気がするんですが、ここ数年徐々に忙しくなっていてまったりできてない💦

はてブでこんな記事が上がっていて、IPアドレスからの地域特定サービスについて具体的にどうなのよ?と思ったので調べてみた結果をまとめてみます。

NURO光最大のデメリットとサポート対応の悪さが上限知らずでどうにもならない

なお、GeoIPという用語について、世間では狭義のGeoIPはMaxMind社のサービスを指しますが、広義のGeoIP系技術はIPアドレスから地域を推定する技術やサービス一般を指すと捉え、本記事では広義のGeoIPの視点から解説します(狭義のGeoIPを示す場合、現行サービス名のGeoIP2やGeoLite2の名称を使います)。

※記事公開後、NURO光の問題の割当IPアドレスと思しきものが分かったため追記しています

前提知識

そもそもNURO光のサポートがどうかとかは僕の預かり知らない技術的興味の範囲外なので、ここでは気にせず、純粋に

元海外IPを割り振られて大手動画配信サイトや子供のゲームなどいろいろなサービスを利用できなくなってしまいました

という点にのみ絞ってfocusします。

世の中では一般的にIPアドレスから接続元地域(国やより詳しい情報)を特定する方式を広くGeoIPという言葉で使っているように思いますが、実際にはユーザーのアクセス元地域を想定する方法にはいくつかのやり方が考えられます。
※僕の知識範囲で調べたものなので、他にもあればぜひ教えて下さい

GeoIP2等の外部データベースを活用する方式(辞書方式)

前提として、狭義のGeoIPという固有名詞はMaxMind社の提供するサービスのことを指しており、一企業の提供するデータベースを利用します。
元々はGeoIPが広く利用されていましたが、今はGeoIPはサービス提供終了(2019年1月)し、GeoIP2に移行しているようです。

MaxMind社はGeoIP2のサービスを提供しており、無償版のGeoLite2と有償版のGeoIP2があります。恐らく世間一般で流通しているOSSライブラリのほとんどが無償版のGeoLite2を利用していると思います
GeoLite2とGeoIP2の違いは有償・無償、データの細かさ、サポートの有無、ライセンスにあるようです。この辺り細かく知りたい人は公式を参照して下さい。


GeoIP2(有償版)の機能表 ※最新情報はリンク先の公式サイトを確認して下さい

MaxMind: What is the difference between GeoIP2 and GeoLite2 databases?

少なくともGeoLite2はMaxMind社から圧縮ファイル形式でデータベースが提供されており、利用者はこのデータベースファイルをサーバー側にダウンロードしてアクセス元IPで検索することにより、どの地域からのアクセスかを調べることができます。

GeoLite2ではCity、Country、ASN(AS番号)の3種類のデータベースが提供されており、アクセス制限などで国レベルの粒度が必要な場合にはCountryを使っているのではないかと思われます。
一方で、アクセス解析などの用途でより細かい地域情報がほしければCityを使っているところもあるでしょう。

GeoLite2 Free Downloadable Databases

この方法のメリットは、タイトルに「辞書方式」とあるように、予めダウンロードしたデータベースを利用できるので、高速にIPアドレスから場所情報の解決が可能な点と、国(Country)・市区町村(City)粒度の情報が得られる点になります。
特に、Webサービスでは高い応答性を求められるため、前もってデータベースをダウンロードできるGeoIP2(GeoLite2)が広く利用されるのは順当と言えます。

一方で、MaxMind社はあくまで一企業であるため、企業買収やサービス方針の変更によりサービス停止や仕様変更、対応サポートの恣意的な運用の可能性があります。
MaxMind社は公式にIPアドレスと地域の紐付けを申請するフォームを用意していますが、こちらで申請した情報がどのような過程を経てGeoIP2(GeoLite2)に反映されるのかは恐らく企業秘密です。

Submit a GeoIP data correction request

また、公的機関ではなく、アメリカにあるいち企業であるため、アメリカの施策等によってサービス内容に制限がかかることもあるかもしれません。日本で利用する分には今の所気にしなくて良いとは思いますが、アメリカの敵対国家に関する情報や、アメリカ国防に関わる情報については意図的に粒度を下げられている、などの可能性は十分にあるのではないかと思います。
※このあたりは正直気にしすぎるだけ無駄だとも思いますが、可能性の一つとして頭に置いておく価値はあると思います

なお、IPアドレスから地域を特定するサービスはMaxMind社以外にもDigital Element社、IPIP.netipgeolocationなども提供しているようですので、サービス開発サイドの方でGeoIP2(GeoLite2)が使えない事情のある方は他のサービスも調べてみると良いと思います。

IANAのIP割当データベースを活用する方式(辞書方式)

ICANN(Internet Corporation for Assigned Names and Numbers)はインターネットにおけるIPアドレスやDNS名などの資源を管理している団体です。
ICANNが割当したグローバルIPアドレスの大本の割当は、IANA(Internet Assinged Number rAuthority)という部門で提供されており、IANAはグローバルIPアドレス管理の大本ですが、細かい管理については大まかな地域(アジア、とかヨーロッパレベル)別にRIR(Regional Internet Registry)と呼ばれる地域ごとの管理団体に管理を移譲しています。


IANA: Number Resourcesより引用)

日本はアジア圏ということでAPNIC(Asia Pacific Network Information Centre)に含まれており、さらにAPNICは日本のIPアドレス割当をJPNIC(日本ネットワークインフォメーションセンター)に移譲しています。冒頭にあったようなNUROのようなISPは、通常はJPNICからIPアドレス割当を受け、それを利用者に提供している、というのが実態になります。
整理すると、日本のグローバルIPアドレスは

IANA -> APNIC -> JPNIC -> 各ISP -> 企業や個人

という形で権限移譲しながら割り当てられているわけですね。

話がそれました。

さて、IPアドレスの地域解決に戻ると、IANAは全てのグローバルIPアドレスをどのRIRに割当しているかという情報を公開しています。

IANA IPv4 Address Space Registry

上記リンク先にLast Updated(執筆時点では2019-07-18でした)とある通り、グローバルIPアドレスの割当は大本のIANAレベルで最新情報を公開しているので、この情報を参照することで、RIRレベル(とても大きな地域レベル)でのざっくりとした地域を調べることが可能です。
少なくともARIN(American Registry for Internet Numbers)の管理IPであればアメリカだろう、とかRIPE NCC(RIPE Network Coordination Centre)の管理IPであればヨーロッパだろう、ということはこの情報から予測できます。

※本筋から逸れますが、なぜグローバルIPアドレスの地域割当が更新されるかについて、詳しい情報が知りたければ「IPアドレス 枯渇 再割当て」などで検索すると良いと思います

というわけで、あとはGeoIP2(GeoLite2)と同じで、データベースをダウンロードしてアクセス元IPと突き合わせをすればいいわけですね。
こちらの方法も予めデータベースをダウンロードできる辞書方式なので、高速な特定が可能ですが、RIRレベルの判別では国までは分からないため、国別のアクセス制限に使うには少々情報の粒度が荒すぎるという問題はあります。

一方で、ICANN本拠地はアメリカに存在しますが、非営利組織として組織構成や意識決定について広く公開されているためその辺りは信頼性の面で利点があるといえるとも思います。


JPNIC: ICANNの組織紹介より引用

IANAのRIRに対するアドレス割当はそもそもIPアドレスという有限のリソース割当を意識したものであり、IPアドレスからアクセス元地域を判断するために作られたものではありませんが、予測情報の一つとして使うこともできなくはない、ということになります。

IPアドレス逆引き、WHOIS情報を参照する(オンライン問い合わせ方式)

インターネットのコアを支えるサービスの一つであるDNS(Domain Name System)は、一般には「ドメイン(ホスト)名 -> IPアドレス」の名前解決を行う正引き(A及びAAAAレコード)が良く引き合いに出されますが、その逆の「IPアドレス -> ドメイン(ホスト)名」の名前解決を行う逆引き(PTR)の機能もあります。

手持ちのLinuxマシンなどがあれば、

dig -x #{調べたいIPアドレス}

で調べることもできますし、自分が今繋いでいるIPアドレスに関する情報であれば、確認君+のようなオンラインサービスでも「あなたのリモートホスト」として調べることができます。

これにより、アクセス元ユーザーのIPアドレスに逆引き(PTR)レコードが設定されていればドメイン名を調べることができるので、例えば「逆引きアドレスのドメインがJPだから、多分日本からのアクセスだろう」といった推測が可能になります。
ただし、逆引きレコードは全てのIPアドレスについて設定されているとは限らないため、この方法で確実にドメイン名を調べることができるとは限りません。

他にも、WHOIS公開データベースを用いることでもう少し詳しい情報を取得できます。

whois #{IPアドレス}

コマンドを実行することで、

※一部マスクしています
% Information related to 'aaa.bbb.ccc.ddd - www.xxx.yyy.zzz'

inetnum:        aaa.bbb.ccc.ddd - www.xxx.yyy.zzz
netname:        G-XXXXXXXX
descr:          UCOM Corporation
country:        JP
admin-c:        JP000XXXXX
tech-c:         JP000XXXXX
remarks:        This information has been partially mirrored by APNIC from
remarks:        JPNIC. To obtain more specific information, please use the
remarks:        JPNIC WHOIS Gateway at
remarks:        http://www.nic.ad.jp/en/db/whois/en-gateway.html or
remarks:        whois.nic.ad.jp for WHOIS client. (The WHOIS client
remarks:        defaults to Japanese output, use the /e switch for English
remarks:        output)
last-modified:  2011-11-22T04:28:29Z
source:         JPNIC

のように、APNIC傘下のJPNIC管理であること、日本からのアクセスであることなどを調べることが可能です。

ただし、WHOISデータベースの情報はIPアドレスの管理元によってフォーマットが異なるため地域情報が入っているとは限らないこと、WHOIS情報公開代行やbulletproof hosting(防弾ホスティング)などを使われるとどこまでの情報を信頼してよいのか分からないという問題もあり、人力で処理するならともかくプログラムで自動処理するのはやや難しいところです。

今回問題になったようなサービスはオンラインサービスのため、人力で調べることはまず不可能だったり、DNSの逆引きレコードが設定されていないケースに対応できないという問題があります。
また、サービス運営側の大きな問題として、これらのオンライン問い合わせ方式では、IPアドレスからDNS逆引き・WHOIS問い合わせといった外部サービスへの問い合わせをアクセスされるたびに実行する必要があるため、アクセス制限に用いるにはサービス応答性の面で都合が悪いという背景もあります。

そういうわけで、これらの方式は何か障害や問い合わせがあったときに後から調べるのには向いている方法ですが、オンラインサービスのアクセス制限に動的に用いるには不向きということになります。

元の問題の原因を考察してみる(あくまで推測です)

ざっとIPアドレスからのアクセス元推測方式についてまとめてみたところで、冒頭に挙げた「特定ISPのサービスで一部のサービスで海外アクセス認定されてしまう」という点について考察してみましょう。

まず大前提として、IPアドレスから地域を特定する具体的な方法はサービス提供者側に委ねられています。あるサービス事業者はGeoIP2やGeoLite2を使っているかもしれませんし、ある事業者は違うものを使っている(独自ブラックリストや別のGeoIPデータベースなど)かもしれません。
そのため、ISP(今回ではNURO光)に対して直接クレームをつけても本来の問題解決に至らない可能性があります。

一方で、ISP側で何も対策をできないのかというと、そんなこともありません。上記に挙げてきた情報で言うのであれば、

  • MaxMind社に管理IPアドレスレンジの地域情報を提供する(多分これが本命)
    • ただし、サービス事業者がGeoIP2(GeoLite2)を使っているとは限らないので、他社サービスを使っている可能性を考えると類似のGeoIP系サービス事業者にも虱潰しで当たる必要がある
    • 対応済みでした(追記参照)
  • もしRIPE NCC(ヨーロッパ圏のRIR)配下からIPアドレスを取得しているなら、JPNICのIPを取得しなおして割り当てる
    • そもそも日本国内のISPサービスでRIPE NCCのIP取って割当できるのか?という疑問はあります。この辺詳しくないので謎
    • 対応済みでした。そもそもJPNIC割当IPでした(追記参照)
  • DNS逆引きレコードをjpドメインなどの国が特定できるドメインで設定する(改善する可能性はあるが微小?)
    • 対応済みでした(追記参照)
  • WHOISデータベースで国情報を提供する(改善する可能性はある)
    • 対応済みでした(追記参照)

といった対策を行うことで、海外アクセスに誤検知される可能性を下げることができるのではないかと思います。

※2019/08/31 15:40更新:その後問題とされているIPアドレスが分かって追加調査したところ、ここで挙げたISP側での対策は全て実施済みのようでした。今回の事例ではISPであるNURO光(SO-NET)は悪くなさそうです

また、特定サービスを使いたいということだけで良ければ、サービス事業者側に直接問い合わせするというのがより近い解決策にはなりますが、企業向けのサービスであればともかく、一般個人向けのマス向けサービスでいちいち個別IPからのアクセス対応をしてくれるというのは期待薄だと思います(僕がサービス提供者側でもコスト面からお断りすると思います)。
ただ、もしサービス提供者側がGeoIP2(GeoLite2)のような公開データベースサービスを利用しているケースの場合、データベースの更新を怠っているという可能性がゼロではありませんので、同じように地域アクセス制限を実施しているサービスで「このサービスはアクセスできるのになぜ御社のサービスはアクセスできないのか?」という問い合わせを上記技術的背景を含めて相談すると、改善される可能性はあります。

なお、MaxMind社のGeoIP(GeoLite)は2019年1月という比較的最近にサービス終了しているため、サービス事業者側がGeoIP2(GeoLite2)への移行を済ませていない可能性はそれなりの確率であり得ると思います。特に、最近割当が変更されたIPアドレスを使っている場合には、2019年1月時点で更新が止まってしまっており、新しいGeoIP2(GeoLite2)データベースを参照していないことで誤検知されている可能性はありそうです。

この辺り、自分が当事者でない(割当IPアドレスもわからないので詳細を調べようがない)ため、あくまで参考情報ということで、実行及び解決するかについては各自自己責任ということでお願いいたします。
※その後IPアドレスが分かったので以降に追記として記載しました
※そもそものアクセスできない原因がGeoIP技術によるものではなく、知らない間に加入していたISPオプションサービスのコンテンツフィルタリングサービスが原因だったりなども考えられるため、安易に原因を言い切るのは無責任になるのでやりません

追記

※本記事投稿後の更新差分です

(2019/08/31 15:40更新)

NURO光は本当にヨーロッパ圏のIPアドレスを使っているのか?

Twitterを「GeoIP」でさらっと検索していたところ、興味深い情報がありました。

このTweetに貼られている内容を信頼すると、NURO光で使われていると思しき 92.202.64.0/19 には

  • nuro.jpのPTRレコードは設定されている
  • WHOISデータベースは登録している

ということがわかります。一方で、IANAの公開情報をたどると、092/8(クラスAグローバルIPネットワーク)はRIPE NCCに割り当てられており、IANA公開情報だけを見るとヨーロッパ圏に見えます

実際に92.202.64.1 に対して whoisコマンドで調べてみます(2019/08/31)時点。

$ whois 92.202.64.1
[Querying whois.arin.net]
[Redirected to whois.ripe.net]
[Querying whois.ripe.net]
[whois.ripe.net]
(略)
inetnum:        92.202.0.0 - 92.203.255.255
netname:        NON-RIPE-NCC-MANAGED-ADDRESS-BLOCK
descr:          IPv4 address block not managed by the RIPE NCC
remarks:        ------------------------------------------------------
remarks:
remarks:        For registration information,
remarks:        you can consult the following sources:
remarks:
remarks:        IANA
remarks:        http://www.iana.org/assignments/ipv4-address-space
remarks:        http://www.iana.org/assignments/iana-ipv4-special-registry
remarks:        http://www.iana.org/assignments/ipv4-recovered-address-space
remarks:
remarks:        AFRINIC (Africa)
remarks:        http://www.afrinic.net/ whois.afrinic.net
remarks:
remarks:        APNIC (Asia Pacific)
remarks:        http://www.apnic.net/ whois.apnic.net
remarks:
remarks:        ARIN (Northern America)
remarks:        http://www.arin.net/ whois.arin.net
remarks:
remarks:        LACNIC (Latin America and the Carribean)
remarks:        http://www.lacnic.net/ whois.lacnic.net
remarks:
remarks:        ------------------------------------------------------
country:        EU # Country is really world wide
admin-c:        IANA1-RIPE
tech-c:         IANA1-RIPE
status:         ALLOCATED UNSPECIFIED
mnt-by:         RIPE-NCC-HM-MNT
created:        2019-01-14T10:46:06Z
last-modified:  2019-01-14T10:46:06Z
source:         RIPE
(後ろは省略)

よく見るとNON-RIPE-NCC-MANAGED-ADDRESS-BLOCKと書かれていますね。
これは、前半部分のQuerying...の部分とも合わせて考えると、

  • IANAレベルではこのクラスAアドレス92.0.0.0/8はRIPE NCCの管轄であるとしている
  • RIPE NCCレベルでは92.202.0.0/16をさらに他のRIRに提供しているアドレスブロックである(他のIPアドレスの足りないRIRに移譲していると思われる。よくわからない人はCIDRとかで検索して下さい)

となってしまっていると考えられます。

ここで、whoisコマンドの問い合わせサーバーをAPNICにしてみると、

$ whois -h whois.apnic.net 92.202.64.1
[Querying whois.apnic.net]
[whois.apnic.net]
% [whois.apnic.net]
(略)
inetnum:        92.202.64.0 - 92.202.95.255
netname:        SO-NET
descr:          So-net Service
country:        JP
admin-c:        JP00001330
tech-c:         JP00001330
remarks:        This information has been partially mirrored by APNIC from
remarks:        JPNIC. To obtain more specific information, please use the
remarks:        JPNIC WHOIS Gateway at
remarks:        http://www.nic.ad.jp/en/db/whois/en-gateway.html or
remarks:        whois.nic.ad.jp for WHOIS client. (The WHOIS client
remarks:        defaults to Japanese output, use the /e switch for English
remarks:        output)
last-modified:  2019-01-30T04:17:02Z
source:         JPNIC

ということで、92.202.64.0/25の情報でSO-NET(NURO光のISP)情報が取得できました。

ここで厄介なのは、IANAの情報からブレークダウンしていってもRIPE NCCに行ってしまい、APNICが管理していることにたどり着けないことです。
RIPE NCCが返しているWHOIS情報を見ても「他のRIR参照してね」としか書かれていないので、最悪全てのRIRのWHOIS問い合わせをしなければならず、これはオンライン問い合わせ型のアクセス制限をしているのであればちょっと難しそうですね。

というわけで、ここで分かるのはNURO光はAPNIC -> JPNICから割り当てられた日本割当のIPアドレスを使っているが、IANAのWHOISデータベースから直接たどるのは難しいということになります。

ただ、IANA -> RIPE NCC -> APNIC -> JPNICと割当が行われているため、NURO光がヨーロッパ圏のIPアドレスを割り当てているということはありません。正確には「割と最近までヨーロッパ圏に割り当てられていたIPアドレスを利用している」が正しいです。

GeoIP2(GeoLite2)はどうなっているのか?

さらに、IPアドレスが分かったので、実際にGeoIP2(GeoLite2)を確認してみます。

yhirose/maxminddb Gemを利用させて頂き、最新のGeoLite2データベースをMaxMind社公式ページからダウンロードして実行しています。

$ irb
irb(main):001:0> require 'maxminddb'
=> true
irb(main):002:0> db = MaxMindDB.new('/tmp/GeoLite2-Country_20190827/GeoLite2-Country.mmdb')
=> #<MaxMindDB::Client: DBPath:'/tmp/GeoLite2-Country_20190827/GeoLite2-Country.mmdb'>
irb(main):003:0> ret = db.lookup('92.202.64.1')
=> #<MaxMindDB::Result:0x00005587621d3f78 @raw={"continent"=>{"code"=>"AS", "geoname_id"=>6255147, "names"=>{"de"=>"Asien", "en"=>"Asia", "es"=>"Asia", "fr"=>"Asie", "ja"=>"アジア", "pt-BR"=>"Ásia", "ru"=>"Азия", "zh-CN"=>"亚洲"}}, "country"=>{"geoname_id"=>1861060, "iso_code"=>"JP", "names"=>{"de"=>"Japan", "en"=>"Japan", "es"=>"Japón", "fr"=>"Japon", "ja"=>"日本", "pt-BR"=>"Japão", "ru"=>"Япония", "zh-CN"=>"日本"}}, "registered_country"=>{"geoname_id"=>1861060, "iso_code"=>"JP", "names"=>{"de"=>"Japan", "en"=>"Japan", "es"=>"Japón", "fr"=>"Japon", "ja"=>"日本", "pt-BR"=>"Japão", "ru"=>"Япония", "zh-CN"=>"日 本"}}, "network"=>"92.202.0.0/15"}>
irb(main):004:0> ret.country.name
=> "Japan"

というわけで、ちゃんとGeoIP2(GeoLite2)では日本と識別できていますね。

合わせて、更新の止まってしまった旧GeoIP(GeoLite)でも調べてみましょう。こちらはUbuntu公式のgeoip-bin及びgeoip-databaseパッケージを利用しました。

# geoiplookup 92.202.64.1
GeoIP Country Edition: DE, Germany

というわけで、ドイツと認識されてしまっていますね。

これらの情報から分かるのは、

  • 少なくともMaxMind社への申請は適切に行われているので、GeoIP2(GeoLite2)データベースではには日本と反映されている(NURO光(SO-NET)が申請したかどうかは知りません)
  • DNS逆引き(PTRレコード)もJPドメインが返るように設定されている
  • WHOISデータベースもRIRを総当りすればちゃんとAPNIC -> JPNICから日本であることを調べることができる

ということになります。

こうなると、疑わしいのはサービス事業者側が古い更新の止まったGeoIP(GeoLite)を利用してしまっているという状況になります。
ここまでの情報を総合すると、NURO光に問い合わせするよりはサービス事業者に問い合わせする方が良さそうですね。

グローバルIPアドレスの移転履歴を調べる

(2019/08/31 16:30更新)
はてブコメントにて id:himakao さまより、JPNICのIPアドレス移転履歴は公開情報なので確認できる旨教えていただきました。

JPNIC: IPv4アドレス移転履歴

確かに、先程調べた92.202.0.0/15が2019-01-16(GeoIP(GeoLite)のサービス終了時期)に国際移転されていることがわかります。

GeoIP技術を使った国判別という観点で見ると、JPNIC内でのIPアドレス移転については同じ日本内なので更新されなくても大事にはなりませんが、国際移転されるケースでは今回のような問題が発生するので、サービス事業者側はこうしたリスクも理解した上でGeoIP系技術を利用する必要がありそうです。

まとめ

IPアドレスからアクセス元地域を調べるGeoIP系技術について、自分の理解をさらっとまとめてみました。
ここに挙げた以外の方法や間違いがありましたらぜひTwitterにて@morimorihoge宛にご意見いただけますと幸いです。


CONTACT

TechRachoでは、パートナーシップをご検討いただける方からの
ご連絡をお待ちしております。ぜひお気軽にご意見・ご相談ください。