Forum Discussion

Chris_Miller's avatar
Chris_Miller
Icon for Altostratus rankAltostratus
Aug 12, 2010

Limit Access to URI to HTTPS and IP

I'm interested in the best way to do this. I want to limit access to the URI "/sample" to users from IP 1.1.1.1 while also only allowing said access to be HTTPS. If someone tries hitting it over HTTP, I don't want to send a redirect, I want to reject it.

Here's what I'm thinking:


when HTTP_REQUEST {
if { [HTTP::uri] eq "/sample" and !( [HTTP::header "True-Client-IP"] eq 1.1.1.1 } ) {
reject } }
Now how do I go about adding in the fact that it has to be over HTTPS? Do I need to use [TCP::local_port]? It looks like that's not a valid command within HTTP_REQUEST.

I also notice there's a "URI::port" and a "URI::protocol" command?

http://devcentral.f5.com/wiki/default.aspx/iRules/URI__port.html

http://devcentral.f5.com/wiki/default.aspx/iRules/URI__protocol.html

6 Replies

  • You might try something like this:

    when HTTP_REQUEST {
    if { [HTTP::uri] eq "/sample" and !( [HTTP::header "True-Client-IP"] eq 1.1.1.1 } ) and !([TCP::client_port==80]) {
    reject } }
  • Is it just possible to have your VIP listening only on port 443? If it is only listening on that then the traffic will never get redirected from port 80 to 443....
  • Posted By naladar on 08/12/2010 07:17 AM

     

    Is it just possible to have your VIP listening only on port 443? If it is only listening on that then the traffic will never get redirected from port 80 to 443....

     

     

    Negative - this is our main HTTP/HTTPS VIP.
  • Posted By naladar on 08/12/2010 07:02 AM

    You might try something like this:

    when HTTP_REQUEST {
    if { [HTTP::uri] eq "/sample" and !( [HTTP::header "True-Client-IP"] eq 1.1.1.1 } ) and !([TCP::client_port==80]) {
    reject } }

    Edit - just tested, client_port is the random source port for the user. Looks like "local_port" will do what I want!
  • How's this look?

    when HTTP_REQUEST {
    if {  [HTTP::uri] eq "/sample" and !( [HTTP::header "True-Client-IP"] eq 1.1.1.1 ) and ! ([TCP::local_port] eq 443 ) } {
    reject }
       }
    
    Edit - looks like this wouldn't work...user with that URI, 1.1.1.1 but port 80 wouldn't get rejected, gonna have to make it an if/else I think.

    How bout this:
    if { [HTTP::uri] eq "/sample" and !([[HTTP::header "True-Client-IP"] eq 1.1.1.1] and [[TCP::local_port] eq 443]) }
    
  • Sorry I meant to comment on this earlier Chris, I just didn't get a chance. If I were going to tackle this I would plan on future expansion and changes. That would be easy to do using datagroups I think. I know it is different in version 10.x, but in 9.4 I would create one datagroup called "valid_uri", put /sample in it and/or /sample/

    Then create another data group called "valid_addresses" that you can plug your 1.1.1.1 in to. Using the iRule below, it would check to see if the URI matches, if the address is coming from the valid address if the port is NOT 443, drop that request. Not real elegant looking, but it would definitely be able to be expanded in the future. You may have to check the iRule for bracket issues, I don't have a BIG-IP in front of me at the moment to test compile....

    
    when HTTP_REQUEST {
    set header_uri [string tolower [HTTP::uri]]
    if { ([matchclass $header_uri starts_with $::valid_uri]) && ([matchclass [IP::client_addr] equals $::valid_addresses]) && not ([matchclass [TCP::local_port] equals 443])} {
        discard
    }
    }