ようこそNICのホームページへ(なが〜い試運転中 from 2004年)
  • @nifty atnifty-ddns ddo.jp dip.jp   HP パソコン 健康 落語 海外 思うまま 電子工作
  • Apache2のログ、IPアドレスから名前を調べる,gethostbyaddrを使う

  • Last update:2020/08/31    Build:2020/08/03
  •  
    毎月apache2のログが吐き出される、analogで一応ログのまとめをしている  
    perlでipアドレスから名前を参照するスクリプトを作ろうと思い立った。
    ipアドレスから逆引きで名前参照するのに、最初はsystem関数を使って、nslookupを使おうと思った。 調べていくと「gethostbyaddr()」関数が使えることがわかった。これを使うことにしたが、 使い方がわからず少し苦労した。備忘録としてこのページを作成する


    1.条件や概要は以下のとおり

    2.実行した結果(一部)は以下のとおりです。

    名前が解決できたのは2447件(全体3147件)で77.7%です。
    71.9.62.205	071-009-062-205.biz.spectrum.com
    160.13.106.1	1.106.13.160.dy.iij4u.or.jp
    49.213.171.100	100-171-213-49.tinp.net.tw
    101.140.189.153	101-140-189-153f1.shg1.eonet.ne.jp
    101.140.222.224	101-140-222-224f1.osk3.eonet.ne.jp
    103.98.32.22	103.98.32.22.rev.datamaxtechnologies.net
    103.112.55.59	103-112-55-59.Chuadanga.carnival.com.bd
    103.58.100.67	103-58-100-67.biznetgiocloud.com
    105.209.43.245	105-209-43-245.access.mtnbusiness.co.za
    105.213.79.35	105-213-79-35.access.mtnbusiness.co.za
    106.104.192.43	106-104-192-43.adsl.static.seed.net.tw
    (略)
    162.243.129.158	zg-0708c-3.stretchoid.com
    222.2.78.180	ZG078180.ppp.dion.ne.jp
    37.26.236.12	zimbra.cbdd.spb.ru
    193.118.53.194	zl-ams-nl-gp3-wk101.internet-census.org
    128.14.134.170	zl-lax-us-gp3-wk106.internet-census.org
    222.8.59.55	ZM059055.ppp.dion.ne.jp
    59.135.105.138	ZV105138.ppp.dion.ne.jp
    111.102.193.97	zz20164245216F66C161.userreverse.dion.ne.jp
    
    (2020/8/5追記)
    名前がわかったのでドメインの最後の部分(.jpなど)を調べました。一覧表を載せます。全部で2447です。 その中にlocalhostが4つあり、1つはもちろんlocalhostなのですが、他の3つは ヴェトナムからのようです。ipアドレスを載せます。117.2.164.101と27.64.22.20と27.70.227.169です。 危ないですね。それから「D」というのが1つありました。意味わかりません。

    多いのはpetalbotが544,msnbotが340,crawlが130と続きます。ほとんど検索ロボットですね。 個人には見られていないということです(悲しい〜〜(^_^;))
    *.am *.arpa *.at *.au *.bd *.bg *.biz *.br
    2 3 1 3 1 4 1 35
    *.by *.ca *.ch *.cloud *.cn *.co *.com *.cz
    1 3 1 1 8 6 1302 1
    *.de *.dk *.drone *.earth *.ec *.eu *.expert *.fr
    12 1 1 1 2 12 1 1
    *.ge *.gr *.hn *.host *.hr *.hu *.id *.il
    3 7 1 3 1 1 5 2
    *.in *.info *.io *.ir *.it *.jp *.kg *.kh
    6 2 11 3 11 378 1 2
    *.lb *.lt *.mx *.net *.ninja *.nl *.org *.pl
    1 1 2 409 5 1 23 12
    *.ps *.ro *.ru *.sc *.se *.sg *.si *.site
    1 3 19 1 2 1 1 2
    *.sk *.su *.th *.tr *.tw *.ua *.uk *.uy
    1 1 2 37 35 4 3 1
    *.ve *.vn *.yt *.za *.zw D localhost
    1 28 1 2 1 1 4
    (2020/8/5追記ここまで)


    (2020/8/7追記)
    全てのIP一覧を追加記載しました。3147件です。長いページです。二種類載せました。 ドメインの右端(.jpなど) をアルファベット順に並べたものと アクセス数の 多い順に並べたものです。
    (2020/8/7追記ここまで)

    (2020/8/31追記)
    アクセス元の国別数を知りたいと思い、調べました。perlのモジュールにIP::Country::Fastと いうデータベースがあり、これでIPから国名が調べられるとのこと。導入や手こずったところは 別途ここに載せます。
    2020年7月の全アクセス数が27,439件(少ない)、うち内部からのアクセスが559件、国名が 不明なIPが414件で国名が判明したIPが26,466件です。最大はアメリカで11,546件、 次いで日本で4,945件、3番目が中国で3,706件、4番目がドイツで1,761件、5番目が EUで1,352件、上位5国(団体含)で88%を占めました。一覧表を ここに載せます。
    全体で81カ国(団体含)です。
    (2020/8/31追記ここまで)

    3.Perlで記述したスクリプト

    gethostbyaddr()関数を利用したスクリプトです。これにはpack()関数とsplit()関数も使っています。
    #!/usr/bin/perl  -w 
    #               -w ワーニングを出す
    # /home/user/ipaddress/ip-check-2.pl
    # apahe2 のログからIPアドレスからURLを調べるスクリプト
    # 2020/8/3 --->OK
    # /var/log/apache2/access.log.1をコピーして実行したところ5000行目くらいで16分位かかった。
    # 全体で28000行くらいあるので時間が非常にかかる。
    # EXCELで重複を取り除くと3100位になった。
    # これで約8分
    # 出力結果がおかしくて、gethostbyaddr の使い方を修正した(2020/8/3)
    #
    
    use strict; # 宣言した変数以外を使えなくする
    use Socket; # gethostbyaddrを使うために必要
    
    my $data_file="/home/user/ipaddress/ipaddr.txt";
    my $out_file="/home/user/ipaddress/out_file.txt";
    my $ip_addr ;
    my $ip_line;
    my $url_name="";
    
    my $i_count ;
    my $AF_INET="2" ;   # gethostbyaddrを使うために必要
    
    # ##      初期値 ###
    $| = 1;   # ゼロ以外が代入されると出力をバッファリングしなくなる。
    $i_count=0 ;
    
    # ###########################  メインプログラム  ###############################
    
    open (OUT,">$out_file"); # 新規にアウトファイルを作成
    close OUT ;
    
    open IN, "<",$data_file || die "Error: data file not existed $!\n" ; #ファイルを入力で開く
    open (OUT,">> $out_file");  
    
    while ($ip_line = <IN>) { # 記録されているIPアドレスを1行読み込む 空行でない場合、以下を実行
    
      if ( $ip_line    =~/\d+\.\d+\.\d+\.\d+/ ) { ;       # IP addressを パターンマッチ ex 192.168.0.1
         $i_count=$i_count + 1 ;
         $ip_addr=$& ;
      }
      
    #  $url_name  = gethostbyaddr($ip_addr, $AF_INET) ; # (2020/8/3 こちらが最初、結果がおかしい)
      $url_name  = gethostbyaddr(pack("C4",split(/\./,$ip_addr)), $AF_INET) ; # 修正後
      unless ( defined $url_name) {             # 未定義かどうか判定(未定義のエラーがでた)
         $url_name="  ";                        # 未定義であれば空白を入れる
      }
    
      print OUT $i_count, " ",$ip_addr, " ",$url_name,"\n" ;
    
    }
    close IN;
    close OUT;
    
    # 終了 プログラムEND
    

    4.試行錯誤したところ

    gethostbyaddr()関数の引数の使い方で少しとまどいました。 単純にIP(192.168.1.1)を入れれば良いと考えていたのですが、 文字のみを4バイトにして入れる必要があるようです。
    192→1バイト 168→1バイト 1→1バイト 1→1バイト
    これを行うのにpack()関数とsplit()関数を使いました。

    gethostbyaddr()関数の第2引数は、「2」でいいようです。 最初AF_INETなる特定文字が書いてあって少し悩みました。 「use Socket;」を使うとも記述があり、悩みました。
    参考としたページです

    電子工作へ     HomePage     このページのトップ