Forum Discussion

cory_seaborn_17's avatar
cory_seaborn_17
Icon for Nimbostratus rankNimbostratus
May 07, 2015

Cookie persistence via iRule

I've read a few articles about accomplishing this but nothing that has really suited my needs so far.

At a high level, we have a 'shared' vserver that we use for multiple services. We load balance to the appropriate pools using an iRule based on URIs. We’d like to explore the possibility of creating a new iRule that will match on a specific URI (for now - eventually we'll want to class match to a datagroup) and implement cookie persistence if it matches. Otherwise, just continue to process the other iRules in the stack.

I'd like something similar to the following. This doesn't work with cookie persistence but DOES work with source address:

when HTTP_REQUEST {
    if { ([HTTP::path] contains "/xyz/") } { persist cookie }
}

We get the following error message when applying the iRule to the vserver:

01070372:3: Persistence mode (Cookie) called out in rule (/Common/test_cookie_persistence) requires a corresponding persistence profile for virtual server (/Common/pool_name).

However, a similar iRule using source address persistence doesn't require an persistence profile on the virtual server:

when HTTP_REQUEST {
    if { ([HTTP::path] contains "/xyz/") } { persist source_addr }
}

Can anybody shed some light on why this is? Or point me in the right direction of an example of a working cookie persistence iRule that doesn't require the need for the persistence profile to be applied? The whole point of the iRule would be to avoid the persistence profile which would then apply to all services using this vserver, so applying one in this case kind of defeats the purpose.

13 Replies

  • I think without a persistance profile, you will need to provide more information (cookie name, expiry time, etc) on the persist command.

     

    Check out the examples on this page: Persist

     

  • Hm, I tried adding in some of the optional parameters (anything beyond 'persist cookie') as mentioned on that page, but still have the same issue.

    Note: Items marked with  are meant to be replaced with a value. Arguments bracketed by [ ] are used to note they are optional. They should not be confused with Tcl command evaluation.
    
    persist simple [] []       
    persist source_addr [] []       
    persist sticky [] []       
    persist dest_addr [] []       
    persist ssl []       
    persist msrdp []
    persist cookie [insert [] [] |
                    rewrite [] [] |
                    passive [] |
                    hash  [ { []} []] ]
    persist uie  []       
    persist hash  []
    persist carp 
    persist none
    
       = The timeout in seconds.
    

    So using this still throws the same error:

    when HTTP_REQUEST {
            if { ([HTTP::path] contains "/xyz/") } { persist cookie insert BIGIP 0 }
        }
    
  • sfuerst_116779's avatar
    sfuerst_116779
    Historic F5 Account

    The persistence profile contains information about the persistence cookie. i.e. is it type Insert/Rewrite/Hash. Does it have a user-defined name? Is it encrypted? When does it expire?

     

    The iRule command tells the BigIP to use cookie persistence... but it needs this extra information to actually do that. (You can pass some of these things via the persist iRule command, but not all.)

     

  • Thanks for the info, sfuerst.

     

    Just noticed that same article says 'Note: The following persistence methods require a corresponding persistence profile be added to the virtual server: ssl, msrdp, cookie.' Sounds like there's no way around this then?

     

    • sfuerst_116779's avatar
      sfuerst_116779
      Historic F5 Account
      Yes, you'll need a cookie persistence profile in order to use cookie persistence. Note that you can manually apply more than one persist profile to a virtual. (The gui doesn't let you do this, but it is useful when selecting between types of persistence via an iRule.)
  • Thanks for again for the help so far.

    I think I was overcomplicating this by assuming a default cookie persistence profile would take precedence over desired persistence behavior set in an iRule (specifically that the default persistence profile would be applied before parsing through the iRules). Looks like that was incorrect, but please correct me if I'm wrong.

    Using a configuration similar to what's below seems to work. With this, a cookie will only be set if you're hitting a URI of either /xyz/ or /abc/. Anything else won't use persistence (note the fallback persistence profile for source_addr shouldn't be required on the vserver).

    Keep in mind this is config from a device on 11.4.1.

    ltm data-group internal /Common/cookie_uris_datagroup {
        records {
            /xyz/ { }
            /abc/ { }
        }
        type string
    }
    
    ltm rule /Common/set_cookie_persistence {
        when HTTP_REQUEST {
        if { [ class match [HTTP::uri] contains cookie_uris_datagroup ] }
            { persist cookie }
        else
            { persist none }
    }
    
    ltm virtual /Common/my_server {
        destination /Common/192.168.1.100:80
        fallback-persistence /Common/source_addr
        ip-protocol tcp
        mask 255.255.255.255
        persist {
            /Common/cookie {
                default yes
            }
        }
        profiles {
            /Common/http { }
            /Common/tcp { }
        }
        rules {
            /Common/set_cookie_persistence
        }
        source 0.0.0.0/0
        source-address-translation {
            type automap
        }
        translate-address enabled
        translate-port enabled
    }
    
  • this is what i understand Steven meant.

     configuration
    
    [root@ve11c:Active:In Sync] config  tmsh list ltm virtual bar
    ltm virtual bar {
        destination 172.28.24.10:80
        ip-protocol tcp
        mask 255.255.255.255
        persist {
            cookie {
                default no
            }
            source_addr {
                default yes
            }
        }
        pool foo
        profiles {
            http { }
            tcp { }
        }
        rules {
            qux
        }
        source 0.0.0.0/0
        source-address-translation {
            type automap
        }
        vs-index 13
    }
    [root@ve11c:Active:In Sync] config  tmsh list ltm rule qux
    ltm rule qux {
        when HTTP_REQUEST {
      if { [HTTP::uri] starts_with "/test/" } {
        persist cookie
      } else {
         Use source address persistence by default
      }
    }
    }
    
     source address persistence
    
    [root@ve11c:Active:In Sync] config  date; tmsh delete ltm persistence persist-records
    Sat May 16 16:30:22 SGT 2015
    
    [root@ve11c:Active:In Sync] config  date; curl -I http://172.28.24.10/
    Sat May 16 16:30:25 SGT 2015
    HTTP/1.1 200 OK
    Date: Sat, 16 May 2015 08:11:08 GMT
    Server: Apache/2.2.3 (CentOS)
    Last-Modified: Sun, 09 Feb 2014 08:39:51 GMT
    ETag: "41879c-59-2a9c23c0"
    Accept-Ranges: bytes
    Content-Length: 89
    Content-Type: text/html; charset=UTF-8
    
    [root@ve11c:Active:In Sync] config  date; tmsh show ltm persistence persist-records all-properties
    Sat May 16 16:30:29 SGT 2015
    Sys::Persistent Connections
    source-address - 172.28.24.10:80 - 200.200.200.101:80
    -----------------------------------------------------
      TMM           0
      Mode          source-address
      Value         172.28.24.13
      Age (sec.)    5
      Virtual Name  /Common/bar
      Virtual Addr  172.28.24.10:80
      Node Addr     200.200.200.101:80
      Pool Name     /Common/foo
      Client Addr   172.28.24.13
      Owner entry
    
    Total records returned: 1
    
     cookie persistence
    
    [root@ve11c:Active:In Sync] config  date; tmsh delete ltm persistence persist-records
    Sat May 16 16:30:46 SGT 2015
    
    [root@ve11c:Active:In Sync] config  date; curl -I http://172.28.24.10/test/
    Sat May 16 16:30:52 SGT 2015
    HTTP/1.1 200 OK
    Date: Sat, 16 May 2015 08:13:30 GMT
    Server: Apache/2.2.3 (CentOS)
    Last-Modified: Mon, 17 Jun 2013 18:14:47 GMT
    ETag: "420027-4b-925773c0"
    Accept-Ranges: bytes
    Content-Length: 75
    Content-Type: text/html; charset=UTF-8
    Set-Cookie: BIGipServerfoo=1875429576.20480.0000; path=/
    
    [root@ve11c:Active:In Sync] config  date; tmsh show ltm persistence persist-records all-properties
    Sat May 16 16:30:55 SGT 2015
    Sys::Persistent Connections
    Total records returned: 0
    
  • I am very new to this but this looks like something that might help me if anyone could assist in clarifying what I would need to do...

     

    I have an exchange server on our LTM running 11.5.3 and it has source address persistence working great for all users with the exception of a GOOD Mobile Messaging server that apparently the vendor says only works properly using cookie persistence.

     

    I don't want to break Exchange by changing the persistence profile for all users but was wondering if there was a way to look at the source IP of the GOOD (GMM) server and change it to a cookie persistence profile instead. Is this along the same lines as the irule in this thread?

     

    Does this mean I could assign both persistence profiles to the exchange VS and make source address persistence the default but use an irule to associate the GMM IP to a cookie persistence profile instead?

     

    Any help is appreciated!

     

    • OTS02's avatar
      OTS02
      Icon for Cirrus rankCirrus
      Hi Mike P. I pulled this out of a rule I am using for mobile app VS: when HTTP_REQUEST { set seshuntoken [HTTP::cookie value "SESSION_TOKEN"] if { [IP::addr [IP::client_addr] equals 10.xxx.xxx.xxx/255.255.255.255] } { if { [HTTP::cookie exists "SESSION_TOKEN"] } { if { $seshuntoken != "" } { persist uie [HTTP::cookie "SESSION_TOKEN"] } } } }
    • OTS02's avatar
      OTS02
      Icon for Cirrus rankCirrus
      Of course, you need to know the name of the cookie that the GOOD server is using. our cookie name happens to be "SESSION_TOKEN".
    • OTS02's avatar
      OTS02
      Icon for Cirrus rankCirrus
      Thinking about it, you probably don't even need to discriminate according to IP address, as the other clients probably will not have that cookie name.