Update .htaccess with Dynamic DNS IP Address to Prevent Password Protection

by Brett on March 9, 2010

I was working on a password protected site that needed to allow one specific user access without requiring a login/password to access it. The site was already using .htaccess to password protect the entire site so the quickest solution was to use the following type of setup in the htaccess file:

Order deny,allow
Deny from all
AuthGroupFile /dev/null
AuthName "A Blog"
AuthType Basic
AuthUserFile /home/admin/domains/domain.com/.htpasswd/public_html/.htpasswd
require valid-user
Allow from person.getmyip.com
Satisfy Any

The main addition that I added to the password protection is line 8 “Allow from”. This line allows a specific IP address or host to have access without requiring password protection.

However, the host that needed to be used was a Dynamic DNS hostname. This creates a problem as Apache takes the following steps when the user requests access.

  1. Grab IP from user requesting access
  2. Do a reverse DNS lookup
  3. Compare the results to the host in the Allow from line (person.getmyip.com)

In this case when a reverse DNS lookup is completed on the users IP address it will not find the Dynamic DNS hostname. Instead, it will find the hostname that is associated with your ISP which might look something like this 8.sub-79-231-223.myvzw.com.

There are a number of ways to get around this issue. In my case I wanted to use a small script to dynamically populate the .htaccess file with the correct IP address.

Below is the following PHP script that handles updating .htaccess with the latest IP address. The main requirement is that there is a comment “# Allow from person.getmyip.com” somewhere in the .htaccess file. This line tells the script where to insert the IP address on the very next line.

<?php
// Rewrites the entire htaccess file. When a line starts with '# Allow from brett.getmyip.com' the
// very next line will be replaced with the actual ip associated with brett.getmyip.com
$htaccessFile = "/home/admin/domains/batie.com/public_html/.htaccess";
$handle = fopen($htaccessFile, "r");
if ($handle) {
	$previous_line = $content = '';
	while (!feof($handle)) {
		$current_line = fgets($handle);
		if(stripos($previous_line,'# Allow from person.getmyip.com') !== FALSE)
		{
			$output = shell_exec('host person.getmyip.com');
			if(preg_match('#([0-9]{1,3}\.){3}[0-9]{1,3}#',$output,$matches))
			{
				$content .= 'Allow from '.$matches[0]."\n";
			}
		}else{
			$content .= $current_line;
		}
		$previous_line = $current_line;
	}
	fclose($handle);
	$tempFile = tempnam('/tmp','allow_');
	$fp = fopen($tempFile, 'w');
	fwrite($fp, $content);
	fclose($fp);
	rename($tempFile,$htaccessFile);
	chown($htaccessFile,'admin');
	chmod($htaccessFile,'0644');
}
?>

I quickly wrote this script and realize that there is room for improvement. However, this meet the need and solved the problem.

After the script was completed adding a simple line to the crontab (crontab -e) file got it running on a regular basis to automatically update the file with the current IP.

# Script to update ip access for dynamic dns host - it allows person.getmyip.com
*/5 * * * * /usr/local/bin/php /home/admin/scripts/allow_person.php >/dev/null 2>&1

Previous post:

Next post: