Forum Discussion
Gary_105208
Nimbostratus
Mar 20, 2009How to Generate Visitor ID/UUID
We're trying to drop a unique visitor cookie that we control the persistence (i.e. 6 months age). I don't see anything in the iRule reference that close to helping.
Any recommendation on how to generate an unique identifier, or ideally UUID?
I see some UUID TCL libraries at http://tcllib.cvs.sourceforge.net/viewvc/tcllib/tcllib/modules/uuid/uuid.tcl?revision=1.9&view=markup but I don't believe these can be loaded into the F5?
Once I have that I can handle all the cookies, etc. I just need a unique id generator.
Thanks, Gary
12 Replies
- The_Bhattman
Nimbostratus
You could incorpate something like the following into your irule
set unique [md5 [IP::client_addr]]
HTTP::cookie insert name "UUID" value $::unique
Then you could base your persistance off of what is in the cookie or you can insert into the HTTP headers.
Hope this helps
CB - Gary_105208
Nimbostratus
Unfortunately, with super proxies and corporate proxies the client IP wouldn't be enough as MD5 isn't collision resistant. But, I'll have to think a bit about how collision non-resistant MD5 is.. It might be good enough. - Gary_105208
Nimbostratus
[EDIT: double post] - Gary_105208
Nimbostratus
Anybody know what the cookie that the BigIP drops is exactly?
i.e. BIGip=3859747244.16671.0000
Is it pretty unique, and is it accessible within an irule? I was thinking it must be as my assumption is it's used for the persistence table. - Gary_105208
Nimbostratus
If not, my thought was to do something similar to what tcllib uuid is doing:
Append the following together:
clock seconds Timestamp
clock clicks system incrementing counter
pid additional entropy
server_addr get some spatial uniqueness
client_addr add some more spatial uniqueness
Then md5 this all, and convert the result to a UUID format. - hoolio
Cirrostratus
The BIG-IP persistence cookie is an encoded (not encrypted) form of the pool member IP and port. The cookie name by default is BIGipServer. The encoding is described in SOL6917 (Click here). This codeshare example (Click here) shows how to decode it in an iRule.
Are you trying to generate a unique ID for handling sessions or for persistence? If the former, I could see why you'd want to prevent collisions. If the latter, I'm not so clear. Can you explain why you would need a globally unique token for persistence? Why couldn't you just the default cookie insert persistence with a expiration time set according to your requirements? I don't understand why the persistence cookie would need to be globally unique if you're just trying to give the client a token with which you get them back to the same pool member.
Aaron - Gary_105208
Nimbostratus
Thanks, on the BigIP cookie. I was hoping it might be a unique id, bt alas not.
What we're doing is creating a unique visitor ID across all our clusters that is used in our applications. We have several clusters and no common, unique id that can be shared to correlate across products. To solve it in the applications can be error prone from a development perspective, and we want to drop a unique visitor cookie at the load balancer. Most of the products go through the load balancer, so it's a good place to do it.
Right now I'm moving forward with implementing portions of the tcllib UUID to get as unique as I can identifier. My main concern now is performance and load on the LB. - Gary_105208
Nimbostratus
I ended up doing the following below... I'm not Tcl master, and some of the binary scan/format was simply copied from the tcllib.
My only thought is, does md5 use the rand function, and does the rand function use clock. If so, then either clock or rand are redundant and probably not increasing entropy.when RULE_INIT { set ::cn "lbId" set ::ce 15552000 } when HTTP_REQUEST { if { not ([HTTP::uri] starts_with "/static" or [HTTP::uri] starts_with "/assets") } { if { not [HTTP::cookie exists $::cookieName] } { append s [clock seconds] [IP::local_addr] [IP::client_addr] [expr { int(100000000 * rand()) }] [clock clicks] set s [md5 $s] binary scan $s c* s lset s 8 [expr {([lindex $s 8] & 0x7F) | 0x40}] lset s 6 [expr {([lindex $s 6] & 0x0F) | 0x40}] set s [binary format c* $s] binary scan $s H* s append u [substr $s 0 8] "-" [substr $s 8 4] "-" [substr $s 12 4] "-" [substr $s 16 4] "-" [substr $s 20 12] unset s HTTP::cookie insert name $::cn value $u } else { set u [HTTP::cookie value $::cn] } set h [HTTP::host] } } when HTTP_RESPONSE { if { not ($u eq "") } { set h [findstr [getfield $h : 1 ] ".eharmony."] if { $h eq "" } { HTTP::cookie insert name $::cn value $u path "/" } else { HTTP::cookie insert name $::cn value $u path "/" domain $h } unset h unset u HTTP::cookie expires $::cn $::ce } } - Patrick_Chang_7Historic F5 AccountMD5 is a deterministic algorithm and does not use rand.
Rand does not use clock. It only uses its seed (which most people set with clock).
As for performance, it turns out that
HTTP::cookie and TCL math are your most expensive operations. - hoolio
Cirrostratus
Here's one method we tried:
How random is rand()?
http://devcentral.f5.com/Default.aspx?tabid=53&forumid=5&tpage=1&view=topic&postid=813535
Aaron
Recent Discussions
Related Content
DevCentral Quicklinks
* 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
Discover DevCentral Connects
