Linux/Apache/アクセスログの数や国を見る~国変換ツール

IPアドレスが管理されている国を割り出すツール(2017-02-23、更新:2019-03-20)


APNICなどで管理しているIPアドレス表から、
該当アドレスがどの国に割り当てられているか分かります。

分かります、といっても英語二文字です。
(ISO 3166-1 Alpha-2 、で決められているんですって)
うん、JPくらいしか分からない。あと、EU?

という訳で、その辺も踏まえた変換スクリプトは以下になります。
前提となる「list.txt」の作り方は、こちら をご覧ください。
要りません、割り当てファイルだけ事前にダウンロードして、./rir_listディレクトリに置きます。

使い方はこんな感じ

# ./convert.pl JP
# ./convert.pl 1.1.64.128
# ./convert.pl /var/log/access_log

スクリプトはこちら


#!/usr/bin/perl -w

# 現状はIPv4だけで足りそうなので、
# v6は必要になったら考えます

my %ip_range;
my %ip_cntry;
my %ip_subnt;

my %iso3166;
load_iso();
# 英語二文字の国名変換
if($ARGV[0] =~ /^\w\w$/){
   printf("%s is [ %s ]\n",
       $ARGV[0],
       (defined $iso3166{$ARGV[0]}) ? $iso3166{$ARGV[0]} : "?"
   );
   exit;
}
 
# まず、割り当て一覧を読み込む
# このツールと同じ場所に rir_listディレクトリを作って
# 以下のファイルを一式置いておく
# ftp://ftp.arin.net/pub/stats/arin/delegated-arin-extended-latest
# ftp://ftp.ripe.net/pub/stats/ripencc/delegated-ripencc-extended-latest
# ftp://ftp.apnic.net/pub/stats/apnic/delegated-apnic-extended-latest
# ftp://ftp.lacnic.net/pub/stats/lacnic/delegated-lacnic-extended-latest
# ftp://ftp.afrinic.net/pub/stats/afrinic/delegated-afrinic-extended-latest
use File::Basename;
my $base_dir = dirname(__FILE__) .  "/rir_list/";
@rir_lists = (
$base_dir . "delegated-afrinic-extended-latest",
$base_dir . "delegated-apnic-extended-latest",
$base_dir . "delegated-arin-extended-latest",
$base_dir . "delegated-lacnic-extended-latest",
$base_dir . "delegated-ripencc-extended-latest"
);
 
foreach my $r_list (@rir_lists){
  open($list, "< $r_list") or die "$! [r_list]\n";
  while(<$list>){
    # 上記の、こんな感じのファイルを読みたい
    #  apnic|JP|ipv4|1.0.16.0|4096|20110412|allocated|A92D9378
    if(/^[^\|]+\|(\w+)\|ipv4\|([\d\.]+)\|(\d+)\|/){
      $ip=$2; $num=$3; $cnt=$1;
      if($ip =~ /(\d+)\.(\d+)\.(\d+)\.(\d+)/){
          $bin=$1*256*256*256
          +$2*256*256
          +$3*256
          +$4; # IP表記から数値に戻す
          $ip_range{$bin} = ($bin + $num);
          $ip_cntry{$bin} = $cnt;
      }
    }
  }
}
  
# IPv4の国名変換
if($ARGV[0] =~ /(\d+)\.(\d+)\.(\d+)\.(\d+)/){
    $bin=$1*256*256*256
    +$2*256*256
    +$3*256
    +$4; # IP表記から数値に戻す
    while(my ($start, $end) = each(%ip_range)){
        if($start <= $bin && $bin <= $end){
            printf("%s is %s [ %s ]\n",
                $ARGV[0],
                $ip_cntry{$start},
                (defined $iso3166{$ip_cntry{$start}}) ? $iso3166{$ip_cntry{$start}} : "?"
                );
            exit;
        }
    }
    printf("%s is not found.\n", $ARGV[0]);
    exit;
}

# 次にアクセスログを読み込みつつ
# IPv4 アドレス部 を 国名に変換する
my $file;
if($ARGV[0] eq '-') { $file = 'STDIN';}
else{ open($file, "< $ARGV[0]") or die "$! [$ARGV[0]]\n";}

