Forum Discussion
DarkSideOfTheQ_
Nimbostratus
Sep 16, 2009Restrict access based off source network
Hello All,
Sanity check...I'm trying to block access to specific pages based off the source network the client is coming from. The rest of the site should remain available to anyone. I *think* I've got the irule down, but am not 100% sure and would appreciate some more knowledgeable input.
Pages to block:
http://our.domain.com/templates/Test.jsp
http://our.domain.com/templates/Stats.jsp
Data Group "internal-ips"
1.1.1.0/24
2.2.2.0/24
3.3.3.0/24
when HTTP_REQUEST {
if { ([HTTP::uri] contains "Test.jsp") or ([HTTP::uri] contains "Stats.jsp") and not ([matchclass [IP::client_addr] equals [$::internal-ips]]) } {
discard
}
}
TIA,
DarkSide
19 Replies
- hoolio
Cirrostratus
That will technically work. However, even with java-based platforms there are methods an attacker can use to obfuscate their request. We discussed this in a recent post:
Irule for restriciting URL paths unsecure
http://devcentral.f5.com/Default.aspx?tabid=53&forumid=5&tpage=1&view=topic&postid=30900
Aaron - The_Bhattman
Nimbostratus
Hi Darkside,
I think your logic looks sound. I would put a open and close parentheses around the URI conditional evaluations so they are evaluated together before the matchclass evaluation. I would also lose the square brackets around $::inernal-ips and lowercase the URI
Like sowhen HTTP_REQUEST { if { !([matchclass [IP::client_addr] equals $::internal-ips]) and ((string tolower [[HTTP::uri]] contains "test.jsp") or (string tolower[HTTP::uri]] contains "stats.jsp")) } { discard } }
Another way to right this is the following:when HTTP_REQUEST { if { !([matchclass [IP::client_addr] equals $::internal-ips]) } { switch -glob [string tolower [HTTP::uri]] { "*test.jsp" - "*stats.jsp" { discard } } } }
I wrote it the way above because I thought the first thing you want to evaluate is the Datagroup. if nothing matches then don't evaluate any further. In theory, it would make evaluations much faster then having to evaluate 3 conditions expressions in an IF clause.
I hope this helps
CB - DarkSideOfTheQ_
Nimbostratus
Aaron - good post, not sure how i missed that in my earlier search. I didn't even think about obfuscation as I don't think the page is all that "secret", so a basic discard should suffice, but I'll have to ask.
CB - In your examples, (I'm probably misinterpreting them) it looks like the logic would discard if the client IP matches the data group, is that right? - hoolio
Cirrostratus
Also, if you use a hyphen in a class name, you need to reference it using curly braces ${::class-name}. It's easier to just use underscores.
Aaron - hoolio
Cirrostratus
The idea behind obfuscation is that an attacker could request /test.jsp as /%74%65%73%74.jsp using URL encoding, possibly use unicode as / \ x 74 \ x 65 \ x 73 \ x 74.jsp (without the spaces) and/or other encoding methods and the web server would potentially parse them all as /test.jsp even though the iRule doesn't.
Aaron - The_Bhattman
Nimbostratus
Hi Darkside,
My examples are assuming to discard IF it does not come from address in the source group.
CB - DarkSideOfTheQ_
Nimbostratus
Aaron - In that other post you linked me to, you mention an irule isn't the best approach to dealing with obfuscation. How would you recommend handling that if I am told they want it secured better?
CB - I figured I wasn't interpreting it correctly, not seeing 'else' mentioned in there threw me off. In terms of making evaluations faster, could i put the 'switch -glob....' part before the data group? In theory, it would stop processing if it didn't see 'test.jsp' or 'stats.jsp', correct?
-DarkSide - The_Bhattman
Nimbostratus
If you do that you would have to add the datagroup within the switch. It all depends on what condition you want to see evaluated first.
CB - DarkSideOfTheQ_
Nimbostratus
OK - i'm officially lost here. I put in the irule I first posted. However, it seemed to discard anything, I couldn't get to the page from a host specified by network or specifically. I added in the log value and saw it in the logs, but the page no workie. I removed the discard piece and could access the pages. Unfortunately, I could access them from hosts not specified in my datagroup. Where is this breaking down???when HTTP_REQUEST { if { ([HTTP::uri] contains "Test.jsp") or ([HTTP::uri] contains "Stats.jsp") and not ([matchclass [IP::client_addr] equals [$::ips_internal]]) } { log local0. "test connection from [IP::client_addr] to [HTTP::uri]" } }
From log:
Sep 16 16:46:07 tmm tmm[959]: Rule secure_test : test connection from to /templates/Test.jsp
Sep 16 16:46:31 tmm tmm[959]: Rule secure_test : test connection from to /templates/Test.jsp
Goal: restrict access to the 'test.jsp' and 'stats.jsp' from anyone except specific internal networks, rest of site needs to remain open to anyone.
Edit: Actually, since I removed the 'discard' for testing, I know that's why it's allowing anyone not in my datagroup to access those pages. However, shouldn't I only see in the logs, hosts/networks specified in my datagroup?
-DarkSide - hoolio
Cirrostratus
You could add more logging to find out what's happening:when HTTP_REQUEST { log local0. "[IP::client_addr]:[TCP::local_port]: Request to [HTTP::uri]" if { ([HTTP::uri] contains "Test.jsp") or ([HTTP::uri] contains "Stats.jsp") and not ([matchclass [IP::client_addr] equals $::ips_internal]) } { log local0. "[IP::client_addr]:[TCP::local_port]: Discarding request to [HTTP::uri]" discard } }
Also, as CB pointed out, you should remove the square braces around the datagroup name. That would probably trigger a runtime TCL error as you'd be trying to execute the contents of the class. If that still doesn't work, you could break up the URI and IP address checks into separate if statements with more logging.
Aaron
Recent Discussions
Related Content
DevCentral Quicklinks
* Getting Started on DevCentral
* Community Guidelines
* Community Terms of Use / EULA
* Community Ranking Explained
* Community Resources
* Contact the DevCentral Team
* Update MFA on account.f5.com
Discover DevCentral Connects
