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

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

2012-04-04 追記:

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

![120330-dns-penetration-monitor.png](https://qiita-image-store.s3.amazonaws.com/0/889/8b3827ee-fbbd-fac5-ce37-175880a54814.png)


```php: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);
	}
}
```