Forum Discussion

Chris_Atkins's avatar
Chris_Atkins
Icon for Nimbostratus rankNimbostratus
Mar 12, 2020

Whitelist certain traffic in an existing irule

So the current irule is this

 

when HTTP_REQUEST {

if   { [HTTP::method] equals "TRACE" } {

  reject 

  }

elseif {[string tolower [HTTP::host]] equals "website.com"} {

  pool website.com443}

elseif {[string tolower [HTTP::host]] equals "website2.com"} {

  pool website2.com443}

}

}

 

So all traffic comes to a single IP and is separated to the different sites/pools. I need to whitelist traffic to one of the sites, only allowing RFC 1918 and some /24s from a /16. From researching I think it's something like this.

when HTTP_REQUEST {

if   { [HTTP::method] equals "TRACE" } {

  reject 

  }

elseif {[string tolower [HTTP::host]] equals "website.com"and [class match [IP::client_addr] equals ALLOWED] } {

  pool website.com443}

elseif {[string tolower [HTTP::host]] equals "website.com"} and { [class match [IP::client_addr] equals DENIED] } {

  reject}

elseif {[string tolower [HTTP::host]] equals "website2.com"} {

  pool website2.com443}

}

}

 

With the allowed IPs in ALLOWED datagroup and denied IPs in Denied.

Would this work?

Will it interfere with the other sites?

 

Thanks in advance

 

Realized after writing that I probably don't need the DENIED group as anything else still going to that site in the rule order could just be rejected. Left it in case I do need it

3 Replies

  • You don't need to check for the TRACE method in the iRule. You can simply create a custom HTTP profile and remove TRACE (and any other methods you don't want to allow) from the Known Methods list. That way your iRule deals with just the pool selection and all TRACE requests are disallowed, no matter where they originate.

    With respect to validating the IP addresses, yes, a single datagroup of whitelisted IP addresses (or address ranges) is the way to go. If an HTTP request arrives from an IP address not in the whitelist datagroup , it can be rejected. So perhaps something like the following:

    when HTTP_REQUEST {
         if { [HTTP::host] equals "website.com" and [class match [IP::client_addr] equals IP_WHITELIST] } {
              pool website.com443
         } elseif { [HTTP::host] equals "website2.com" } {
              pool website2.com443
         }
    }

    With respect to whether or not this will interfere with other sites, I'm not quite sure what you mean. In the state above, only traffic to website.com and website2.com are allowed. Requests for other hosts, such as website3.com will fail. If there are other hosts you need to support with this one virtual server/iRule combo, then you can add an "else" clause to the "if" statement to select the pool for all other traffic, or other "elseif" clauses to select the appropriate pool by hostname, as needed.

    • Chris_Atkins's avatar
      Chris_Atkins
      Icon for Nimbostratus rankNimbostratus

      Excellent, thank you.

       

      As far as affecting the other websites in the rule, I just wanted to make sure I hadn't written it in a way that would deny traffic to other sites in the list.

       

      I see you took out the deny version altogether, would users with the non whitelist IP see a slow time out then or a reset?

       

      It might not matter since we don't want them connecting anyways, but maybe the app owner wants users trying to connect to know it was reset instead of maybe the site is down.

  • Yes, you probably should include an explicit reject (or drop) as the default condition (else) if traffic does not match any of your rules. It depends on whether you want to alert the client via a reset or just silently drop the connection.