Permanently Redirect a Specific IP Request for a Single Page via htaccess

Post #374 categorized as Function, last updated on Nov 5, 2007
Tagged with apache, htaccess, mod_rewrite, redirect, tips, tricks

Not the most interesting title, but “oh well”..

Recently, a reader named Alison left a comment requesting help with a particular htaccess trick. She wanted to know how to permanently redirect (301) all requests for a specific page when requested from a specific IP address. In other words, when a visitor coming from 123.456.789 requests the page requested-page.html, the visitor will be redirected to just-for-you.html. All visitors not coming from that specific IP address are not redirected, and thus will see the originally requested page. Further, the redirect must apply only to requested-page.html, such that every visitor — including the one coming from 123.456.789 — will be able to see all of the other pages. Here is the htaccess code to make it happen:

# permanently redirect specific IP request for single page
RewriteEngine On
RewriteBase /
RewriteCond %{REMOTE_HOST} 123\.456\.789
RewriteCond %{REQUEST_URI} /requested-page\.html$
RewriteRule .* /just-for-you.html [R=301,L]

To use this redirect, simply edit the IP address, requested page, and redirect page. Copy and paste the code into your htaccess file and upload to your server. Test the 301 redirect via proxy and that’s it. Relax and enjoy!

Subscribe to Perishable Press


35 Responses

TopLeave a comment

[ Gravatar Icon ]

#1tim

Shouldn’t that last line be:

RewriteRule .* /just-for-you.html [R=301,L]

302 is a temporary re-direct. 301 is permanent.

[ Gravatar Icon ]

#2Perishable

Man, today is just not my day!
Anyway, you are absolutely correct..
I meant 301, said 301, and have no idea why I wrote 302 in the code (could be all the pain meds?).. either way, thank you for catching the error. The code now reads correctly (i think)..

[ Gravatar Icon ]

#3Snook

Hey dude this is great, but if I wanted to block an IP range, say:

214.53.25.64 - 214.53.25.128

how would it be written?

[ Gravatar Icon ]

#4Perishable

Snook,

There are several ways to block a specific IP range.

The first utilizes a CIDR number to block the specified range (via htaccess):

# block IP range by CIDR number
<Limit GET POST PUT>
 order allow,deny
 allow from all
 deny from 214.53.25.64/26
</Limit>

The second method is similar, only here we are expressing the range in netmask notation, using corresponding network/netmask values:

# block an IP range via network/netmask values
<Limit GET POST PUT>
 order allow,deny
 allow from all
 deny from 214.53.25.64/255.255.255.192
</Limit>

The third method tests all IP addresses against a predefined regular expression via RewriteCond/RewriteRule directives:

RewriteEngine On
RewriteCond %{REMOTE_ADDR} ^214\.53\.25\.(6[4-9]|7[0-9]|8[0-9]|9[0-9])$ [OR]
RewriteCond %{REMOTE_ADDR} ^214\.53\.25\.1([0-1][0-9]|2[0-8])$
RewriteRule .* - [F]

There is probably a more efficient way to write the regular expressions in the previous example, but that should definitely get the job done.

[ Gravatar Icon ]

#5Mike

A great little article Jeff; some people these days still try and use metas on occasion to generate redirects by htaccess is truely the way i should be done!

[ Gravatar Icon ]

#6Perishable

I agree completely, Mike — handling redirects as close to the server as possible is definitely the way to go!

[ Gravatar Icon ]

#7Tony Tsai

um… ip cloaking via .htaccess ?

[ Gravatar Icon ]

#8Perishable

Ah, good point there, Tony. Thanks.

[ Gravatar Icon ]

#9Tony Tsai

I wasn’t thinking about it until people start to ask how to do it for specific IPs, Can probably use this to send SE ip to a page and regular ip to another page, maybe further divide the regular ip into region for geo targetted cloaking.

Pretty good info here and a lot of room to think about… thanks

[ Gravatar Icon ]

#10Lisa

This post has just made my day! I was looking all over to find this piece of code.

I have a questions though. Do I have to rewrite the “RewriteEngine On” and “RewriteBase /” everytime I want to block a different IP?

[ Gravatar Icon ]

#11Perishable

Thank you for the kind remarks, Lisa :) And, no, you do not need to rewrite the first two directives for each different IP that you would like to block. For example, this will work just fine for multiple IPs:

# permanently redirect multiple IP requests for single page
RewriteEngine On
RewriteBase /
RewriteCond %{REMOTE_HOST} 123\.456\.789
RewriteCond %{REMOTE_HOST} 456\.789\.123
RewriteCond %{REMOTE_HOST} 789\.123\.456
RewriteCond %{REQUEST_URI} /requested-page\.html$
RewriteRule .* /just-for-you.html [R=301,L]

You may add as many IPs as you like, however, keep in mind that there may be a better way to block numerous addresses via pattern matching, depending on your needs.

[ Gravatar Icon ]

#12Tweak

how about redirecting for a specific ISP. im trying to give a certain annoying character on my site a message, he uses a certain ISP that none of my other uses use. In my log files he shows up as
##-###-##-###.dhcp.insightbb.com

His ip is constantly changing and im talking about every octet, not just the last 2.

[ Gravatar Icon ]

#13Perishable

Hi Tweak, try the following code in your root htaccess file:

<Files *>
  Order Allow,Deny
  Allow from all
  Deny from dhcp.insightbb.com
</Files>

This should do the trick, however it would be better to block via range of IP addresses. Using the hostname to prevent access requires your server to execute a reverse-DNS request with the DNS network, thereby reducing performance for every server request.

[ Gravatar Icon ]

#14Jean Morgan

I need to bar a specific ISP from allowing any of their customers access to my website. Will this code in .htaccess do that?

[ Gravatar Icon ]

#15Perishable

Yup, should work fine! :)
Here is another way of blocking a specific ISP via its IP address(es).

<Files *>
 Order Allow,Deny
 Allow from all
 Deny from 123.123.123.
 Deny from 456.456.456.
</Files>

..etc. You could also block via the ISP’s hostname, but there is a negative impact on performance because of all the reverse-DNS requests.

[ Gravatar Icon ]

#16jewls

I am trying to block an employer’s ISP from visiting my blog. It is outside their sphere of influence in my life however, I get constant criticism. I would like to redirect or block the ISP - not sure exactly if that is what this code is doing. I do not however want a message to come up that says, “You have been denied access to this page” - I just want it to be a frustrate them by redirects until they stop trying.
I am novice enough that I don’t know for sure that I know where to put this code or which part of it I need - and need to edit.
I apologize for being high maintenance about this - but any help you could offer would be greatly appreciated. Please do not comment ON my blog about this issue for the above stated reasons!

[ Gravatar Icon ]

#17Perishable

Hi jewls, the code in the article should work fine for blocking a specific ISP. You will need to obtain the IP address of the ISP and then edit the code accordingly. The code should then be placed into your site’s web-accessible root HTAccess file. Then to display a custom error message, create a web page as desired and edit the HTAccess code to reflect the its location on your server. Once everything is in place, all visitors coming from the specified ISP will receive the “access-denied” message.

[ Gravatar Icon ]

#18Bob

Hi, I have a small fan-site that keeps being abused by one person who targets me from multiple family/friend computers. (136 contact form emails in 3 months is insane). I can see it’s him via online IP locators and they are always within a 50mile radius. There’s a real hotspot for activity in his area and it’s really annoying - I don’t get it from anywhere else. So far I’ve been collecting his specific IPs to block via a php script, but inevitably, the following week he uses a different computer and he’s at it again. The IPs are always different but generally the first 2 octets in common (A spate of attacks where the first 2 octets are always the same and on the next spate they’ve changed, but again, the first 2 octets are the same throughout that attack session - This is where I can see he is in a different town.)
What I would like to do is block his ranges of IPs and refer him to a “You are not welcome” page. I’m not IP savvy so would it be best to block him based on the first 2 octets or be more specific and do it on 3? If it means blocking a handful of innocent visitors in his area, so be it - I just cant stand the continued abuse anymore.
Also, what would the code be to do it?
I’m sorry for the longwinded message but I’m at my wits end!

[ Gravatar Icon ]

#19Perishable

Hi Bob, I understand your frustration with malicious harassment. Fortunately, the article above provides everything you need to handle this situation effectively and securely. As you say, however, there will be a considerable number of users who will no longer enjoy access to your site, but sometimes stopping malicious behavior is worth the sacrifice. Good luck!

[ Gravatar Icon ]

#20Jonathan

Here’s how to do an “entire” ISP. For some values of “do” … :-) I’ll use “perishablepress.com” as the ISP “customer” I want to “do” …

a) find the IP of the customer:
user@host:~$ dig +short perishablepress.com
207.210.105.30

b) Find the containing netblock:
user@host:~$ whois 207.210.105.30
[examine output, looking for “netrange”, “cidr”, “inetnum”, or anything else that means “more than one IP”]
user@host:~$ whois 207.210.105.30 | grep -i cidr
CIDR: 207.210.64.0/18

c) Create a regular expression from this:

c1) Make sure a perl module is installed: CPAN - NetAddr::IP
[debian unstable or ubuntu gutsy or hardy: sudo apt-get install libnetaddr-ip-perl; redhat: have fun with that …]

c2) create an executable script with this in:
user@host:~$ cat bin/netblock2regex
#!/usr/bin/perl
use NetAddr::IP;
my $ip = new NetAddr::IP $ARGV[0], $ARGV[1];
print $ip->re(), "\n";

c3) Use the script
user@host:~$ ./bin/netblock2regex 207.210.64.0 18
?:(?<![0-9])207\.210\.(?:64|65|66|67|68|69|70|71|72|73|74|75|76|77|
78|79|80|81|82|83|84|85|86|87|88|89|90|91|92|93|94|95|96|97|98|99|
100|101|102|103|104|105|106|107|108|109|110|111|112|113|114|115|
116|117|118|119|120|121|122|123|124|125|126|127)
\.(?:[0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])(?![0-9]))

That string takes the place of the “123.\123\.123” in your htaccess file. Everything else stays the same.

HTH,
Jonathan

PS The string will probably get munged by the commenting system. There should be *no* animated smileys in your htaccess file … :-)

[ Gravatar Icon ]

#21Perishable

Thanks for the info Jonathan. A few more explanatory notes and that comment would make an excellent article in and of itself. ;)

I think your method raises an important point. I seemed to have missed the fact that ISPs generally employ an entire range of IP addresses, not just one, as I mistakenly suggested in previous comments. Even so, I think it would be much easier to block an entire ISP (based on its CIDR number) by simply using something similar to this in your site’s web-accessible root HTAccess file:

# block ISP by CIDR
<Files *>
   Order Allow,Deny
   Allow from all
   Deny from 207.210.64.0/18
</Files>

I am not that familiar with the perl language, so correct me if I am mistaken, but wouldn’t this technique be easier than the method described in your comment?

Regards,
Jeff

[ Gravatar Icon ]

#22Jeremy

Hi Jeff,
Great article. I have one question though: How do I redirect a page that is being served up by Wordpress’ rewrite rule?

For example, I would like to have this page: http://truthdaredoubledare.com/projects/haruurara/ redirect if requested from a specific DNS. I’ve tried the following to no avail :/

# RewriteEngine On
# RewriteBase /
# RewriteCond %{REMOTE_HOST} xxx\.xxx\.xxx
# RewriteCond %{REQUEST_URI} ./wordpress/page-to-block\.php$
# RewriteRule ./wordpress/page-to-redirect.php [R=301,L]

Thanks in advance :D

[ Gravatar Icon ]

#23Hamster

Nice tips, hopefully it will be handy for me.

I have been using toolator’s ip blocker for sometime now, which is basically pasting a html code onto the site. However they are now charging for there services, and i donät make that much money……lol.

would all that, which has been written above, be used in html format.

forgive me for being thick, but this is not my specialised subject.

[ Gravatar Icon ]

#24Jeff Starr

@Jeremy: I have yet to try this myself, but looking at your code, I might suggest removing the PHP file extension (i.e., \.php) from the second rewrite condition. Also, in the rewrite rule itself, you could try adding a string to match against, for example:

RewriteRule (.*) http://domain.tld/target-file.php [R=301,L]

[ Gravatar Icon ]

#25Jeff Starr

@Hamster: The code presented in the article will work with any web-served document, XHTML, HTML, PHP, or otherwise. You will need access to an htaccess file (or the Apache config file) to implement it, but once in place, it should work just fine.

[ Gravatar Icon ]

#26Emmx

Great bit of code, I came to comments as I had a question and found my answer here :) Thanks to the coder!

[ Gravatar Icon ]

#27Jeff Starr

My pleasure, Emmx, thanks for the positive feedback :)

[ Gravatar Icon ]

#28lenny

Would this work with myspace?

[ Gravatar Icon ]

#29Jeff Starr

Hi lenny,
No, unfortunately the redirect method described in the article is a server-side technique that requires server access to implement. I think MySpace recently restricted server access to staff only, sadly..

[ Gravatar Icon ]

#30Sheps

I’ve setup the redirect in my .htaccess above - but has anyone else found that it slows down regular access to the web site?

I tested blocking my IP - took a while for the redirected page to appear, when I tried it from another connection - I couldn’t access my site, it just stayed there trying to find the page.

Is this something I’ve done?

[ Gravatar Icon ]

#31Jeff Starr

@Sheps: Nope, Apache is great at handling simple redirects (and even complicated ones!). Granted, using mod_rewrite is not the optimal way of identifying IP addresses, but it is needed to accomplish the URL-specific redirect. Perhaps there is another issue involved..?

[ Gravatar Icon ]

#32Almir

How to redirect using .htaccess

from:
mysite.com/index.php?option=com_jdownloads&amp;Itemid=49&amp;task=viewcategory&amp;catid=9

to:
mysite.com/index.php?option=com_jdownloads&amp;Itemid=49&amp;task=viewcategory&amp;catid=7

it ’s not working if use %{REQUEST_URI}

[ Gravatar Icon ]

#33Jeff Starr

@Almir: Try targeting the query string via the %{QUERY_STRING} variable.

[ Gravatar Icon ]

#34Almir

can you post example using query string, please

[ Gravatar Icon ]

#35Jeff Starr

Sure, here is a basic example of how to target the query string:

<ifmodule mod_rewrite.c>
   RewriteCond %{QUERY_STRING} target\-string\-01 [NC,OR]
   RewriteCond %{QUERY_STRING} target\-string\-02 [NC]
   RewriteRule .* - [F,L]
</ifmodule>

That should provide enough information to facilitate further research via Google or your favorite search engine. Replace each of the target strings to match your desired query string and you should be good to go!

Share your thoughts..

TopRead official comment policy

The rules are simple. Comment intelligently. Stay on-topic. Don’t spam! Suspected spam will be deleted. Use your real name or nickname, not a site name or business name. Using a site name or business name is a good way to get your link or comment removed. Certain comments are moderated; if your comment does not appear after several days, or if you wish to comment privately, contact me. Also, by posting a comment, you grant this site a perpetual license to reproduce your comment, name, and website URL. Lastly, you may use basic HTML markup, but please do not use <pre> tags. Instead, wrap your code with <code> tags. Use a new set of <code> tags for each code term or phrase, as well as for each individual line of code (i.e., multiple lines of code require multiple code tags). Please see the complete comment policy for more information.