Dynamic IP .htaccess blocklist? - apache

Is it possible to block users from IP adresses with a dynamic file-based blocklist?
So, suppose the .htaccess looks like:
order Deny,Allow
Deny from 123.156.0.1
Deny from 10.0.0.10
Allow from all
Can this list be made dynamic, for example:
order Deny,Allow
[include Deny list here]
Allow from all
Another option would of course be to fix it with PHP, but it is preferable to let Apache handle this.

According to the Apache docs, it doesn't seem to be possible to read values from a text file.
However, you could include a configuration file containing the IP addresses. They would have to be in Apache's conf file format, though.
This should work:
order Deny,Allow
include conf/IPList.conf
Allow from all
It's even possible to include whole directories, even though it's not recommended.

I use the RewriteMap feature from Apache's RewriteModule, as a whitelist like this:
## WHITELIST IPS ##
RewriteMap ipslist txt:/path/to/whitelist.txt
RewriteCond %{REMOTE_ADDR} ^(.*)$
RewriteCond ${ipslist:%1|black} ^black$ [NC]
RewriteRule (.*) - [F]
With some tweaking, you could make this a blacklist.

Related

htaccess use of Order Deny,Allow

I'm using Order Deny,Allow in my .htaccess file, without success. IP's I need to prevent access to are going right through with no troubles. I read that as of Apache 2.4 Order Deny,Allow would no longer work; first is that factual and second if so what has replaced it? I cannot access my httpd.conf file, so Require and Require not is not an option for me.
I only have access to .htaccess, how can I accomplish banning by ip or if no longer possible, redirecting by ip. Below is a snipit of my Order Deny,Allow if it matters. Thanks in advance!
Order Deny,Allow
Deny from 123.125.71.*
Deny from 123.125.71.121.some.domain.com
Deny from some.domain.com
Allow from All
(as you can see, I'm attempting to block the same ip, in various formats but no matter the format, the traffic continues to go through.)
To push the undesired ip to 403 ,you can use the following rule :
RewriteEngine on
RewriteCond %{REMOTE_ADDR} ^00\.00\.00\.00$
RewriteRule ^ - [R=403,L]
Replace 00.00.00.00 with your undesired ip address.
To ban multiple ipaddress, you can add multiple conditions seprated by a [OR] flag to your rule :
RewriteEngine on
RewriteCond %{REMOTE_ADDR} ^00\.00\.00\.00$ [OR]
RewriteCond %{REMOTE_ADDR} ^00\.00\.00\.00$
RewriteRule ^ - [R=403,L]

Denying access to URLs then IP blocks in htaccess

I'm trying to block bad bots from clicking certain links to one site running Apache 2.4. Here is what I am trying in htaccess:
RewriteEngine On
# Check for the suspect querystring first
RewriteCond %{QUERY_STRING} gclid=(.*)
RewriteRule .* - [E=IsAdClick:1]
# Filter on those requests with an ad string
<IfDefine IsAdClick>
# BAN USER BY IP
Order Deny,Allow
Deny from 172.64.0.0/13
Deny from 173.245.48.0/20
...
</IfDefine>
The deny rules work if they are by themselves, but for the life of me I cannot get the conditional to work. I've tried other things like
<If "%{QUERY_STRING} =~ /gclid=.*?/">
# BAN USER BY IP
Order Deny,Allow
Deny from 172.64.0.0/13
Deny from 173.245.48.0/20
...
</If>
but there is no effect. Traffic still comes through. What am I missing? I don't want to write a whole bunch of RewriteCond for each IP, nor change the .config files. Thanks.
Update: According to this SO post it seems that IfDefine only responds to command line parameters. Ref:
The IfDefine directive in Apache, Only , ONLY and when I say only i
mean ONLY, responds to parameters passed at the command line. Let me
emphasize that a little. ONLY COMMAND LINE!
How to achieve the effect I'm looking for though?
This took a lot of trial and error, but this seems to be working on THE_REQUEST which include any querystring data:
# Filter on those requests with an adwords string
<If "%{THE_REQUEST} =~ /gclid=/i">
# BAN USER BY IP
Order Deny,Allow
Deny from 172.64.0.0/13
Deny from 173.245.48.0/20
...
</If>
Still, I'd like to know why my second attempt in my question failed.

Multiple domains in one htaccess and have limited access to only one

I don't know if it is possible. I have three domains in one .htaccess and pointing to a shared location:
domain-a.com
domain-b.com
domain-c.com
And now i want to block domain-c.com for all traffic and allow access from only two ip's. Domain-a.com and domain-b.com have to stay untouched.
I have tried to use this code in the .htaccess.
order deny,allow
deny from all
allow from x.x.x.x
I just don't know how to get it to work for one domain only instead of three.
To deny access to the domain , you can use the following :
RewriteEngine on
RewriteCond %{HTTP_HOST} ^(www\.)?domain_c.com$
#--allowed ip(s)--#
RewriteCond %{REMOTE_ADDR} !^(ip1|ip2)$
RewriteRule ^ - [F,L]

Block IP access to specific page only

I need to block access from a certain IP address to one page of a website only, not the entire website.
Here's what I have, but doesn't seem to be working (I switch out offending IP to mine and am still abel to access after refresh/cache dump etc)
<Files specificpage.php>
order deny,allow
deny from XX.XXX.XXX.XX
</Files>
Is there a better way of doing this or does anything jump out here?
thx
You can actually mod_rewrite rules for finer control here. Place this in your root .htaccess:
RewriteEngine On
RewriteCond %{REMOTE_ADDR} =XX.XXX.XXX.XX
RewriteRule ^specificpage\.php$ - [F,NC]

prevent directory access using setenvif

I would like to use SetEnvIf to block directory access to specific ip addresses.
here is what i came up with.
<Directory /main>
order allow,deny
SetEnvIf Remote_Addr ^(2|5|6)\. banned [OR]
SetEnvIf Remote_Addr ^(7|8|9)\. banned
allow from all
deny from env=banned
</Directory>
the (2|5|6)\. and (7|8|9)\. are wildcarded ip address examples,
I am trying to prevent those ranges from accessing the main directory on my server.
but not sure if the [OR] and the wildcarded ip addresses will work.
Also how can i redirect the banned to http://officeofstrategicinfluence.com/spam/
instead of just denying or blocking them?
[OR] cannot be used like the way you have used but it can be used as per the regex syntax. Try this code:
<Directory /main>
SetEnvIf Remote_Addr ^(2|5|6|7|8|9)\. banned
order allow,deny
allow from all
deny from env=banned
</Directory>
Also note that <Directory> directive only works in Apache config not in .htaccess
UPDATE: As per comments, you can use this rewrite rule in your root .htaccess:
RewriteEngine On
RewriteCond %{REMOTE_ADDR} ^(2|5|6|7|8|9)\.
RewriteRule ^main(/|$) http://officeofstrategicinfluence.com/spam/ [NC,L,R]