Forum Discussion

keith_varga_107's avatar
keith_varga_107
Icon for Nimbostratus rankNimbostratus
Jun 07, 2012

irule for http vs https requests

DevCentral Team,

 

 

Here is our current irule:

 

 

when HTTP_REQUEST {

 

HTTP::header insert "X_CLIENT_IP" [IP::client_addr]

 

HTTP::header insert "X-Forwarded-For" [IP::client_addr]

 

if { [string tolower [HTTP::uri]] contains "/pmcserver/checkforwork" } {

 

pool pm2_qa_web

 

return

 

} elseif { [string tolower [HTTP::uri]] contains "pmcserver" } {

 

pool pm2_qa_pmcserver

 

return

 

} elseif { [string tolower [HTTP::uri]] starts_with "/partner" } {

 

pool pm2_qa_soap

 

return

 

} else {

 

pool pm2_qa_web

 

return

 

}

 

}

 

 

 

the developers were asking for the following additional requirements:

 

 

1. Reject http://www.ourProduct.com:80/api/*. Returns HTTP status 403?

 

2. Route https://www.ourProduct.com:443/api/* to a pool for serverA using port 80.

 

 

The intention of the rules is to ensure that nothing going to /api is ever sent via HTTP, we want everything via HTTPS. Ideally the client can't open a connection, but they are not sure that is possible.

 

 

 

We have two F5 virtual servers, one for http and one for https. Since the irule is set a the virtual server level i could not find a way to do this without two separate irules. For example, using two irules (one for each VS) is what i came up with just below. However, was wondering if there was a more elegant way to perhaps combine these into one rule.

 

 

thanks much,

 

Keith Varga

 

 

 

 

Proposed http F5 virtual server irule:

 

 

when HTTP_REQUEST {

 

HTTP::header insert "X_CLIENT_IP" [IP::client_addr]

 

HTTP::header insert "X-Forwarded-For" [IP::client_addr]

 

if { [string tolower [HTTP::uri]] contains "/pmcserver/checkforwork" } {

 

pool pm2_qa_web

 

return

 

} elseif { [string tolower [HTTP::uri]] contains "pmcserver" } {

 

pool pm2_qa_pmcserver

 

return

 

} elseif { [string tolower [HTTP::uri]] starts_with "/partner" } {

 

pool pm2_qa_soap

 

return

 

} elseif { [string tolower [HTTP::uri]] starts_with "/api" } {

 

reject

 

HTTP::respond 403 content "api requires https"

 

} else {

 

pool pm2_qa_web

 

return

 

}

 

}

 

 

 

 

Proposed https F5 virtual server irule:

 

 

when HTTP_REQUEST {

 

HTTP::header insert "X_CLIENT_IP" [IP::client_addr]

 

HTTP::header insert "X-Forwarded-For" [IP::client_addr]

 

if { [string tolower [HTTP::uri]] contains "/pmcserver/checkforwork" } {

 

pool pm2_qa_web

 

return

 

} elseif { [string tolower [HTTP::uri]] contains "pmcserver" } {

 

pool pm2_qa_pmcserver

 

return

 

} elseif { [string tolower [HTTP::uri]] starts_with "/partner" } {

 

pool pm2_qa_soap

 

return

 

} elseif { [string tolower [HTTP::uri]] starts_with "/api" } {

 

pool pm2_qa_api

 

return

 

} else {

 

pool pm2_qa_web

 

return

 

}

 

}

4 Replies

  • Hi Keith,

    Did you have a question about the iRule you posted?

    You could modify it to use a switch statement to avoid running string tolower on the URI multiple times:

    when HTTP_REQUEST {
    HTTP::header insert "X_CLIENT_IP" [IP::client_addr]
    HTTP::header insert "X-Forwarded-For" [IP::client_addr]
    switch -glob [string tolower [HTTP::uri]] {
    "*/pmcserver/checkforwork*" {
    pool pm2_qa_web
    }
    "*pmcserver*" {
    pool pm2_qa_pmcserver
    }
    "/partner*" { 
    pool pm2_qa_soap 
    }
    default {
    pool pm2_qa_web 
    }
    }
    }
    

    Aaron
  • thanks for that suggestion Aaron. DevCentral crashed yesterday when i was trying to submit my case, and so it was missing the question. I updated the question/case above with my actual question.

     

     

    thanks again,

     

    Keith Varga
  • I'd use separate iRules for the two virtual servers and change both to a switch as in the example above. You could use one combined iRule and check [TCP::local_port] to see if it is being executed on port 80 or port 443, but I think it's cleaner to use two separate rules.

     

     

    Aaron