I recently came across this troubling situation, received a request where a team wanted allow access to a specific user agent with a particular range of IPs.
the requirement was to specifically add this in htaccess file.

In simple terms i wanted to achieve something like, ┬áIf User-Agent=”Prerender”&& Remote_Addr=^54. allow from all

However Apache version 2.2 do not support If statement

Note: You can check the apache version by using below commands on linux

[explorer@Linuxserver ~]$ rpm -qa | grep http
httpd-2.2.3-92.el5_11

[explorer@Linuxserver ~]$ /usr/sbin/apachectl -version
Server version: Apache/2.2.3

So i came up with something like this:

SetEnvIf User-Agent “.*” passit=0 Iprange=0 combi=1
SetEnvIfNoCase User-Agent “Prerender” passit=1
SetEnvIf Remote_Addr “^54\.” Iprange=1
SetEnvIf passit 0 combi=0
SetEnvIf Iprange 0 combi=0
SetEnvIf combi 1 passboth
Allow from env=passboth

In above hack I was able to get the result i wanted.
Logic here is, i can get A AND B by —–> NOT ( (NOT A) OR (NOT B) )

Coming back to what i have done..
First Line:
I set three env vaiable initially. passit to false, Iprange to false and combi to true. “.*” means for any user agent.
Second line:
Here i set passit to true only if the User-Agent is Prerender. SetEnvIfNoCase instruct that the User-Agent will be case insensitive.
Third Line:
Setting the env varibale to Iprange to ture for ip range that start with 54.
Third and the fourth line:
Again setting env variable combi to false if either passit or Iprange is false/zero. Which means now the variable combi will be true/one only when
passit or Iprange both are true.

For Apache 2.4 its quite easy with “Require directives”:

Require all granted : Access is allowed unconditionally
Require all denied : Access is denied unconditionally.
Require env env-var [env-var] : Access is allowed only if one of the given environment variables is set.
Require method http-method [http-method] : Access is allowed only for the given HTTP methods.
Require expr expression : Access is allowed if expression evaluates to true.

You can use below configuration:
<RequireAll>
Require expr “%{HTTP_USER_AGENT} == ‘Prerender’ && %{REMOTE_ADDR} -ipmatch ‘192.168.1.0/24′”
Require all granted
</RequireAll>

For those getting confused, RequireAll means that all the requirements in that container need to be met, while RequireAny means that only one or more of the contained requirements should met.

Leave a Reply

Your email address will not be published. Required fields are marked *

You may use these HTML tags and attributes:

<a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>