Betternet Unlimited Free VPN Proxy

Chromeのブラウザアクセス時に、ipアドレスを変更することができるChrome Extension.
ユーザー数が100万人って、思ったより少ない気がしますが、まず入れてみましょう。

Chromeに追加したら、接続します。

うーん、なんか上手くいかないな。

Domain and IP address search

In the case of unauthorized access, it may be necessary to investigate the ip address of the request and check from where it is illegal access.

Let’s see CMAN.
https://www.cman.jp/network/support/ip.html

As the ip address is also the library of php, you can determine which continent, region request from the address.

Another ip address service.
https://www.iplocation.net/

Yes, search result was same between different services.

EIPとは?

– 企業内情報ポータルという意味でのEIP(Enterprise Information Portal)
– IPアドレスの一種であるEIP

Elastic IPという、Amazon Web Services(AWS)の文脈で用いられるEIP

Elastic IPアドレスは、AWSに登録したアカウントに紐つけされるIPアドレスです。IPアドレスは基本的にパブリックIPアドレスとプライベートIPアドレスの2つに分けることができ、パブリックIPアドレスはインターネットを通じて機器を利用する際に割り当てられるアドレス
一方のプライベートIPアドレスはインターネットではなくローカルのネットワークでのみ割り当てられるIPアドレスで、インターネットからは遮断されたIP

EC2ダッシュボードで、パブリックとプライベートのIPがありますね。
IPv4 パブリック IP
プライベート IP

Elastic IP、EIPはパブリックIPの方。なるほど。

ipアドレスに対応するホスト名を取得する

google.comのhost名をgethostbyaddrを使うと、

$url = "www.google.com";
$ip = "172.217.161.196";
$host = gethostbyaddr($ip);
echo $host;

きたー、ラリー・ページの10^100
なんか知らんが嬉しいね

www.nttdocomo.co.jp
ip:163.49.61.185
gethostbyaddr:185.61.49.163.static.iijgio.jp
え、iij使ってるの?

www.fsa.go.jp
ip:151.101.101.14
gethostbyaddr:151.101.101.14
金融庁、財務省、などはgethostbyaddrでipしか表示されない。

rakuten->deploy.static.akamaitechnologies.com
nttdata(184.27.113.234)->a184-27-113-234.deploy.static.akamaitechnologies.com
ん?どういうこと、これ?akamaitechnologiesってそんなにいいの?

gaだと、service providerは細かく表示されているので、恐らくプロバイダーのデータベースを持ってると思うんだが、、

あれ?
GeoIP ISP Edition
https://www.maxmind.com/ja/geoip2-isp-database
やっぱり。。しかしip周りの領域は、なにかとmaxmindと被るな。

service providerは、DBないとかなりキツイな~、というか関数自作は無理がある。。
ので、

$ip = "192.168.33.1";
$host = gethostbyaddr($ip);
if($host == $ip){
    $gethost = "(not set)";
} else {
    $gethost = $host;
}
echo $gethost;

よしよしよし

次は画面サイズ(screen resolution)
これはjsでいけると思います。

ipの地域をtableで表示する

getパラメーターの値で表示を切り替えます。