while(<$file>){
    my $hit = 0;
    if(/^(.*[ \[\(:])(\d\d?\d?\.\d\d?\d?\.\d\d?\d?+\.\d\d?\d?+)([ \]\)].*)$/){
        # アクセスログの書式に合わせて if 文内の正規表現を調整
        # 上記の例だと、11.22.33.44 とか [11.22.33.44] が出てきたら無節操に変換を試みる
        $pre=$1; $ip=$2; $suf=$3;
        if($ip =~ /(\d+)\.(\d+)\.(\d+)\.(\d+)/){
            $bin=$1*256*256*256
            +$2*256*256
            +$3*256
            +$4; # IP表記から数値に戻す

            foreach my $start (keys(%ip_range)){
                if($start <= $bin && $bin <= $ip_range{$start}){
                    printf("%s%s[%s]%s\n",
                            $pre,
                            $ip,
                            $ip_cntry{$start},
                            $suf );
                    $hit++;
                    last;
                }
            }
        }
    }
    if(! $hit){
        # 変換できない場合はそのまま出力
        print $_;
    }
}

sub load_iso {
$iso3166{AD}="アンドラ Andorra 西ヨーロッパ";
$iso3166{AE}="アラブ首長国連邦 United Arab Emirates 中東";
$iso3166{AF}="アフガニスタン Afghanistan 中東";
$iso3166{AG}="アンティグア・バーブーダ Antigua and Barbuda 中央アメリカ";
$iso3166{AI}="アンギラ Anguilla 中央アメリカ";
$iso3166{AL}="アルバニア Albania 東ヨーロッパ";
$iso3166{AM}="アルメニア Armenia 東ヨーロッパ";
$iso3166{AO}="アンゴラ Angola 南アフリカ";
$iso3166{AQ}="南極 Antarctica 南極";
$iso3166{AR}="アルゼンチン Argentina 南アメリカ";
$iso3166{AS}="アメリカ領サモア American Samoa オセアニア";
$iso3166{AT}="オーストリア Austria 東ヨーロッパ";
$iso3166{AU}="オーストラリア Australia オセアニア";
$iso3166{AW}="アルバ Aruba 中央アメリカ";
$iso3166{AX}="オーランド諸島 Aland Islands 北ヨーロッパ";
$iso3166{AZ}="アゼルバイジャン Azerbaijan 東ヨーロッパ";
$iso3166{BA}="ボスニア・ヘルツェゴビナ Bosnia and Herzegovina 東ヨーロッパ";
$iso3166{BB}="バルバドス Barbados 中央アメリカ";
$iso3166{BD}="バングラデシュ Bangladesh 南アジア";
$iso3166{BE}="ベルギー Belgium 西ヨーロッパ";
$iso3166{BF}="ブルキナファソ Burkina Faso 西アフリカ";
$iso3166{BG}="ブルガリア Bulgaria 東ヨーロッパ";
$iso3166{BH}="バーレーン Bahrain 中東";
$iso3166{BI}="ブルンジ Burundi 中央アフリカ";
$iso3166{BJ}="ベナン Benin 西アフリカ";
$iso3166{BL}="サン・バルテルミー Saint Barthelemy 中央アメリカ";
$iso3166{BM}="バミューダ Bermuda 中央アメリカ";
$iso3166{BN}="ブルネイ・ダルサラーム Brunei Darussalam 東南アジア";
$iso3166{BO}="ボリビア多民族国 Bolivia, Plurinational State of 南アメリカ";
$iso3166{BQ}="ボネール、シント・ユースタティウスおよびサバ Bonaire, Saint Eustatius and Saba 中央アメリカ";
$iso3166{BR}="ブラジル Brazil 南アメリカ";
$iso3166{BS}="バハマ Bahamas 中央アメリカ";
$iso3166{BT}="ブータン Bhutan 南アジア";
$iso3166{BV}="ブーベ島 Bouvet Island 南極";
$iso3166{BW}="ボツワナ Botswana 南アフリカ";
$iso3166{BY}="ベラルーシ Belarus 東ヨーロッパ";
$iso3166{BZ}="ベリーズ Belize 中央アメリカ";
$iso3166{CA}="カナダ Canada 北アメリカ";
$iso3166{CC}="ココス(キーリング)諸島 Cocos (Keeling) Islands インド洋地域";
$iso3166{CD}="コンゴ民主共和国 Congo, the Democratic Republic of the 中央アフリカ";
$iso3166{CF}="中央アフリカ共和国 Central African Republic 中央アフリカ";
$iso3166{CG}="コンゴ共和国 Congo 中央アフリカ";
$iso3166{CH}="スイス Switzerland 西ヨーロッパ";
$iso3166{CI}="コートジボワール Cote d'Ivoire 西アフリカ";
$iso3166{CK}="クック諸島 Cook Islands オセアニア";
$iso3166{CL}="チリ Chile 南アメリカ";
$iso3166{CM}="カメルーン Cameroon 中央アフリカ";
$iso3166{CN}="中華人民共和国 China 東アジア";
$iso3166{CO}="コロンビア Colombia 南アメリカ";
$iso3166{CR}="コスタリカ Costa Rica 中央アメリカ";
$iso3166{CU}="キューバ Cuba 中央アメリカ";
$iso3166{CV}="カーボベルデ Cape Verde 西アフリカ";
$iso3166{CW}="キュラソー Curacao 中央アメリカ";
$iso3166{CX}="クリスマス島 Christmas Island オセアニア";
$iso3166{CY}="キプロス Cyprus 地中海地域";
$iso3166{CZ}="チェコ Czechia 東ヨーロッパ";
$iso3166{DE}="ドイツ Germany 西ヨーロッパ";
$iso3166{DJ}="ジブチ Djibouti 東アフリカ";
$iso3166{DK}="デンマーク Denmark 北ヨーロッパ";
$iso3166{DM}="ドミニカ国 Dominica 中央アメリカ";
$iso3166{DO}="ドミニカ共和国 Dominican Republic 中央アメリカ";
$iso3166{DZ}="アルジェリア Algeria 北アフリカ";
$iso3166{EC}="エクアドル Ecuador 南アメリカ";
$iso3166{EE}="エストニア Estonia 東ヨーロッパ";
$iso3166{EG}="エジプト Egypt 北アフリカ";
$iso3166{EH}="西サハラ Western Sahara 西アフリカ";
$iso3166{ER}="エリトリア Eritrea 東アフリカ";
$iso3166{ES}="スペイン Spain 西ヨーロッパ";
$iso3166{ET}="エチオピア Ethiopia 東アフリカ";
$iso3166{FI}="フィンランド Finland 北ヨーロッパ";
$iso3166{FJ}="フィジー Fiji オセアニア";
$iso3166{FK}="フォークランド(マルビナス)諸島 Falkland Islands (Malvinas) 南アメリカ";
$iso3166{FM}="ミクロネシア連邦 Micronesia, Federated States of オセアニア";
$iso3166{FO}="フェロー諸島 Faroe Islands 北ヨーロッパ";
$iso3166{FR}="フランス France 西ヨーロッパ";
$iso3166{GA}="ガボン Gabon 中央アフリカ";
$iso3166{GB}="イギリス United Kingdom 西ヨーロッパ";
$iso3166{GD}="グレナダ Grenada 中央アメリカ";
$iso3166{GE}="ジョージア Georgia 東ヨーロッパ";
$iso3166{GF}="フランス領ギアナ French Guiana 南アメリカ";
$iso3166{GG}="ガーンジー Guernsey 西ヨーロッパ";
$iso3166{GH}="ガーナ Ghana 西アフリカ";
$iso3166{GI}="ジブラルタル Gibraltar 西ヨーロッパ";
$iso3166{GL}="グリーンランド Greenland 北ヨーロッパ";
$iso3166{GM}="ガンビア Gambia 西アフリカ";
$iso3166{GN}="ギニア Guinea 西アフリカ";
$iso3166{GP}="グアドループ Guadeloupe 中央アメリカ";
$iso3166{GQ}="赤道ギニア Equatorial Guinea 中央アフリカ";
$iso3166{GR}="ギリシャ Greece 西ヨーロッパ";
$iso3166{GS}="サウスジョージア・サウスサンドウィッチ諸島 South Georgia and the South Sandwich Islands 南アメリカ";
$iso3166{GT}="グアテマラ Guatemala 中央アメリカ";
$iso3166{GU}="グアム Guam オセアニア";
$iso3166{GW}="ギニアビサウ Guinea-Bissau 西アフリカ";
$iso3166{GY}="ガイアナ Guyana 南アメリカ";
$iso3166{HK}="香港 Hong Kong 東アジア";
$iso3166{HM}="ハード島とマクドナルド諸島 Heard Island and McDonald Islands インド洋地域";
$iso3166{HN}="ホンジュラス Honduras 中央アメリカ";
$iso3166{HR}="クロアチア Croatia 東ヨーロッパ";
$iso3166{HT}="ハイチ Haiti 中央アメリカ";
$iso3166{HU}="ハンガリー Hungary 東ヨーロッパ";
$iso3166{ID}="インドネシア Indonesia 東南アジア";
$iso3166{IE}="アイルランド Ireland 西ヨーロッパ";
$iso3166{IL}="イスラエル Israel 中東";
$iso3166{IM}="マン島 Isle of Man 西ヨーロッパ";
$iso3166{IN}="インド India 南アジア";
$iso3166{IO}="イギリス領インド洋地域 British Indian Ocean Territory インド洋地域";
$iso3166{IQ}="イラク Iraq 中東";
$iso3166{IR}="イラン・イスラム共和国 Iran, Islamic Republic of 中東";
$iso3166{IS}="アイスランド Iceland 北ヨーロッパ";
$iso3166{IT}="イタリア Italy 西ヨーロッパ";
$iso3166{JE}="ジャージー Jersey 西ヨーロッパ";
$iso3166{JM}="ジャマイカ Jamaica 中央アメリカ";
$iso3166{JO}="ヨルダン Jordan 中東";
$iso3166{JP}="日本 Japan 東アジア";
$iso3166{KE}="ケニア Kenya 東アフリカ";
$iso3166{KG}="キルギス Kyrgyzstan 中央アジア";
$iso3166{KH}="カンボジア Cambodia 東南アジア";
$iso3166{KI}="キリバス Kiribati オセアニア";
$iso3166{KM}="コモロ Comoros インド洋地域";
$iso3166{KN}="セントクリストファー・ネイビス Saint Kitts and Nevis 中央アメリカ";
$iso3166{KP}="朝鮮民主主義人民共和国 Korea, Democratic People's Republic of 東アジア";
$iso3166{KR}="大韓民国 Korea, Republic of 東アジア";
$iso3166{KW}="クウェート Kuwait 中東";
$iso3166{KY}="ケイマン諸島 Cayman Islands 中央アメリカ";
$iso3166{KZ}="カザフスタン Kazakhstan 中央アジア";
$iso3166{LA}="ラオス人民民主共和国 Lao People's Democratic Republic 東南アジア";
$iso3166{LB}="レバノン Lebanon 中東";
$iso3166{LC}="セントルシア Saint Lucia 中央アメリカ";
$iso3166{LI}="リヒテンシュタイン Liechtenstein 西ヨーロッパ";
$iso3166{LK}="スリランカ Sri Lanka 南アジア";
$iso3166{LR}="リベリア Liberia 西アフリカ";
$iso3166{LS}="レソト Lesotho 南アフリカ";
$iso3166{LT}="リトアニア Lithuania 東ヨーロッパ";
$iso3166{LU}="ルクセンブルク Luxembourg 西ヨーロッパ";
$iso3166{LV}="ラトビア Latvia 東ヨーロッパ";
$iso3166{LY}="リビア Libya 北アフリカ";
$iso3166{MA}="モロッコ Morocco 北アフリカ";
$iso3166{MC}="モナコ Monaco 西ヨーロッパ";
$iso3166{MD}="モルドバ共和国 Moldova, Republic of 東ヨーロッパ";
$iso3166{ME}="モンテネグロ Montenegro 東ヨーロッパ";
$iso3166{MF}="サン・マルタン(フランス領) Saint Martin (French part) 中央アメリカ";
$iso3166{MG}="マダガスカル Madagascar インド洋地域";
$iso3166{MH}="マーシャル諸島 Marshall Islands オセアニア";
$iso3166{MK}="マケドニア旧ユーゴスラビア共和国 Macedonia, the former Yugoslav Republic of 東ヨーロッパ";
$iso3166{ML}="マリ Mali 西アフリカ";
$iso3166{MM}="ミャンマー Myanmar 東南アジア";
$iso3166{MN}="モンゴル Mongolia 東アジア";
$iso3166{MO}="マカオ Macau 東アジア";
$iso3166{MP}="北マリアナ諸島 Northern Mariana Islands オセアニア";
$iso3166{MQ}="マルティニーク Martinique 中央アメリカ";
$iso3166{MR}="モーリタニア Mauritania 西アフリカ";
$iso3166{MS}="モントセラト Montserrat 中央アメリカ";
$iso3166{MT}="マルタ Malta 地中海地域";
$iso3166{MU}="モーリシャス Mauritius 南アフリカ";
$iso3166{MV}="モルディブ Maldives インド洋地域";
$iso3166{MW}="マラウイ Malawi 南アフリカ";
$iso3166{MX}="メキシコ Mexico 中央アメリカ";
$iso3166{MY}="マレーシア Malaysia 東南アジア";
$iso3166{MZ}="モザンビーク Mozambique 南アフリカ";
$iso3166{NA}="ナミビア Namibia 南アフリカ";
$iso3166{NC}="ニューカレドニア New Caledonia オセアニア";
$iso3166{NE}="ニジェール Niger 中央アフリカ";
$iso3166{NF}="ノーフォーク島 Norfolk Island オセアニア";
$iso3166{NG}="ナイジェリア Nigeria 中央アフリカ";
$iso3166{NI}="ニカラグア Nicaragua 中央アメリカ";
$iso3166{NL}="オランダ Netherlands 西ヨーロッパ";
$iso3166{NO}="ノルウェー Norway 北ヨーロッパ";
$iso3166{NP}="ネパール Nepal 南アジア";
$iso3166{NR}="ナウル Nauru オセアニア";
$iso3166{NU}="ニウエ Niue オセアニア";
$iso3166{NZ}="ニュージーランド New Zealand オセアニア";
$iso3166{OM}="オマーン Oman 中東";
$iso3166{PA}="パナマ Panama 中央アメリカ";
$iso3166{PE}="ペルー Peru 南アメリカ";
$iso3166{PF}="フランス領ポリネシア French Polynesia オセアニア";
$iso3166{PG}="パプアニューギニア Papua New Guinea オセアニア";
$iso3166{PH}="フィリピン Philippines 東南アジア";
$iso3166{PK}="パキスタン Pakistan 南アジア";
$iso3166{PL}="ポーランド Poland 東ヨーロッパ";
$iso3166{PM}="サンピエール島・ミクロン島 Saint Pierre and Miquelon 北アメリカ";
$iso3166{PN}="ピトケアン Pitcairn オセアニア";
$iso3166{PR}="プエルトリコ Puerto Rico 中央アメリカ";
$iso3166{PS}="パレスチナ Palestinian Territory, Occupied 中東";
$iso3166{PT}="ポルトガル Portugal 西ヨーロッパ";
$iso3166{PW}="パラオ Palau オセアニア";
$iso3166{PY}="パラグアイ Paraguay 南アメリカ";
$iso3166{QA}="カタール Qatar 中東";
$iso3166{RE}="レユニオン Reunion インド洋地域";
$iso3166{RO}="ルーマニア Romania 東ヨーロッパ";
$iso3166{RS}="セルビア Serbia 東ヨーロッパ";
$iso3166{RU}="ロシア連邦 Russian Federation ロシア";
$iso3166{RW}="ルワンダ Rwanda 中央アフリカ";
$iso3166{SA}="サウジアラビア Saudi Arabia 中東";
$iso3166{SB}="ソロモン諸島 Solomon Islands オセアニア";
$iso3166{SC}="セーシェル Seychelles インド洋地域";
$iso3166{SD}="スーダン Sudan 東アフリカ";
$iso3166{SE}="スウェーデン Sweden 北ヨーロッパ";
$iso3166{SG}="シンガポール Singapore 東南アジア";
$iso3166{SH}="セントヘレナ・アセンションおよびトリスタンダクーニャ Saint Helena, Ascension and Tristan da Cunha 西アフリカ";
$iso3166{SI}="スロベニア Slovenia 東ヨーロッパ";
$iso3166{SJ}="スヴァールバル諸島およびヤンマイエン島 Svalbard and Jan Mayen 北ヨーロッパ";
$iso3166{SK}="スロバキア Slovakia 東ヨーロッパ";
$iso3166{SL}="シエラレオネ Sierra Leone 西アフリカ";
$iso3166{SM}="サンマリノ San Marino 西ヨーロッパ";
$iso3166{SN}="セネガル Senegal 西アフリカ";
$iso3166{SO}="ソマリア Somalia 東アフリカ";
$iso3166{SR}="スリナム Suriname 南アメリカ";
$iso3166{SS}="南スーダン South Sudan 東アフリカ";
$iso3166{ST}="サントメ・プリンシペ Sao Tome and Principe 中央アフリカ";
$iso3166{SV}="エルサルバドル El Salvador 中央アメリカ";
$iso3166{SX}="シント・マールテン(オランダ領) Sint Maarten (Dutch part) 中央アメリカ";
$iso3166{SY}="シリア・アラブ共和国 Syrian Arab Republic 中東";
$iso3166{SZ}="スワジランド Swaziland 南アフリカ";
$iso3166{TC}="タークス・カイコス諸島 Turks and Caicos Islands 中央アメリカ";
$iso3166{TD}="チャド Chad 中央アフリカ";
$iso3166{TF}="of the French Southern and Antarctic Lands.svg フランス領南方・南極地域 French Southern Territories インド洋地域";
$iso3166{TG}="トーゴ Togo 西アフリカ";
$iso3166{TH}="タイ Thailand 東南アジア";
$iso3166{TJ}="タジキスタン Tajikistan 中央アジア";
$iso3166{TK}="トケラウ Tokelau オセアニア";
$iso3166{TL}="東ティモール Timor-Leste 東南アジア";
$iso3166{TM}="トルクメニスタン Turkmenistan 中央アジア";
$iso3166{TN}="チュニジア Tunisia 北アフリカ";
$iso3166{TO}="トンガ Tonga オセアニア";
$iso3166{TR}="トルコ Turkey 中東";
$iso3166{TT}="トリニダード・トバゴ Trinidad and Tobago 中央アメリカ";
$iso3166{TV}="ツバル Tuvalu オセアニア";
$iso3166{TW}="台湾 Taiwan, Province of China 東アジア";
$iso3166{TZ}="タンザニア Tanzania, United Republic of 東アフリカ";
$iso3166{UA}="ウクライナ Ukraine 東ヨーロッパ";
$iso3166{UG}="ウガンダ Uganda 中央アフリカ";
$iso3166{UM}="合衆国領有小離島 United States Minor Outlying Islands オセアニア";
$iso3166{US}="アメリカ合衆国 United States 北アメリカ";
$iso3166{UY}="ウルグアイ Uruguay 南アメリカ";
$iso3166{UZ}="ウズベキスタン Uzbekistan 中央アジア";
$iso3166{VA}="バチカン市国 Holy See (Vatican City State) 西ヨーロッパ";
$iso3166{VC}="セントビンセントおよびグレナディーン諸島 Saint Vincent and the Grenadines 中央アメリカ";
$iso3166{VE}="ベネズエラ・ボリバル共和国 Venezuela, Bolivarian Republic of 南アメリカ";
$iso3166{VG}="イギリス領ヴァージン諸島 Virgin Islands, British 中央アメリカ";
$iso3166{VI}="アメリカ領ヴァージン諸島 Virgin Islands, U.S. 中央アメリカ";
$iso3166{VN}="ベトナム Viet Nam 東南アジア";
$iso3166{VU}="バヌアツ Vanuatu オセアニア";
$iso3166{WF}="ウォリス・フツナ Wallis and Futuna オセアニア";
$iso3166{WS}="サモア Samoa オセアニア";
$iso3166{YE}="イエメン Yemen 中東";
$iso3166{YT}="マヨット Mayotte インド洋地域";
$iso3166{ZA}="南アフリカ South Africa 南アフリカ";
$iso3166{ZM}="ザンビア Zambia 南アフリカ";
$iso3166{ZW}="ジンバブエ Zimbabwe 南アフリカ";
$iso3166{EU}="European Union!";
}