DNS浸透を温かく見守るコマンドラインツール


サーバ移転とかしたときに、どのへんまでDNS情報が更新されてるか知りたい時に使います。

2012-04-04 追記:

コメントにてgeekpageさんがこのツールの問題を指摘しています。コメントを参照の上、各自の修正するなりして状況に対応してくださいm(_ _)m ご指摘くださったgeekpageさんありがとうございます!

dns-penetration-monitor.php
#!/usr/bin/env php
<?php

//$monitor = new DNSPenetrationMonitor(ドメイン, 新しいIP);
$monitor = new DNSPenetrationMonitor('suin.asia', '59.106.173.151');
$monitor->monitor();

class DNSPenetrationMonitor
{
    protected static $providers = array(
        '202.234.232.6'     => 'OCN',
        '221.113.139.250'   => 'OCN',
        '210.196.3.183'     => 'auone',
        '210.141.112.163'   => 'auone',
        '202.248.37.74'     => '@nifty',
        '202.248.20.133'    => '@nifty',
        '202.238.95.24'     => 'So-net',
        '202.238.95.26'     => 'So-net',
        '143.90.130.165'    => 'odn',
        '143.90.130.39'     => 'odn',
        '8.8.8.8'           => 'google',
        'dns3.sakura.ad.jp' => 'sakura',
        'exnsa.plala.or.jp' => 'plala',
        '198.153.192.1'     => 'Norton',
        '198.153.194.1'     => 'Norton',
        '208.67.222.222'    => 'OpenDNS',
        '208.67.220.220'    => 'OpenDNS',
        '4.2.2.1'           => 'GTEIDNS',
        '4.2.2.2'           => 'GTEIDNS',
        '156.154.70.1'      => 'Dnsadvantage',
        '156.154.71.1'      => 'Dnsadvantage',
    );

    protected $hostName   = '';
    protected $newAddress = '';
    protected $intervalSeconds = 5;
    protected $providerStringLength = 0;

    /**
     * @param string $hostName
     * @param string $newAddress
     * @param int $intervalSeconds
     */
    public function __construct($hostName, $newAddress, $intervalSeconds = 5)
    {
        $this->hostName = $hostName;
        $this->newAddress = $newAddress;
        $this->intervalSeconds = $intervalSeconds;
        $this->providerStringLength = $this->_calculateProviderStringLength();
    }

    /**
     * @return void
     */
    public function monitor()
    {
        $this->_print("Start monitor: {$this->hostName}");
        $this->_print("To quit: Ctrl + C");

        while ( true )
        {
            $this->lookup();
            $this->_print("Sleep {$this->intervalSeconds} seconds...");
            sleep($this->intervalSeconds);
        }
    }

    /**
     * @return void
     */
    public function lookup()
    {
        foreach ( self::$providers as $providerAddress => $providerName )
        {
            $currentAddress = $this->_getAddress($this->hostName, $providerAddress);
            $this->_printLookupResult($currentAddress, $providerAddress);
        }
    }

    protected function _calculateProviderStringLength()
    {
        $maxLength = 0;

        foreach ( self::$providers as $address => $name )
        {
            $length = strlen($address.$name);

            if ( $maxLength < $length )
            {
                $maxLength = $length;
            }
        }

        return $maxLength;
    }

    protected function _isNewAddress($currentAddress)
    {
        return ( strpos($currentAddress, $this->newAddress) !== false );
    }

    protected function _getAddress($hostName, $nameServerName)
    {
        $command = sprintf('nslookup %s %s', $hostName, $nameServerName);
        $output  = array();
        exec($command, $output);
        $output = array_filter($output);
        return array_pop($output);
    }

    protected function _getStatusString($currentAddress)
    {
        if ( $this->_isNewAddress($currentAddress) )
        {
            return  "\033[32mNEW\033[0m";
        }

        return "\033[31mOLD\033[0m";
    }

    protected function _printLookupResult($currentAddress, $providerAddress)
    {
        $now = date('Y-m-d H:i:s');
        $status = $this->_getStatusString($currentAddress);
        $providerName = self::$providers[$providerAddress];
        $providerString = str_pad("$providerName($providerAddress)", $this->providerStringLength + 2, ' ', STR_PAD_RIGHT);
        $message = "[$now] $providerString $status $currentAddress";
        $this->_print($message);
    }

    protected function _print($message)
    {
        file_put_contents('php://stdout', $message.PHP_EOL);
    }
}