Forum Discussion

lchln_304378's avatar
lchln_304378
Icon for Nimbostratus rankNimbostratus
Dec 29, 2016

Translate mod_rewrite to iRules

Hi guys,

Trying to migrate mod_rewrite rules to F5 iRules and am not having much success. The current setup uses a regex to get the subdomain from a HTTP_HOST and then rewrites the URL, appending the subdomain to the URI. The regex is used as we serve multiple clients and use sub-domains to distinguish them.

eg.

abc.domain.com rewrites to domain.com/abc

mod_rewrite rules here:

  RewriteCond %{HTTP_HOST} ^([^.]+)\.abc\.domain\.com$ [NC]
  RewriteCond %{REQUEST_URI} !pages/ [NC]    
  RewriteCond %{REQUEST_URI} !test_pages/ [NC]
  RewriteCond %{REQUEST_URI} !testpages/ [NC]
  RewriteRule ^(.*)$ https://abc.domain.com/test//%1/%{REQUEST_URI} [P,L]

I've written up the below and have tried to implement but with little success:

when HTTP_REQUEST {
    if {[string tolower [HTTP::host]] matches_regex {^([^.]+)\.abc\.domain\.com$}} then
    {
        HTTP::redirect "https://abc.domain.com/test//%1/%[HTTP::host]"
        }
    }

Any advice? Am I misusing HTTP::host and should I instead be using HTTP:uri? I was messing around with using a string map but I don't have enough knowledge to make it work:

when HTTP_REQUEST {
  set subdomain [string map {".abc.domain.com" "" "abc.domain.com" ""} [string tolower [HTTP::host]]]
  if { $subdomain ne "" } {
HTTP::redirect "https://abc.domain.com/test//%1/$subdomain"
  }
}

Thanks in advance for any advice.

  • JG's avatar
    JG
    Icon for Cumulonimbus rankCumulonimbus

    How about the following:

    when HTTP_REQUEST {
        if { [string tolower [HTTP::host]] ends_with ".abc.domain.com" } {
            switch -glob [string tolower [HTTP::uri]] {
                "*pages/*"      -
                "*test_pages/*" -
                "*testpages/*"  -
                default {
                            HTTP::redirect "https://abc.domain.com/test/[HTTP::host]/[HTTP::uri]"
                }
            }
        }
    }   
    

    However, the Apache mod_rewrite rule does not do a redirect.

  • JG's avatar
    JG
    Icon for Cumulonimbus rankCumulonimbus

    You need to enable SSL bridging on you virtual server, and then try this:

    when HTTP_REQUEST {
        if { [string tolower [HTTP::host]] ends_with ".abc.domain.com" } {
            switch -glob [string tolower [HTTP::uri]] {
                "*lib/*"  {
                              HTTP::redirect "http://my-error-page-server/"
                }
                "*static_pages/*" {
                              HTTP::redirect "http://my-error-page-server/"
                }
                "*assets/*"  {
                              HTTP::redirect "http://my-error-page-server/"
                }
                default {
                            HTTP::header replace Host "abc.domain.com"
                            HTTP::uri /test/[HTTP::host]/[HTTP::uri]
                            node 1.2.3.4  IP addr of backend server.
            }
        }
    }
    
  • JG's avatar
    JG
    Icon for Cumulonimbus rankCumulonimbus

    Then you need to enable SSL bridging, and apply this example irule:

    when HTTP_REQUEST {
        if { [string tolower [HTTP::host]] equals "abc.domain.com" } { 
            HTTP::header replace Host [string range [HTTP::host] 4 end]
            HTTP::uri "/[string range [HTTP::host] 0 3]"
        }
    }
    

    Of course you will need to modify the irule to suit your real situation.

    [Edited the irule]

  • JG's avatar
    JG
    Icon for Cumulonimbus rankCumulonimbus
    when HTTP_REQUEST {
        HTTP::header replace Host "[getfield [HTTP::host] '.' 2].[getfield [HTTP::host] '.' 3]"
        HTTP::uri "/[getfield [HTTP::host] '.' 1]"
    }
    
  • JG's avatar
    JG
    Icon for Cumulonimbus rankCumulonimbus
    when HTTP_REQUEST {
        if { [string tolower [HTTP::host]] ends_with ".domain.com" } {
            switch -glob [string tolower [HTTP::uri]] {
                "/lib/*"  {
                              HTTP::redirect "http://my-error-page-server/"
                }
                "/static_pages/*" {
                              HTTP::redirect "http://my-error-page-server/"
                }
                "/assets/*"  {
                              HTTP::redirect "http://my-error-page-server/"
                }
                default {
                            HTTP::header replace Host "[getfield [HTTP::host] '.' 2].[getfield [HTTP::host] '.' 3]"
                            HTTP::uri "/[getfield [HTTP::host] '.' 1]"
                            node 1.2.3.4  Your backend server.
                }
            }
        }
    }
    

    If this does not work, please forget the irule for a moment and write down a full description of you requirement, for we seem to be trying to hit a moving target.