custom ban page for homebrew website - apache

I understand how to ban an IPs address from my apache webserver using .htaccess:
order allow,deny
deny from 192.168.44.201
deny from 224.39.163.12
deny from 172.16.7.92
allow from all
I'd like to create a custom "You've been banned" page. How could I do this?
EDIT:
To clarify, I am not trying to create a custom 403 page, as these are used in other instances as well (i.e. failed basic authentication, etc). The closest I have come so far is:
rewritecond %{REMOTE_ADDR} ^127\.0\.0\.1$
RewriteRule !^banned$ /banned [NC,L]
but this produces an internal server error when the IP is matched, instead of sending the user to /banned

The other answers which suggest an ErrorDocument for the 403 code would be the usual way to do this. But since you want to show a different error page if the user is denied access based on IP (as opposed to other reasons), you can use mod_rewrite, as you suspected.
RewriteCond %{REMOTE_ADDR} =192.168.44.201 [OR]
RewriteCond %{REMOTE_ADDR} =224.39.163.12 [OR]
RewriteCond %{REMOTE_ADDR} =172.16.7.92
RewriteRule !^/banned.html /banned.html [L]
P.S. This should go in your virtual host configuration, not an .htaccess file, if at all possible. If you don't have access to the virtual host configuration file, you could put it in a .htaccess file, but remove the leading slash from the RewriteRule pattern (so !^/banned.html becomes !^banned.html).

You use an ErrorDocument directive. People that are denied access are sent a 403 header, so:
ErrorDocument 403 banned.html
will redirect banned people to banned.html
Edit: The other alternative is to drop the mod_access stuff altogether, and use an IP-based rewrite rule (as mentioned in the question). It should just be:
RewriteEngine on
RewriteCond %{REMOTE_ADDR} 192.168.44.201 [OR]
RewriteCond %{REMOTE_ADDR} 224.39.163.12 [OR]
RewriteCond %{REMOTE_ADDR} 172.16.7.92
RewrulteRule .* banned.html [L]
Edit 2: David beat me to an almost identical answer; I think his way is what you want

In your .htaccess file:
ErrorDocument 403 /banned.html
change /banned.html to whatever path/to/filename you want.

Related

.htaccess Redirect with Cloudflare location

I'm really struggling to place redirects into my .htaccess file based on the cloud flare country code. I'm either getting "too many redirect errors" or 500 internal errors using examples from across this site.
I currently have this:
Options +FollowSymLinks
RewriteEngine on
SetEnvIf CF-IPCountry "(.*)$" Country=$1
RewriteCond %{ENV:Country} GB
RewriteRule ^(.*)$ http://example.com/$1 [R,L]
So I need the default domain to be http://example.com
but if a country code of GB comes from cloudflare for example, I need it to redirect to:
http://example.com/gb
With my limited knowledge of .htaccess is this possible?
Try with:
Options +FollowSymLinks
RewriteEngine on
RewriteCond %{HTTP:CF-IPCountry} ^GB$
RewriteCond %{REQUEST_URI} !(?:gif|png|jpg|jpeg|css)$ [NC]
RewriteRule !^gb/ /gb%{REQUEST_URI} [NC,NE,R,L]
Redirect http://example.com/test to http://example.com/gb/test when the request comes from a user with CF-IPCountry=GB which is not already using a link with /gb/

Redirect a range of IPs using RewriteCond