<table>
      <?php if($_GET&#91;"selectedDimension"&#93; == 'continent'): ?>
      <th>Continent</th><th>Users</th>
      <?php
        $i = 0;
        foreach($c1 as $key => $value){
          if($i < 10){
            echo "<tr>";
            echo "<td>".$key."</td><td>".$value."</td>";
            echo "</tr>";
          }
          $i++;    
        }
      ?>
      </table>
      <?php elseif($_GET&#91;"selectedDimension"&#93; == 'country'): ?>
      <th>Country</th><th>Users</th>
      <?php
        $i = 0;
        foreach($c2 as $key => $value){
          if($i < 10){
            echo "<tr>";
            echo "<td>".$key."</td><td>".$value."</td>";
            echo "</tr>";
          }
          $i++;    
        }
      ?>
      </table>
      <?php elseif($_GET&#91;"selectedDimension"&#93; == 'city'): ?>
      <th>City</th><th>Users</th>
      <?php
        $i = 0;
        foreach($c3 as $key => $value){
          if($i < 10){
            echo "<tr>";
            echo "<td>".$key."</td><td>".$value."</td>";
            echo "</tr>";
          }
          $i++;    
        }
      ?>
      </table>
      <?php else: ?>
      <th>Page</th><th>PageView</th>
      <?php
        $i = 0;
        foreach($data as $key => $value){
          if($i < 10){
            echo "<tr>";
            echo "<td>".$key."</td><td>".$value."</td>";
            echo "</tr>";
          }
          $i++;    
        }
      ?>
      </table>
      <?php endif; ?>

continent

country

city

一人デバックしてるなー
というか、これ、ページビュー単位ではなくて、cookie単位しないと駄目だ
うおおおおおおお、結構複雑だ

cookieに重複がない場合だけ、ipの地域を取得するに変更
foreachの前で$cookie=array();と宣言します。

$cookie = array();
foreach ($cursor as $document) {
  $pv[] = $document->date;
  if(!in_array($document->cookie, $cookie)){
    if(!is_null($document->continent)){
    $c1[] = $document->continent;
    }
    if(!is_null($document->contry)){
    $c2[] = $document->contry;
    }
    if(!is_null($document->city)){
    $c3[] = $document->city;
    }
  }
  $cookie[] = $document->cookie;
  $session[] = $document->session;
  if(!is_null($document->referrer)){
  $avgtime[] = $document->avgtime;
  }
  if(!is_null($document->referrer)){
  $referrer[] = $document->referrer;
  }
  $visit[] = $document->visit;
  $access[] = substr($document->date, 11, 2);
  $page[] = $document->page;    
}

continent, country, cityがuniqueになりました。
よっしゃ、ip周りはOKそう。

次は、browser, os, service provider
これ、js、phpでとれるんか?
取れなければ、スキップとしたい。が、GAでは必ず見る項目ではある。。

ipアドレスの地理情報を取得してmongoDBに挿入する

192.168.33.1だとgeoliteがエラーになるので、198.7.31.23にします。

$data = array("date"=>date("Y-m-d H:i:s"));
$audience = $_POST['userdata']; 
$mongo = "app.na".$audience[0][1];
$audience = array_splice($audience, 1);

$ip_addr = $audience[0][1];
if($ip_addr == "192.168.33.1"){
	$ip_addr = "198.7.31.23";
}

foreach($audience as $value){
	$data += array($value[0]=>$value[1]); 
}

require_once '../geolite/vendor/autoload.php';
use GeoIp2\Database\Reader;

$reader = new Reader('../geolite/GeoLite2-City.mmdb');
$record = json_decode(json_encode($reader->city($ip_addr)));

$continent = $record->continent->names->en;
$contry = $record->country->names->en;
$city = $record->city->names->en;

$data = $data + array('continent'=>$continent, 'contry'=>$contry, 'city'=>$city);

var_dump($data);

$mng = new MongoDB\Driver\Manager("mongodb://localhost:27017");

$bulk = new MongoDB\Driver\BulkWrite;
$bulk->insert($data);
$mng->executeBulkWrite($mongo, $bulk);

echo "finished!!!";

取得できています。

mongoDBにもはいってます。

-geoliteがエラーの時の為に、try catch (Exception $e) に変えると、以下の分岐条件は削除できます。

if($ip_addr == "192.168.33.1"){
	$ip_addr = "198.7.31.23";
}

ipの地理情報はmongoDBには入りません。

因みに、Chrom extensionでBetternet Unlimited Free VPN ProxyやHotspot Shieldなどを使うとIPアドレスを偽造できるようです。

次は、表示側を作ります。
flexを入れ子にしたレイアウトにします。

ipの大陸、国、地域を配列にpush

$audience = array("date"=>"2018-04-18 08:05:50", "ip"=>"198.7.31.23", "visit"=>"Returned User");

$ip_addr = $audience["ip"];

require_once 'vendor/autoload.php';
use GeoIp2\Database\Reader;

$reader = new Reader('GeoLite2-City.mmdb');
$record = json_decode(json_encode($reader->city($ip_addr)));

$continent = $record->continent->names->en;
$contry = $record->country->names->en;
$city = $record->city->names->en;

$audience = $audience + array('continent'=>$continent, 'contry'=>$contry, 'city'=>$city);

print_r("<pre>");
var_dump($audience);
print_r("</pre>");

きた!

ipから、continent, country, cityを取得

encodeしてdecodeします。

$reader = new Reader('GeoLite2-City.mmdb');
$ip_addr = '182.22.59.229';
$record = json_decode(json_encode($reader->city($ip_addr)));



echo $record->continent->names->en ."<br>";
echo $record->country->names->en ."<br>";
echo $record->city->names->en ."<br>";

首相官邸
https://www.kantei.go.jp/
202.214.216.10
Asia
Japan
Komagatani
大阪府羽曳野市駒ケ谷?

white house
https://www.whitehouse.gov/
North America
United States
Cambridge

おもろい!続けて..

ペニンシュラ
peninsula.com
North America
United States
cityがnullの場合もあるようです。
ってか、アメリカかい!

GeoIP2でipアドレスの住所判定

GeoLite2 CountryがIPアドレスから国を取得するデータベース、GeoLite2 CityがIPアドレスから地域を取得するデータベース

# wget http://geolite.maxmind.com/download/geoip/database/GeoLite2-Country.mmdb.gz
# gunzip GeoLite2-Country.mmdb.gz
# wget http://geolite.maxmind.com/download/geoip/database/GeoLite2-City.mmdb.gz
# gunzip GeoLite2-City.mmdb.gz

mmdbはインメモリデータベース
gunzip:圧縮された圧縮ファイルを解凍する

composerを入れてGeoIP2 PHP APIをインストール

$ curl -sS https://getcomposer.org/installer | php
composer require geoip2/geoip2:~2.0

<?php
require_once 'vendor/autoload.php';
use GeoIp2\Database\Reader;

$reader = new Reader('GeoLite2-City.mmdb');
$ip_addr = '182.22.59.229';
$record = $reader->city($ip_addr);

print_r("<pre>");
var_dump($record);
print_r("</pre>");
?>

ドイツ語、英語、スペイン語、フランス語、日本語、ポルトガル語、ロシア語、中国語で出力されます。
[“record”:”GeoIp2\Record\AbstractRecord”:private]=>
array(2) {
[“geoname_id”]=>
int(1850147)
[“names”]=>
array(8) {
[“de”]=>
string(5) “Tokio”
[“en”]=>
string(5) “Tokyo”
[“es”]=>
string(5) “Tokio”
[“fr”]=>
string(5) “Tokyo”
[“ja”]=>
string(6) “東京”
[“pt-BR”]=>
string(7) “Tóquio”
[“ru”]=>
string(10) “Токио”
[“zh-CN”]=>
string(6) “东京”
}
}

1.エリア、国、都市を取得
2.wget・gunzipをcronで実行できるか確認が必要
3.クライアントリクエストからの負担を軽くするため、都市の抽出はmongoDBに入れる前にphp側で実行したい