Restricting access to a URL by IP address using mod_rewrite

There are gazillions of articles out there telling you how to restrict access to a directory using either FilesMatch or mod_rewrite rules in .htaccess. But trying to find out how to restrict access to a page based on a URL is somewhat more difficult. FilesMatch and RewriteRule only work on the first part of the URL - they ignore the querystring. But mod_rewrite is capable of restricting access to a page based on the querystring value and the IP address of the visitor if you can find the right syntax - and here it is...

I am assuming you already have mod_rewrite working (ie. your .htaccess contains Options +FollowSymLinks or whatever else may be required, if applicable). Let's say you want to block IP address 123.255.123.255 from accessing the page www.mydomain.com/index.php?option=com_my_special_component. Here is how you could write the rule:

RewriteEngine On
RewriteCond %{REMOTE_ADDR} ^123\.255\.123\.255
RewriteCond %{QUERY_STRING} option=com_my_special_component [NC]
RewriteRule ^(.*)$ index.php [F,L]

The first line just turns on URL rewriting. The second line matches the IP address (use backslashes before each dot), the third line matches the querystring (ie. anything that comes after the ? in the URL) - in this case it would match if option=com_my_special_component comes anywhere in the URL after the ? (eg. index.php?id=1&option=com_my_special_component&action=dostuff would still match with this rule). The [NC] at the end of that line tells it to apply the rule regardless of whether any of the characters in the URL are uppercase or lowercase. The final line redirects the user to index.php with a 'forbidden' header - so they will get an error message in their browser, and tells mod_rewrite to stop interpreting any further rewrite rules.

If you want to ban multiple IP addresses, you can add new lines for them, but you need to add an [OR] flag to the end of each line except the last one - for example:

RewriteEngine On
RewriteCond %{REMOTE_ADDR} ^123\.255\.123\.255 [OR]
RewriteCond %{REMOTE_ADDR} ^124\.255\.124\.255 [OR]
RewriteCond %{REMOTE_ADDR} ^125\.255\.125\.255
RewriteCond %{QUERY_STRING} option=com_my_special_component [NC]
RewriteRule ^(.*)$ index.php [F,L]

If you want to turn it around and only allow a certain IP address to access the page, you just put an exclamation mark before the IP address, like this:

RewriteEngine On
RewriteCond %{REMOTE_ADDR} !^123\.255\.123\.255
RewriteCond %{QUERY_STRING} option=com_my_special_component [NC]
RewriteRule ^(.*)$ index.php [F,L]

In that example, only IP address 123.255.123.255 would be able to access the page. If you want to allow multiple IP addresses to access the page, you can add a new line for each one - but in that case you should NOT add the [OR] flag to the end - for example:

RewriteEngine On
RewriteCond %{REMOTE_ADDR} !^123\.255\.123\.255
RewriteCond %{REMOTE_ADDR} !^124\.255\.124\.255
RewriteCond %{REMOTE_ADDR} !^125\.255\.125\.255
RewriteCond %{QUERY_STRING} option=com_my_special_component [NC]
RewriteRule ^(.*)$ index.php [F,L]

Important Note: If you already have any mod_rewrite rules in your .htaccess file, you should place the above rules before the existing rules (but after the existing RewriteEngine On statement - of course, you could then also remove the RewriteEngine On statement from the above examples). Otherwise, if your existing rules contain an [L] flag, your new rules will never be applied.

 

Comments

Posted by Doris on
Thanks for posting! I learned a lot!
Doris
Leave a Reply



(Your email will not be publicly displayed.)


Captcha Code

Click the image to see another captcha.


Posted by:

Share: