Forum Moderators: phranque
So... I setup a page to catch their IP address which I want to redirect them to.
I know how to block those visitors once I get their IP. All I need is the .htaccess code (or whatever I'm supposed to use) to redirect all visitors coming from a certain domain name to a particular page.
THANKS a MILLION! :c)
RewriteEngine on
RewriteCond %{HTTP_REFERER} www\.wikihow\.com
RewriteCond %{REQUEST_URI} !^/error.html
RewriteRule ^.? /error.html
works fine for me. You need to have that second line because it'd go into an endless loop otherwise. I forgot that before.
If it's not working, are you sure your browser sends the referer? Do you get some error or is it just showing the requested page? You do have apache as a webserver, right?
You might also try adding
Options +FollowSymLinks +SymLinksIfOwnerMatch
Right before
RewriteEngine On
RewriteRule ^.? /error.html
To
RewriteRule .* [domain.com...]
But no, it won't actually open the error.html page because it says it can't find or connect to domain.com... So this isn't exactly working proper.... :cS
try changing
RewriteRule .* [domain.com...]
to
RewriteRule .* [domain.com...] [R=307]
Will that code work on subdomains? Like if the referrer was subdomain.domain.com?
Also, if I have other RewriteEngine rules in my .htaccess file will they still work, on separate lines further down? (I took the previous rules out for testing) So for instance my ReWriteEngine rules that block and redirect the IP addresses...)
RewriteEngine on
RewriteCond %{HTTP_REFERER} .wikihow\.com [OR]
RewriteCond %{HTTP_REFERER} wikihow\.com
RewriteCond %{REQUEST_URI} !^/error.html
RewriteRule ^.? /error.html
and yes, it shouldn't interfere with your other rewrite rules, but testing that is never wrong ;)
Contrary to what I thought, it won't redirect me to the error page (the site blocking rule), but will instead block my IP from seeing the site in the first place. Is this what is supposed to happen?
So, if I'm confusing you, um sorry. I'm just wondering which rule takes precedence? The one the comes first in the .htaccess file or the second one? Because for me, the second one is the one happening...
If the IP-based code uses mod_access directives (e.g. "Deny from 192.168.0.1"), then it's likely that your server is configured to execute mod_access directives first.
It's critical to understand that directives in your .htaccess file *are not* executed in the order you type them -- You should not view .htaccess code as a sequentially-executed "program." Directives in .htaccess are executed on a per-module basis, as determined by the server configuration. That is, all directives handled by the first module are executed, followed by all directives from the second module, etc. So the order in which you put your code only affects the relative order of execution of directives handled by the same module.
Module execution order on Apache 1.x is determined by the reverse LoadModule order in httod.conf. It is determined by an internal priority scheme on Apache 2.x.
Jim
Here is what I got (with specific domains and details substitued)
RewriteEngine on
RewriteCond %{HTTP_REFERER} .wikihow\.com [OR]
RewriteCond %{HTTP_REFERER} wikihow\.com
RewriteRule .* [domain.com...] [R=307]
Options +FollowSymlinks
RewriteEngine on
RewriteCond %{REMOTE_HOST} 43\.533\.242\.111 [OR]
...
RewriteCond %{REMOTE_HOST} 34\.756\.323\.656
RewriteRule .* [domain.com...] [R=301,L]
Here is my problem now: The two parts of the code work perfectly fine when they are not present in the .htaccess file at the same time. However, when they are together, I get an infite loop error from my browser. I'm not sure why...
The first request gets redirected, then the client comes back with a second request (for the /error page) and gets blocked by IP address. Use a server headers checker such as the "Live HTTP Headers" add-on for Firefox/Mozilla browsers to verify this behaviour.
Note also that a 307 response is not supported by true HTTP/1.0 clients. While these are very rare now --almost non-existent-- you should test for the protocol level before returning any new HTTP/1.1 status responses *if* your site is hosted on anything except a shared name-based virtual server (HTTP/1.0 clients cannot reach purely-name-based servers, because they don't send a "Host" request header). Rather than sniffing the protocol and varying the response code, it would be easier to return a 301 or a 302, supported by HTTP/1.0.
Or to fix both problems, use an internal rewrite as janharders originally suggested, rather than a redirect. (If you do use an internal rewrite, be sure to completely flush your browser cache between tests, to prevent previously-cached responses from confusing your test results.)
Jim
So this is the final code that seems to work fine. Not sure if there is anything wrong syntax-wise.
(domain-blocking code that sends the person to a error page that collects their IP address for my information and then uses a meta redirect to send them away to an external site)
RewriteEngine on
RewriteCond %{HTTP_REFERER} .wikihow\.com [OR]
RewriteCond %{HTTP_REFERER} wikihow\.com
RewriteCond %{REQUEST_URI} !^/error.html
RewriteRule .* [domain.com...]
(IP-blocking code that blocks malicious visitors I have already identified and redirects them to a non-existent page on my site which gives them a 403 error. Not too clever, I know...)
Options +FollowSymlinks
RewriteEngine on
RewriteCond %{REMOTE_HOST} 44\.44\.44\444 [OR]
...
RewriteCond %{REMOTE_HOST} 33\.33\.333\.333
RewriteRule .* [domain.com...] [R=301,L]
I'd suggest:
# Enable mod_rewrite
Options +FollowSymlinks
RewriteEngine on
#
# Internally rewrite visitors referred by wikihow to special page
RewriteCond %{HTTP_REFERER} wikihow\.com
RewriteCond %{REQUEST_URI} !^/error.html
RewriteRule .* /error.html [L]
#
# Send 403-Forbidden response to requests from unwelcome IP addresses/ranges
RewriteCond %{REMOTE_ADDR} 44\.44\.44\.44 [OR]
...
RewriteCond %{REMOTE_ADDR} 55\.55\.55\.55 [OR]
RewriteCond %{REMOTE_ADDR} 33\.33\.33\.33
RewriteCond %{REQUEST_URI} !^/path-to-your-custom-403-error-page\.html$
RewriteRule .* - [F]
I hope I'm expressing myself clearly enough...
# Send 403-Forbidden response to requests from unwelcome IP addresses/ranges
RewriteCond %{REMOTE_ADDR} 44\.44\.44\.44 [OR]
...
RewriteCond %{REMOTE_ADDR} 55\.55\.55\.55 [OR]
RewriteCond %{REMOTE_ADDR} 33\.33\.33\.33
RewriteCond %{REQUEST_URI} !^/fake-error-page\.html$
RewriteRule .* - [F]
RewriteRules must be designed so that their conditions for invocation are mutually-exclusive. This is done by rule order, use of specific and different RewriteRule and RewriteCond patterns, differing and/or additional RewriteCond variables, and the [L] and [S] flags. If a mod_access directive is being applied first, but you want it applied only after mod_rewrite gets a chance to process the request, then you'll need to re-code that mod_access code using mod_rewrite directives to control the execution order. (Sorry, this stuff isn't always simple)... :(
Also as stated above, be sure you are completely flushing your browser cache before each test.
Jim
However, the problem is the code regarding how to block particular IP addresses, which is separate from redirecting those that came from a particular domain. (see 2 posts up) How I deal with the unwelcome IPs is I send them to a non-existent page which depending on their browser, will show them a 403 with my root domain in their address bar. The reason I do this, is that I want them to think that my site no longer holds any content. I am not using an actual 403 error page.
So with the code you last gave me, the IPs are getting redirected to my site's IP capture page, not given the non-existent page. Sorry, is that explained good enough?
# Send 403-Forbidden response to requests from unwelcome IP addresses/ranges
RewriteCond %{REMOTE_ADDR} 44\.44\.44\.44 [OR]
...
RewriteCond %{REMOTE_ADDR} 55\.55\.55\.55 [OR]
RewriteCond %{REMOTE_ADDR} 33\.33\.33\.33
[i]RewriteCond %{REQUEST_URI} !^/error\.html$[/i]
RewriteCond %{REQUEST_URI} !^/path-to-your-custom-403-error-page\.html$
RewriteRule .* - [F]
Opinions differ, but I recommend not toying around with unwelcome accesses -- To avoid "dangerous" code complications and keep the sites easy to maintain, just send a 403-Forbidden response and be done with it. Give no information on the custom 403 error page other than "Access denied" -- There is no profit in issuing a "challenge" to the bad guys. YMMV.
Jim
I want the following things to be happening in my .htaccess file.
1) If visitor arrives at any page of my site from baddomain.com, I want him to be redirected to a *SPECIFIC* page on my site where I can gather his IP address. (The specific page will then whisk him back off to baddomain.com via a meta redirect)
2) If a malicious visitor that has a particular IP address comes to any page on my site, I want him to be redirected a *DIFFERENT SPECIFIC* page on my site that would be a fake 404 page.
I think that is the clearest I can put it. Sorry, I haven't communicated very well. The code that I've worked out and that you've given me does one, but not both of those things at any time. If I get one working, then the other one won't work... and on it goes.
THANK-YOU!