homepage Welcome to WebmasterWorld Guest from 54.242.18.190
register, free tools, login, search, pro membership, help, library, announcements, recent posts, open posts,
Become a Pro Member

Home / Forums Index / Code, Content, and Presentation / Apache Web Server
Forum Library, Charter, Moderators: Ocean10000 & incrediBILL & phranque

Apache Web Server Forum

    
Apache RewriteMap - White List IPs and IP Ranges
AndyJax




msg:4574753
 3:53 pm on May 16, 2013 (gmt 0)

I am trying to use the RewriteMap directive in Apache to "white list" (allow only) a mix of certain ranges of IPs and with specific IPs. What makes this tricky for me is that the whitelist will contain a mix of large ranges of IPs such as 131.132.* (or in CIDR notation it would be 131.132.0.0/16) plus specific IPs also in the same list. My understanding is that you cannot use CIDR notation in mod_rewrite because RewriteConds just do simple text-string/character comparisons (Is this correct?). So far, this is what I have come up with for my RewriteMap directive, but not sure it will work. Do you think the following will work to whitelist ranges of IPs in 131.132.*.* (131.132.0.0/16) ... i.e. start range 131.132.0.0 to end range 131.132.255.255) and the range 121.122.123.* (i.e. start range 121.122.123.0 to end range 121.122.123.255) and the specific IP 111.112.113.114, and will block all other IPs? Also, will the back references (%1, %2, %3, %4) in the last three RewriteCond lines (note the RewriteCond lines are "OR'ed") work properly referring back to the first RewriteCond line for all references?

RewriteMap ipslist txt:"/path/to/whitelist.txt"
RewriteCond %{REMOTE_ADDR} ^(\d+)\.(\d+)\.(\d+)\.(\d+)$
RewriteCond ${ipslist:%1.%2.%3.%4|block} ^block$ [OR]
RewriteCond ${ipslist:%1.%2.%3.*|block} ^block$ [OR]
RewriteCond ${ipslist:%1.%2.*.*|block} ^block$
RewriteRule (.*) - [F]

####
#### in whitelist.txt file
####
111.112.113.114 allow
121.122.123.* allow
131.132.*.* allow

 

phranque




msg:4574794
 8:08 pm on May 16, 2013 (gmt 0)

the %N backreferences will use the last matched RewriteCond so you should be okay there.
you could test it from some known IPs...

lucy24




msg:4574808
 8:40 pm on May 16, 2013 (gmt 0)

My understanding is that you cannot use CIDR notation in mod_rewrite because RewriteConds just do simple text-string/character comparisons (Is this correct?).

It depends on what Apache version you're on. I read somewhere-- but now can't find the definitive reference-- that 2.4 adds CIDR functionality to mod_rewrite. Be still my thundering pulse.

Back references refer to "the most recent MATCHED Condition". A group of [OR]-delimited conditions is functionally the same as a single pipe-delimited group. That is, if the first "OR" doesn't match, it simply doesn't count and mod_rewrite continues to the next condition in the set. (If you've got a package that can go either way, the [OR] version runs faster but the pipe version may be easier for a human to read. You can't win.)

For comparison purposes I tried this in my test site. If I request the page /detour.html, I should get redirected. On the surface it looks different from your ruleset, but the underlying structure is the same:

RewriteCond %{REQUEST_URI} !test-three
RewriteCond %{THE_REQUEST} (GET)\ (/[^.\s]+\.html)
RewriteCond %1 HEAD [OR]
RewriteCond %2 detour
RewriteRule .* http://www.example.com/hoosegow/test-three.html [R=301,L]

(I could tell it was working when I got a browser error "infinite redirect loop" and hastily added the first Condition :)) Here it's skipping a non-matched Condition-- the HEAD line-- and continuing to the next Condition.

Deeper question: Are you certain that a RewriteMap is the most efficient way to achieve the result you want? I think most people would use mod_authz-whatsit in "Deny,Allow" order. A rule that potentially requires consulting the same map up to three times on every single request seems like a last-resort approach. At a minimum, you can probably constrain the rule to page requests; very few robots ask for images and stylesheets, and you've probably got hotlink code already. The Rule itself then says

