Forum Discussion
How best to accomplish HTTP redirection for specific URLs?
I am trying to create a site where some URLs are not redirected to HTTPS but all other URLs do get redirected. I do not know what is the best method to accomplish this. I want the ability to easily add URLs that should not be redirected. Should I be using iRule for this? Or is an html rewrite profile better?
For example... http://www.drspanky.com/slowcomputer/is/slow/index.html --> not redirected http://www.drspanky.com/notso/fastcomputer/is/notfast.html ---> not redirected http://www.drspanky.com/slownotebook/is/slow/nossl/index.html --> not redirected http://www.drspanky.com/slow12345/nossl/is/slow/myhome.svc --> not redirected All other requests to www.drspanky.com are redirected to https.
I am fairly new with working on the F5 Big IP LTM appliances. I have been able to create simple LTM policies for http and https web sites. For most all of the https sites I have, I am simply using the F5 ceritified iRule to redirect all http requests to https.
I have a series of sites that have a number of URLs that cannot be redirected. I am porting this site from a Cisco ACE 4710 appliance where I have http url class-maps defined for the URLs not to be redirected.
I am using the latest and greatest tmos release on new hardware. thnx in advance for any suggestions. I want to learn so pointing me in the right direction would be very much appreciated.
- Kevin_StewartEmployee
I'd go with the data group method. It's by far the easiest to manage and requires no subsequent changes to the iRule. Example.
Data group - string-based (ex. my_uri_dg)
"/uri1" "/uri2" "/uri3" "/uri4"
iRule:
when HTTP_REQUEST { if { not ( [class match [string tolower [HTTP::uri]] starts_with my_uri_dg] ) } { HTTP::redirect "https://[HTTP::host][HTTP::uri]" } }
So as long as the requested URI pattern (starts_with) is in the data group, the request will pass through. Otherwise, for everything else, it gets redirected. It doesn't appear that the host name changes, so you shouldn't have to evaluate that. Also note that we're just looking for data the group key, so the corresponding values can be empty.
- nitass_89166Noctilucent
Can you use regex in these data groups? I will want to match a common 3 digit string in each URI but the digits will change over time. Also I would want to ignore case on these URIs.
what about this?
e.g.
root@(ve11a)(cfg-sync Changes Pending)(Active)(/Common)(tmos) list ltm virtual bar ltm virtual bar { destination 172.28.20.111:80 ip-protocol tcp mask 255.255.255.255 pool foo profiles { http { } tcp { } } rules { myrule } source 0.0.0.0/0 source-address-translation { type automap } vs-index 23 } root@(ve11a)(cfg-sync Changes Pending)(Active)(/Common)(tmos) list ltm rule myrule ltm rule myrule { when HTTP_REQUEST { set path [string tolower [HTTP::path]] switch -glob $path { "/slowcomputer/is/slow/index.html" - "/notso/fastcomputer/is/notfast.html" - "slownotebook/is/slow/nossl/index.html" - "/slow[0-9][0-9][0-9][0-9][0-9]/nossl/is/slow/myhome.svc" { do nothing } default { HTTP::redirect "https://[HTTP::host][HTTP::uri]" } } } } [root@ve11a:Active:Changes Pending] config curl -I http://172.28.20.111/slowcomputer/is/slow/index.html HTTP/1.1 404 Not Found Date: Sun, 25 Aug 2013 01:28:50 GMT Server: Apache/2.2.3 (CentOS) Content-Type: text/html; charset=iso-8859-1 [root@ve11a:Active:Changes Pending] config curl -I http://172.28.20.111/SLOW54321/nossl/is/slow/myhome.svc HTTP/1.1 404 Not Found Date: Sun, 25 Aug 2013 01:31:45 GMT Server: Apache/2.2.3 (CentOS) Content-Type: text/html; charset=iso-8859-1 [root@ve11a:Active:Changes Pending] config curl -I http://172.28.20.111/somethingelse HTTP/1.0 302 Found Location: https://172.28.20.111/somethingelse Server: BigIP Connection: Keep-Alive Content-Length: 0
- Tony_Kitzky_936NimbostratusAhh... I think I followed what you did. Thnx. I can use this as a sample to learn from. I like the method of using a data group for the individual URIs. I need to dig into iRule fundamentals, I guess.
- nitass_89166Noctilucenti understand we cannot use regex in data group. so, we may separate those data (from data group) and check it using command such as switch glob, string match, scan, etc.
- nitassEmployee
Can you use regex in these data groups? I will want to match a common 3 digit string in each URI but the digits will change over time. Also I would want to ignore case on these URIs.
what about this?
e.g.
root@(ve11a)(cfg-sync Changes Pending)(Active)(/Common)(tmos) list ltm virtual bar ltm virtual bar { destination 172.28.20.111:80 ip-protocol tcp mask 255.255.255.255 pool foo profiles { http { } tcp { } } rules { myrule } source 0.0.0.0/0 source-address-translation { type automap } vs-index 23 } root@(ve11a)(cfg-sync Changes Pending)(Active)(/Common)(tmos) list ltm rule myrule ltm rule myrule { when HTTP_REQUEST { set path [string tolower [HTTP::path]] switch -glob $path { "/slowcomputer/is/slow/index.html" - "/notso/fastcomputer/is/notfast.html" - "slownotebook/is/slow/nossl/index.html" - "/slow[0-9][0-9][0-9][0-9][0-9]/nossl/is/slow/myhome.svc" { do nothing } default { HTTP::redirect "https://[HTTP::host][HTTP::uri]" } } } } [root@ve11a:Active:Changes Pending] config curl -I http://172.28.20.111/slowcomputer/is/slow/index.html HTTP/1.1 404 Not Found Date: Sun, 25 Aug 2013 01:28:50 GMT Server: Apache/2.2.3 (CentOS) Content-Type: text/html; charset=iso-8859-1 [root@ve11a:Active:Changes Pending] config curl -I http://172.28.20.111/SLOW54321/nossl/is/slow/myhome.svc HTTP/1.1 404 Not Found Date: Sun, 25 Aug 2013 01:31:45 GMT Server: Apache/2.2.3 (CentOS) Content-Type: text/html; charset=iso-8859-1 [root@ve11a:Active:Changes Pending] config curl -I http://172.28.20.111/somethingelse HTTP/1.0 302 Found Location: https://172.28.20.111/somethingelse Server: BigIP Connection: Keep-Alive Content-Length: 0
- Tony_Kitzky_936NimbostratusAhh... I think I followed what you did. Thnx. I can use this as a sample to learn from. I like the method of using a data group for the individual URIs. I need to dig into iRule fundamentals, I guess.
- nitassEmployeei understand we cannot use regex in data group. so, we may separate those data (from data group) and check it using command such as switch glob, string match, scan, etc.
- Kevin_StewartEmployee
Okay, this is a little hacky, but there is technically a way to achieve "regex-like" behavior with data groups. I'll start with the data group.
/slow1234/nossl/is/ /fast1234/nossl/is/ ...
The digits in the URI aren't important and I'm purposely limiting the URIs to three-levels deep, but yours should be limited to the lowest common denominator for your matched URIs. Now the iRule:
when HTTP_REQUEST { limit the request URI to three levels Example: /slow1234/nossl/is/slow/ becomes /slow1234/nossl/is/ set uri [string range [HTTP::uri] 0 [string first "/" [HTTP::uri] [expr [string first "/" [HTTP::uri] [expr [string first "/" [HTTP::uri] 1] +1]]+1]]] Turn the URI into a glob pattern based on numeric values Example: /slow1234/nossl/is/slow becomes /slow*/nossl/is/slow regsub -all -nocase {\d+} $uri "*" globuri append globuri "*" Search for the glob pattern in the data group if { not ( [lindex [class get -nocase glob_datagrouop $globuri] 1] eq "" ) } { log local0. "no match" perform redirects } }
The idea here is that I'm using the [class get ] command with a glob pattern - not truly a regex itself, but the regsub command above makes sure that only digits are affected. So to illustrate what's happening:
-
The URI is first truncated to three levels. That'll make more sense in a moment.
-
The regsub command replaces any instance of a sequential digits in the URI with a glob "*" character, and then an additional "*" is appended to the end.
-
This pattern is fed into the [class get ] command, which produces a list. If the pattern matches a single data group entry, then it's flagged as a match. Otherwise all or multiple records are returned and it's not a match. Of course you want to make sure that your URI patterns cannot produce multiple results in the search.
The reason for limiting the data group URI is that you can't really do a "starts_with" expression like you can with other class commands. So, for example, if the data group URI was something like "/slow1234/nossl/is/" and the request URI was "/slow3454/nossl/is/slow/test/foo/bar", the glob pattern would become "/slow*/nossl/is/slow/test/foo/bar" - and this wouldn't match the data group.
-
Recent Discussions
Related Content
* 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