Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Apache rewrite subnet ip range

Can someone please tell me how to put the following IP ranges (belongs to Cloudfront) in a mod_rewrite? I am looking to redirect the non-www requests for example.com to www.example.com BUT not redirect any IP address coming from IP Ranges below:

54.192.0.0/16
54.230.0.0/16
54.239.128.0/18
54.239.192.0/19
54.240.128.0/18
204.246.164.0/22
204.246.168.0/22
204.246.174.0/23 
204.246.176.0/20 
205.251.192.0/19 
205.251.249.0/24 
205.251.250.0/23 
205.251.252.0/23 
205.251.254.0/24 
216.137.32.0/19 

I used a tool called rgxg to convert all of the above from CIDR to Regex and created the following entries in my httpd.conf:

    RewriteCond %{HTTP_HOST} ^example\.com$ [NC,OR]

    RewriteCond %{HTTP:X-FORWARDED-FOR} !54\.192(\.(25[0-5]|2[0-4][0-9]||1[0-9]{2}|[1-9]?[0-9])){2} 

    RewriteRule ^/(.*)?$ http://www.example.com/$1 [R=301,NC,NE,L]

I have added all the ip ranges in my RewriteCond entries but included only the first one as I didn't want to clutter this post. The rule don't appear to work. If I put just a single IP address, it works without a problem.

Can someone please check and see what I'm doing wrong?

Thanks! -Ma

like image 218
Ma Diga Avatar asked Jun 28 '14 16:06

Ma Diga


2 Answers

If you're using Apache HTTPD 2.4 or later, you can also use expressions to match REMOTE_ADDR against a CIDR mask directly, instead of converting these to regexps.

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'"
like image 182
zts Avatar answered Oct 16 '22 12:10

zts


Let's look at the first range:

54.192.0.0/16

In the regex

54\.192(\.(25[0-5]|2[0-4][0-9]||1[0-9]{2}|[1-9]?[0-9])){2} 

Notice the double ||. Given how hard it is to debug, if there is even one mistake, I don't feel bad throwing the whole thing away.

The following is not quite exact because it would match fragments up to 999, but all that matters is that it catches all IPs in the range, and no other valid IPs. It does.

54\.192\.[0-9]{1,3}\.[0-9]{1,3}

And it's easy to read. I would recommend using that instead. Try it, and if that works, the other ones can also be revisited.

I am not sure how you receive the IP, but depending on context this is another option:

RewriteCond %{REMOTE_ADDR} !^54\.192\.[0-9]{1,3}\.[0-9]{1,3}$

Let's look at some potential ranges:

54.192.0.0/16 => ^54\.192\.[0-9]{1,3}\.[0-9]{1,3}$
54.230.0.0/16 => ^54\.230\.[0-9]{1,3}\.[0-9]{1,3}$
54.239.128.0/18 => ^54\.239\.(?:19[01]|1[3-8][0-9]|12[89])\.[0-9]{1,3}$
54.239.192.0/19 => ^54\.239\.(?:22[0-3]|2[01][0-9]|19[2-9])\.[0-9]{1,3}$
54.240.128.0/18 => ^54\.240\.(?:19[01]|1[3-8][0-9]|12[89])\.[0-9]{1,3}$
204.246.164.0/22 => ^204\.246\.16[4-7]\.[0-9]{1,3}$
204.246.168.0/22 => ^204\.246\.(?:17[01]|16[89])\.[0-9]{1,3}$
204.246.174.0/23  => ^204\.246\.17[45]\.[0-9]{1,3}$
204.246.176.0/20 => ^204\.246\.(?:19[01]|18[0-9]|17[6-9])\.[0-9]{1,3}$
205.251.192.0/19 => ^205\.251\.(?:22[0-3]|2[01][0-9]|19[2-9])\.[0-9]{1,3}$
205.251.249.0/24 => ^205\.251\.249\.[0-9]{1,3}$
205.251.250.0/23 => ^205\.251\.25[01]\.[0-9]{1,3}$
205.251.252.0/23 => ^205\.251\.25[23]\.[0-9]{1,3}$
205.251.254.0/24 =>  ^205\.251\.254\.[0-9]{1,3}$
216.137.32.0/19 => ^216\.137\.(?:6[0-3]|[45][0-9]|3[2-9])\.[0-9]{1,3}$
like image 38
zx81 Avatar answered Oct 16 '22 12:10

zx81