RewriteRule (^|\.html|/)$ - [F]

substituting whatever extension(s) you actually use.

AndyJax




msg:4574939
 12:27 pm on May 17, 2013 (gmt 0)

Thanks for the replies. Unfortunately I can only test in a live production environment which gives me heart burn. Still scratching my head a bit. One of my main uncertainties is whether or not the RewriteCond conditions of %1.%2.%3.%4 , %1.%2.%3.* , and %1.%2.*.* will find the proper matching entries in the whitelist file. For example, if a request were to come in from IP 121.122.123.101, would it find the match on the 121.122.123.* entry in the whitelist file. Not sure about the '*'s in the last two RewriteCond directives. Thanks for your help on this.

AndyJax




msg:4574991
 2:56 pm on May 17, 2013 (gmt 0)

Also, to answer your question Lucy24, I am trying to use RewriteMap so we could update the list of whilelisted IPs in an external file so that we don't have to restart apache. My understanding is that with RewriteMap using a separate file, it will re-load its cache whenever the external whitelist file's modified timestamp changes.

lucy24




msg:4575090
 8:07 pm on May 17, 2013 (gmt 0)

Ah, you're the exceptional user who has his own server. Most questions come from people on shared hosting using htaccess. Now, if the whitelisting only applied to one directory, you could make a separate htaccess. But obviously no go for the entire site.

<snip, snip>

At this point I edited out a long and complicated reply because I realized I'm not sure you even can use a RewriteMap within a RewriteCond. Have you tried? I can't find anything about it in the docs.

If g1smd were here, I suspect he would tell you to rewrite --not redirect-- all requests to a php script which does the lookup and then either sends users to the requested page or issues a 403. (Your server logs will show everything as a 200, but do not panic. They are getting their 403s, honest.) Unlike your server, this php file can be replaced and updated at any time. I assume the list of Good Addresses isn't enormously long; I don't think we're even looking at a separate database, just a list of numbers.

AndyJax




msg:4576174
 12:41 pm on May 21, 2013 (gmt 0)

From what I have seen out there, yes you can use RewriteMap within a RewriteCond, although I have not tried it myself. The architect here does not want to use an external script for this for security reasons. My main concern is whether or not the back references (%1, %2, %3, %4, etc.) in the last three RewriteCond lines (note the RewriteCond lines are "OR'ed") work properly referring back to the first RewriteCond line for all references and if it will properly search for matches on n.n.n.* or n.n.*.* in the whitelist file?

phranque




msg:4576176
 12:50 pm on May 21, 2013 (gmt 0)

welcome to WebmasterWorld, AndyJax!

the %N backreferences will use the last matched RewriteCond

AndyJax




msg:4576187
 1:16 pm on May 21, 2013 (gmt 0)

Thanks. I will go ahead and try it out. Thanks for your help.

AndyJax




msg:4579020
 1:54 pm on May 29, 2013 (gmt 0)

The following is how I got it working:

WHITELIST IPS ##
RewriteMap ipslist txt:/path/to/whitelist.txt
RewriteCond %{REMOTE_ADDR} ^(\d+)\.(\d+)\.(\d+)\.(\d+)$
RewriteRule .* - [E=Va:%1,E=Vb:%2,E=Vc:%3,E=Vd:%4]
RewriteCond ${ipslist:%{ENV:Va}.%{ENV:Vb}.%{ENV:Vc}.%{ENV:Vd}|black} ^black$
RewriteCond ${ipslist:%{ENV:Va}.%{ENV:Vb}.%{ENV:Vc}.*|black} ^black$
RewriteCond ${ipslist:%{ENV:Va}.%{ENV:Vb}.*.*|black} ^black$
RewriteRule (.*) - [F]

Global Options:
 top home search open messages active posts  
 

Home / Forums Index / Code, Content, and Presentation / Apache Web Server
rss feed

All trademarks and copyrights held by respective owners. Member comments are owned by the poster.
Home ¦ Free Tools ¦ Terms of Service ¦ Privacy Policy ¦ Report Problem ¦ About ¦ Library ¦ Newsletter
WebmasterWorld is a Developer Shed Community owned by Jim Boykin.
© Webmaster World 1996-2014 all rights reserved