Currently I am redirecting all users except for the IP 12.345.678.90 using:
RewriteEngine On
RewriteCond %{REQUEST_URI} !/maintenance$
RewriteCond %{REMOTE_HOST} !^12\.345\.678\.90
RewriteRule $ /maintenance [R=302,L]
What syntax would I use to allow a range? In my Allow list I have:
Allow from 123.45.678.90/28
Would it work if I just update the REMOTE_HOST line to:
RewriteCond %{REMOTE_HOST} !^12\.345\.678\.90/28
If you're using Apache HTTPD 2.4 or later, you can use expressions to match REMOTE_ADDR against a CIDR mask.
The short form looks like this:
RewriteCond expr "-R '192.168.1.0/24'"
The following longer form is also available, but the documentation suggests it is less efficient:
RewriteCond expr "%{REMOTE_ADDR} -ipmatch '192.168.1.0/24'"
That makes the full solution to your example something like this:
RewriteEngine On
RewriteCond %{REQUEST_URI} !/maintenance$
RewriteCond expr "! -R '12.345.678.90/28'"
RewriteRule $ /maintenance [R=302,L]
You probably want the %{REMOTE_ADDR} to match against, but you can't use CIDR notation as the %{REMOTE_ADDR} is literally the remote address and you can use a regular expression to try to match against it. So for 123.45.67.89/28, (123.45.67.80 - 123.45.67.95), you'd have to do something like this:
RewriteCond %{REMOTE_ADDR} !^123\.45\.67\.8[0-9]$
RewriteCond %{REMOTE_ADDR} !^123\.45\.67\.9[0-5]$
Although this is an old question, I find it still very relevant. An alternative that does allow CIDR notation is the following (example is in a virtualhost apache conf file):
<VirtualHost *:80>
.
.
.
<Files maintenance>
Require all denied
Require ip 12.345.678.90/28
</Files>
.
.
.
</VirtualHost>
As a sidenote, I suspect, without having done any testing or finding any evidence, that this method is "faster" than the RewriteCond expr "-R '192.168.1.0/24'" methods mentioned.
This is for the simple reason that at this high level there appears to be less computational steps involved.
N.B. a requester from an IP that is denied will see a "Permission denied" or "Forbidden" type response. You can make this prettier by adding in a custom 404 page that responding with a 200/OK (this way Google won't penalise your domain). The 200/OK has to be the first line of your custom 404 page. For example in PHP, the first line would read:
<?php header("Status: 200 OK"); ?>
You'd want to do this for a legit page you redirect to. Actual 404s should respond with 404 to keep us from ending up with a ton of useless search engine results down the road.
Try this in .htaccess. It's working.
RewriteCond %{REMOTE_ADDR} !^123\.456\.789\.[0-255]
I like to use the following which allows partial address matching. In Your virtualHost/htaccess file
SetEnvIf HOST "siteYouAreworkingON.com" ACCESS_CONTROL<br>
SetEnvIf Remote_Addr "list of full or partia ipadresses separated by |"<br>
RewriteCond %{ENV:ACCESS_CONTROL} 1<br>
RewriteRule .* http://gohere.instead [L,R]
Hope it helps.

Authorizing access through htaccess with both http and https

I've searched for solutions and not finding a clear answer - It's a little out of my field but I need to find an answer in a pinch.
I use an .htaccess to verify and allow access to certain webpages from outside links.
here's a sample of what I use:
AuthUserFile /dev/null
AuthGroupFile /dev/null
RewriteEngine On
RewriteCond %{HTTP_REFERER} !^http://www.website_abc.com/
RewriteCond %{HTTP_REFERER} !^http://www.website_xyz.com/
RewriteRule /* http://www.mysite.com/denied_message.php [R,L]
this works as I want it to - I list the sites that I want to access and park .htaccess in a root directory.
My problem is when someone is linking from HTTPS it block's them even if they are in the list (and I tried putting https in the list as well).
I found various answers but none that I fully understood or that did the trick.
one was using :
RewriteCond %{HTTPS} on
but that allowed anyone in from any location.
Can someone spell this out for me?
apache / LAMP
Thanks!
RewriteCond %{HTTPS} on
This adds a condition that the actual request for your site is through HTTPS. You only want to match the referer. I'm not sure what you've tried as far as adding https:// versions of what you have in your referer checks, but this works when I put them in a blank htaccess file:
RewriteEngine On
RewriteCond %{HTTP_REFERER} !^http://www.website_abc.com/
RewriteCond %{HTTP_REFERER} !^http://www.website_xyz.com/
RewriteCond %{HTTP_REFERER} !^https://www.website_abc.com/
RewriteCond %{HTTP_REFERER} !^https://www.website_xyz.com/
RewriteRule /* http://www.mysite.com/denied_message.php [R,L]

mod_rewrite based on ip

I'd like to implement mod_rewrite to put my site into maintenance. Basically all IP addresses except a handful we specify would be forwarded to a static html page.
Please can someone help with this rule. Also is there a way to turn this on and off easily without editing the htaccess file?
You can use the REMOTE_ADDR variable in a RewriteCond
RewriteCond %{REMOTE_ADDR} !^10\.0\.1\.1$
RewriteRule ^ /maintenance.html
Just change the condition to match the IPs you want, for more than one you can use ^(ip1|ip2|...|ipn)$.
About how to disable the maintenance mode without changing the .htaccess file I think that's not possible short of writing a program that would delete it or otherwise modify it, an easy one would be to rename it.
I'd like to slightly correct Vinko Vrsalovic's answer.
RewriteCond %{REMOTE_ADDR} !^10\.0\.1\.1$
RewriteRule ^ /maintenance.html
This rule result will be infinite loop and HTTP server error, because it will be executed on redirection page too. To make it work you should exclude redirection page from the rule. It can be done this way:
RewriteCond %{REMOTE_ADDR} !^10\.0\.1\.1$
RewriteCond %{REQUEST_URI} !/maintenance.html$ [NC]
RewriteRule .* /maintenance.html [R=302,L]
Small improvement to Alexander's answer, it's not necessary to use regular expression for the IP address.
RewriteCond %{REMOTE_ADDR} !=10.0.0.1
RewriteCond %{REQUEST_URI} !/maintenance.html$ [NC]
RewriteRule .* /maintenance.html [R=302,L]
you could enable this state and disable it via some admin interface that is able to write to .htaccess (e.g. permissions set to 755 or 777). it would just always find the .htaccess, insert those two lines at the beginning and on disabling maintenance it would delete those two lines, leaving the rest of the file untouched
Optional redirect only specific addresses
Late to the party, and just an add-on if somebody needs it the other way around.
With this approach, you redirect only specific addresses into maintenance then play with the aliases.
ServerName 10.0.1.1
ServerAlias 10.0.2.1
ServerAlias 10.0.3.1
RewriteEngine On
RewriteRule ^(.*)$ http://www.domainname.com/maintenance.html$1 [L,R=301]

Redirect all IPs except those whitelisted

I want to protect some subdomains from the public. Restriction should be done against a whitelist of IPs.
Infinite loop due to the redirect is not a problem as its not the www-domain.
I tried this http://discussions.apple.com/message.jspa?messageID=2411725, but couldnt get it to work.
However I did try this first
RewriteEngine on
RewriteCond %{REMOTE_ADDR} !^123\.45\.67\.89$ [OR]
RewriteCond %{REMOTE_ADDR} !^213\.45\.67\.89$
RewriteRule ^/.* http://www.mydomain.com [R]
.. but didnt work.
What am I doing wrong ?
This kind of thing is actually exactly what Apache's Allow and Deny directives are intended for. Inside the <VirtualHost> block for the domain you want to restrict access to, put this:
<Location />
Order allow,deny
Allow from all
Deny from 123.45.67.89
Deny from 213.45.67.89
</Location>
However, this would produce a 403 (forbidden) error, which doesn't redirect to your www domain by default. I think you can make it do so by adding the directive
ErrorDocument 403 http://www.example.com
You have to combine the RewriteCond directives with AND instead of OR as you want to redirect if both conditions are true (therefor the IP address is neither X nor Y). So try this:
RewriteEngine on
RewriteCond %{REMOTE_ADDR} !^123\.45\.67\.89$
RewriteCond %{REMOTE_ADDR} !^213\.45\.67\.89$
RewriteRule ^ http://www.example.com/ [R]