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

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

Related Posts:

One Response to “Update .htaccess with Dynamic DNS IP Address to Prevent Password Protection”

  1. ray Says:

    I've having exactly the same problem as yours, and I'm updating my dynamic IP manually for a few years using FTP lol.

    Your great blog enlightened me, but sadly my webhost doesn't allow shell_exec so I wrote a simple perl script instead, hope reader here find it useful.

    My perl doing exactly the same as your php, however, instead of reading a live .htaccess file, my perl read from a template instead, of course, if you assign a live .htaccess as a template, it works as well.

    Once it found the template file, it looks for any line(s) contains the word @@@DYNAMIC@@@ and then replace it with a new line below

    allow from 1.2.3.4

    The perl script is already running on my shared web hosting account :)

    #!/usr/bin/perl
    
    $htaccess = "/volume1/web/test/.htaccess";
    $template = "/volume1/web/test/template";
    
    # get ip address
    $result=`host myhome.somedomain.com`;
    @sp = split(/ /,$result);
    $size = @sp;
    $ip = $sp[$size-1];
    
    open(TEMPLATE, $template) || die("Could not open file!");
    @raw_data=;
    close(TEMPLATE);
    
    open(NEW, ">$htaccess") || die("Could not create file!");
    
    foreach $line (@raw_data){
    	if($line =~ /\@\@\@DYNAMIC\@\@\@/){
    		print NEW "allow from $ip\n";
    	}else{
    		print NEW $line;
    	}
    }
    
    close(NEW);
    

Leave a Reply

XHTML: You can use these tags: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>

Notify me of followup comments via e-mail. You can also subscribe without commenting.