Table of Contents

F5 BIG-IP iRules Examples

If you want to check iRule, you shuoud restart the browser.



Basic Knowlege

URL

URL


HTTP_REQUEST

From http To https

when HTTP_REQUEST {
    if {[HTTP::uri] starts_with "/contatcts/"} { 
        HTTP::redirect "https://[HTTP::host][HTTP::uri]"
        return
    }
}


URL Rewrite in BIG-IP iRule

when HTTP_REQUEST {
    if { [HTTP::uri] starts_with "/abc/" } {
        HTTP::uri [string map {"/abc/" "/xyz/"} [HTTP::uri]]
    }
}


URL Top

when HTTP_REQUEST {
    if { [HTTP::uri] equals "/"} {
        HTTP::redirect "https://[HTTP::host]/en/"
        return
    }
}


Check active_members

when HTTP_REQUEST {
    if {([HTTP::uri] contains "server1")&&([active_members http_pool_server1]>0)} {
        pool http_pool_server1
        return
    }
    elseif {([HTTP::uri] contains "server2")&&([active_members http_pool_server2]>0)} {
        pool http_pool_server2
        return
    }
    else{
        pool Pools_Sorry
        return
    }
}


substitute

if { [HTTP::uri] starts_with "/uk" } {
    set uri [string map -nocase {"/uk" "/jp"} [HTTP::uri]]
    HTTP::redirect $uri
    return
}


log

Log File is /var/log/ltm.

when HTTP_REQUEST {
    set country [whereis [IP::client_addr] country]
    log local0. "Country is $country"
}

when HTTP_REQUEST {
   set LogString "Client [IP::client_addr]:[TCP::client_port] -> [HTTP::host][HTTP::uri]"
   log local0. "============================================="
   log local0. "$LogString (request)"
   foreach aHeader [HTTP::header names] {
      log local0. "$aHeader: [HTTP::header value $aHeader]"
   }
   log local0. "============================================="
}
when HTTP_RESPONSE {
   log local0. "============================================="
   log local0. "$LogString (response) - status: [HTTP::status]"
   foreach aHeader [HTTP::header names] {
      log local0. "$aHeader: [HTTP::header value $aHeader]"
   }
   log local0. "============================================="
}


Geolocation

when HTTP_REQUEST {
    set country "[whereis [IP::client_addr] country]"

    if { $country equals "US" } {
        HTTP::redirect "http://maintenance.example.com/"
        return
    }
}


WebSockets

BIG-IP from Ver11 can use websockets like https. so you don't need iRule.

when CLIENT_ACCEPTED {
    HTTP::enable
}
when HTTP_REQUEST {
    if { [matchclass [HTTP::uri] starts_with $::MyValidUris] } [
        #WebSockets
        use pool Pools_WEB_80
        HTTP::disable
    } else {
        #http
        HTTP::respond 404 content [subst $::block_page]
    }
}

when CLIENT_ACCEPTED {
    HTTP::enable
}
when HTTP_REQUEST { 
    if { ([HTTP::uri] starts_with "/the-websocket-uri") } {
        #WebSockets
        use pool Pools_WEB_80
        HTTP::disable
    } elseif { not ( [class match [HTTP::uri] starts_with UnrestrictedUris] ) } { 
        # Drop the request
        drop
    } 
}



when HTTP_REQUEST {
  if { [string tolower [HTTP::header Upgrade]] contains "websocket" }{
      HTTP::disable
}
}

SOL14814: The BIG-IP system may drop WebSocket traffic


For BIG-IP versions later than 11.4.0, you can use a single virtual server with an HTTP profile.
For BIG-IP versions earlier than 11.4.0, consider using a separate virtual server with the applicable profile for each protocol.

SOL14754 - BIG-IP support for the WebSocket protocol


Check Active Members

when HTTP_REQUEST {
    if { [active_members [LB::server pool]] == 0 } {
    HTTP::redirect "http://sorry.example.com/"
    }
}

when HTTP_REQUEST {
    if {[active_members Pools_tet]==0} {
    HTTP::redirect "http://maintenance.example.com/"
    }
}


persist cookie
use pool Pools_Test

pool Pool_1
persist cookie insert

pool Pool_1
persist cookie insert  lb 0




HTTP_RESPONSE

when HTTP_RESPONSE {
    set cookieName "mycountry"
    set country "[whereis [IP::client_addr] country]"

    HTTP::cookie insert name ${cookieName} value ${country} path "/"  domain  "example.com"
    HTTP::cookie  expires ${cookieName} 100
}

JSessionID Persistence with Universal Persistence

  1. Create iRule
  2. Create Persistence Profile with Universal. This Persistence Profile Use the iRules.

when HTTP_REQUEST {
    if { [HTTP::cookie exists "JSESSIONID"] } {
        persist uie [HTTP::cookie "JSESSIONID"]
    } 
    if { [HTTP::uri] starts_with "/test" } {
        use pool Pools_TEST
        return
    }
    else {
        set jsess [findstr [HTTP::uri] "JSESSIONID" 11 ";"]
        if { $jsess != "" } {
            persist uie $universal-profile-name
        }
    }
}
when HTTP_RESPONSE {
    if { [HTTP::cookie exists "JSESSIONID"] } {
        persist add uie [HTTP::cookie "JSESSIONID"]
    }
}




LB_FAILED

Check Active Members

This works fine and when all pool members are down or unavailable, requests are sent to the sorry page.

when HTTP_REQUEST {
   #abbr
   pool test-pool
   #abbr
}

when LB_FAILED { 
    HTTP::fallback "http://maintenance.example.com/"
    return
}

when HTTP_REQUEST {
   #abbr
       set test 1
       pool test-pool1
   } else {
       set test 2
       pool test-pool2
   }
   #abbr
}

when LB_FAILED { 
    switch $test {
        1 {
            HTTP::fallback "http://maintenance1.example.com/"
            return
        }
        2 {
            HTTP::fallback "http://maintenance2.example.com/"
            return
        }
    }

}