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

  • Last update:2020/09/01    Build:2020/08/31
  •  
    毎月apache2のログから国別のアクセス数を知りたいと思った。Perlのモジュールに 「IP::Country::Fast」があり利用できるとのこと。
    導入にはcpanというソフトがあるらしい、いろいろ調べると「@OMAKASEさん」の cpanmが使いかってが良い とのこと。(pdfはこちら)
    「カンタローCGI」さんの cpanmをインストールする色んな方法 、( pdfはこちら) を参考にさせていただいた。 この中にcurlを使ってインストールする方法があったが、うまく行かず、aptを使ってインストールした。  

    1.CPANMのインストール

    root@ubuntu:~# apt install cpanminus
    パッケージリストを読み込んでいます... 完了
    依存関係ツリーを作成しています                
    状態情報を読み取っています... 完了
    以下の追加パッケージがインストールされます:
      libcpan-distnameinfo-perl libcpan-meta-check-perl libfile-pushd-perl liblocal-lib-perl libmodule-build-perl
      libmodule-cpanfile-perl libmodule-signature-perl libparse-pmfile-perl libstring-shellquote-perl
    推奨パッケージ:
      libpod-readme-perl libsoftware-license-perl
    以下のパッケージが新たにインストールされます:
      cpanminus libcpan-distnameinfo-perl libcpan-meta-check-perl libfile-pushd-perl liblocal-lib-perl
      libmodule-build-perl libmodule-cpanfile-perl libmodule-signature-perl libparse-pmfile-perl
      libstring-shellquote-perl
    アップグレード: 0 個、新規インストール: 10 個、削除: 0 個、保留: 1 個。
    406 kB のアーカイブを取得する必要があります。
    この操作後に追加で 1,164 kB のディスク容量が消費されます。
    続行しますか? [Y/n] y
    取得:1 http://jp.archive.ubuntu.com/ubuntu bionic/universe amd64 libcpan-distnameinfo-perl all 0.12-1 [8,662 B]
    取得:2 http://jp.archive.ubuntu.com/ubuntu bionic/universe amd64 libcpan-meta-check-perl all 0.014-1 [7,594 B]
    取得:3 http://jp.archive.ubuntu.com/ubuntu bionic/universe amd64 libfile-pushd-perl all 1.014-1 [11.8 kB]
    取得:4 http://jp.archive.ubuntu.com/ubuntu bionic/universe amd64 libmodule-build-perl all 0.422400-1 [201 kB]
    取得:5 http://jp.archive.ubuntu.com/ubuntu bionic/universe amd64 liblocal-lib-perl all 2.000024-1 [46.1 kB]
    取得:6 http://jp.archive.ubuntu.com/ubuntu bionic/universe amd64 libmodule-cpanfile-perl all 1.1002-1 [23.8 kB]
    取得:7 http://jp.archive.ubuntu.com/ubuntu bionic/universe amd64 libparse-pmfile-perl all 0.41-1 [14.2 kB]
    取得:8 http://jp.archive.ubuntu.com/ubuntu bionic/universe amd64 libstring-shellquote-perl all 1.04-1 [12.0 kB]
    取得:9 http://jp.archive.ubuntu.com/ubuntu bionic/universe amd64 cpanminus all 1.7043-1 [58.0 kB]
    取得:10 http://jp.archive.ubuntu.com/ubuntu bionic/universe amd64 libmodule-signature-perl all 0.81-1 [22.9 kB]
    406 kB を 1秒 で取得しました (676 kB/s)              
    (以下略)
    
    aptを使ってroot権限でインストールしたことで、/root以下にインストールされた。 これがあとで困ったことになる。共有フォルダーに入れられないのかな??

    cpanmのバージョンを確認しました。
    nic@server:~/test$ cpanm -v
    cpanm (App::cpanminus) 1.7043 on perl 5.030000 built for x86_64-linux-gnu-thread-multi
    Work directory is /home/nic/.cpanm/work/1598750546.123902
    You have LWP 6.43
    You have /bin/tar: tar (GNU tar) 1.30
    Copyright (C) 2017 Free Software Foundation, Inc.
    License GPLv3+: GNU GPL version 3 or later .
    This is free software: you are free to change and redistribute it.
    There is NO WARRANTY, to the extent permitted by law.
    
    作者: John Gilmore, Jay Fenlason.
    Usage: cpanm [options] Module [...]
    
    Try `cpanm --help` or `man cpanm` for more options.
    

    2.「IP::Country::Fast」をインストール

    PerlのIPから国を調べるモジュール「IP::Country::Fast」をインストールする
    root@server:~# cpanm IP::Country::Fast
    --> Working on IP::Country::Fast
    Fetching http://www.cpan.org/authors/id/N/NW/NWETTERS/IP-Country-2.28.tar.gz ... OK
    Configuring IP-Country-2.28 ... OK
    ==> Found dependencies: Geography::Countries
    --> Working on Geography::Countries
    Fetching http://www.cpan.org/authors/id/A/AB/ABIGAIL/Geography-Countries-2009041301.tar.gz ... OK
    Configuring Geography-Countries-2009041301 ... OK
    ! Can't configure the distribution. You probably need to have 'make'. 
     継続行 See /root/.cpanm/work/1598752083.123970/build.log for details.
    ! Installing the dependencies failed: Module 'Geography::Countries' is not installed
    ! Bailing out the installation for IP-Country-2.28.
    


    3.「IP::Country::Fast」の所在確認

    root@server:~# perl -MIP::Country::Fast -e 1
    Can't locate IP/Country/Fast.pm in @INC (you may need to install the IP::Country::Fast module)
      継続行 (@INC contains: /etc/perl /usr/local/lib/x86_64-linux-gnu/perl/5.30.0
      継続行 /usr/local/share/perl/5.30.0 /usr/lib/x86_64-linux-gnu/perl5/5.30 
      継続行  /usr/share/perl5 /usr/lib/x86_64-linux-gnu/perl/5.30 
      継続行 /usr/share/perl/5.30 /usr/local/lib/site_perl /usr/lib/x86_64-linux-gnu/perl-base).
    BEGIN failed--compilation aborted.
    
    エラーが出た。Fast.pmがないと言っているようだ。


    4.Fast.pmを探す

    root@ubuntu-server-nic:~# find / -name Fast.pm
    /root/.cpanm/work/1598752083.123970/IP-Country-2.28/lib/IP/Country/Fast.pm
    /usr/share/perl5/CGI/Fast.pm
    
    ユーザーrootにあることがわかった。

    5.テストプログラムを実行してみる

    テストプログラムは「KSKNET」さんの IP::Country::Fast - IP割り当て国を調べる 、(pdfはこちら) にあるperlスクリプトをそのまま使わせて貰いました。スクリプトと使用例は以下のとおりです。
    [例 - countryip.pl]
    #!/usr/bin/perl
    use IP::Country::Fast;
    print "Enter the IP address: ";
    my $ip_addr = <STDIN>
    my $reg = IP::Country::Fast->new();
    print $reg->inet_atocc($ip_addr) . "\n";
    
    [使用例]
    [testuser@server testuser]$ ./countryip.pl
    Enter the IP address: 218.219.203.56
    JP
    


    実行してみました。エラーがでました。やはり「Fast.pm」が見つからないようです。
    nic@server: ~test$ ./ip-to-country.pl
    Can't locate IP/Country/Fast.pm in @INC (you may need to install the IP::Country::Fast module) 
     継続行 (@INC contains: /etc/perl /usr/local/lib/x86_64-linux-gnu/perl/5.30.0 
     継続行 /usr/local/share/perl/5.30.0 /usr/lib/x86_64-linux-gnu/perl5/5.30 
     継続行 /usr/share/perl5 /usr/lib/x86_64-linux-gnu/perl/5.30 /usr/share/perl/5.30 
     継続行 /usr/local/lib/site_perl /usr/lib/x86_64-linux-gnu/perl-base) at ./ip-to-country.pl line 3.
    BEGIN failed--compilation aborted at ./ip-to-country.pl line 3.
    

    6.libで場所を指定

    @INCの場所がわからないので、いろいろとしらべました。 「日本のPerlユーザーのためのハブサイト」さんの @INC にみる Perl のやりかたがいっぱい 、(pdfはこちら) を参考にさせて貰いました。

    修正したperlのスクリプトです。
    #!/usr/bin/perl
    use lib '/root/.cpanm/work/1598752083.123970/IP-Country-2.28/lib/'; <==ここ
    use IP::Country::Fast;
    
    print "Enter the IP address: ";
    my $ip_addr = <STDIN>
    
    my $reg = IP::Country::Fast->new();
    print $reg->inet_atocc($ip_addr) . "\n";
    
    これでうまく動きました。
    但し、場所がroot下にあるため実行する必要がある際は、 rootのパーミッションを700から755にする必要があるということです。 これが問題。 何かいい方法がないものか?

    7.連続してIPを読み国名を書き出すスクリプト

    単体ではうまくいったので、これを修正して連続して国名を調べるスクリプトを作りました。 以下のとおりです。
    (2020/9/1追記)
    修正したスクリプトは以下のとおり
    #!/usr/bin/perl
    #
    # IPアドレスから国名を調べる
    # ファイルから読み込み国名を調べファイルに書き出す
    # ip-to-country-conti-2-user.pl (ip-to-country-conti-2-user-200901-pl.txt)
    # Perl モジュール IP::Country::Fast を使う
    # 2020/8/30 OK
    # 2020/9/1 OK IP::Country::Fast モジュールをuser 下に置いた
    #
    use strict; # 宣言した変数以外を使えなくする
    #use lib '/root/.cpanm/work/1598752083.123970/IP-Country-2.28/lib/';
    use lib '/home/user/.cpanm/work/1598918143.133026/IP-Country-2.28/lib/'; <==変更#2020/9/1
    
    use IP::Country::Fast;
    
    my $data_file="/home/user/ipaddress/ipaddr.txt";
    my $out_file="/home/user/ipaddress/out_ip-and-country.txt";
    my $ip_addr ;
    my $reg;
    my $ip_line;
    
    
    my $i_count ;
    my $null="";
    
    # ##      初期値 ###
    $| = 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");  
    
      $reg = IP::Country::Fast->new();  <== whileループの外に出した
    
    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=$& ;
      }
      
    
      print OUT $i_count, " ",$ip_addr, " ",$reg->inet_atocc($ip_addr) . "\n" ;
    
    
    }
    close IN;
    close OUT;
    
    # 終了 プログラムEND
    
    以下は、2020/8/31現在、最初のスクリプトです。
    (2020/9/1追記ここまで)
    #!/usr/bin/perl
    #
    # IPアドレスから国名を調べる
    # ファイルから読み込み国名を調べファイルに書き出す
    # ip-to-country-conti.pl (ip-to-country-conti-200830-pl.txt)
    # Perl モジュール IP::Country::Fast を使う
    # 2020/8/30 OK
    #
    use strict; # 宣言した変数以外を使えなくする
    use lib '/root/.cpanm/work/1598752083.123970/IP-Country-2.28/lib/';
    
    use IP::Country::Fast;
    
    my $data_file="/home/user/ipaddress/ipaddr.txt";
    my $out_file="/home/user/ipaddress/out_ip-and-country.txt";
    my $ip_addr ;
    my $reg;
    my $ip_line;
    my $country;
    
    
    my $i_count ;
    my $null="";
    
    # ##      初期値 ###
    $| = 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=$& ;
      }
      
      $reg = IP::Country::Fast->new();
      unless ( defined $reg) {       # 未定義かどうか判定(未定義のエラーがでた)
         $reg="  ";  # 未定義であれば空白を入れる
      }
    
      print OUT $i_count, " ",$ip_addr, " ",$reg->inet_atocc($ip_addr) . "\n" ;
    
    }
    close IN;
    close OUT;
    
    # 終了 プログラムEND
    

    Apache2のログ、IPアドレスから名前を調べる     HomePage     このページのトップ