Technical Forum
Ask questions. Discover Answers.
cancel
Showing results for 
Search instead for 
Did you mean: 

iRule to protect a URI pattern by subnet?

Mark_Gallagher
Altocumulus
Altocumulus

Good day,

I have been trying several approaches on BIG-IP/LTM 12.1.3.7 to achieve the following goal:

A VIP listens on an IP where most of the traffic is bound for web content, let's say https://something.company.com/content/blahblahblah. anything that does not start with /manage basically.

Some admins will come from internal RFC 1918 source IPs and should be allowed to access https://something.company.com/admin/blablabla

Any other requests not from this broad RFC 1918 subnet for /admin should be dropped/rejected/redirected to a sorry page or so.

I seems like it should be simple to do this via an iRule like so:

when HTTP_REQUEST {
  set httpUri [string tolower [HTTP::uri]]
  set clientIp [class match -value [IP::client_addr] equals datagroup_allowed_ip_www_manage]
  if { $httpUri starts_with "/admin" && $clientIp equals "" } {
    drop
  } else {
    pool prd-pl-company
  }
}

The datagroup includes some rfc-1918 addresses like so:

ltm data-group internal /Common/datagroup_allowed_ip_www_manage {
    records {
        192.168.0.0/16 { }
    }
    type ip
}

The above approach does not work. Non /manage requests will fall through to the VIP and anything with /manage will be dropped regardless of source IP.

I've tried this with a a line in the irule to specify the subnet using /16 or 192.168.0.0/255.255.0.0 rather than the datagroup but it doesn't work either.

I've tried with a policy like so:

ltm policy /Common/pol-admin-isolate {
    controls { forwarding }
    description "policy admin network isloate"
    last-modified 2019-10-28:05:45:55
    requires { http tcp }
    rules {
        prd-pol-admin-isolate-allow-internal-cli-net {
            actions {
                0 {
                    forward
                    select
                    pool /Common/prd-pl-company
                }
            }
            conditions {
                0 {
                    tcp
                    address
                    case-sensitive
                    matches
                    values { 193.168.0.0/16 }
                }
                1 {
                    http-uri
                    path
                    normalized
                    starts-with
                    values { /admin }
                }
            }
        }
        prd-pol-www-manage-isolate {
            actions {
                0 {
                    forward
                    reset
                }
            }
            conditions {
                0 {
                    http-uri
                    path
                    normalized
                    starts-with
                    values { admin }
                }
            }
            ordinal 1
        }
    }
    strategy /Common/first-match
}

This works exactly like the iRule.

I must be overlooking something, but I cannot figure out what it might be. Anyone have any luck doing something similar?

Thanks,

Mark

2 REPLIES 2

JG
Cumulonimbus
Cumulonimbus

Try the following:

when HTTP_REQUEST {
    if { ([string tolower [HTTP::uri]] starts_with "/admin") && not ([IP::addr [IP::client_addr] equals 192.168.0.0/16]) } {
        drop
    } else {
        pool prd-pl-company
    }
}

.

Thanks for the input JG. I did try this (also with an exclamation point outside the parentheses) and it doesn't seem to match. I have definitely been able to get the match to work with a large list of /32 addresses, but never the /16.

This what I tried as far as what they were recommending in a KB for efficient subnet matching:

when HTTP_REQUEST {
 if {( [string tolower  [HTTP::uri]] contains "/admin") && (not[IP::addr [IP::remote_addr] equals 192.168.0.0/255.255.0.0])} { 
        HTTP::respond 503 content {