Forum Discussion
Jamey_Price_105
Nimbostratus
Oct 21, 2006Setting the Pool in STREAM_MATCHED
We're setting up a pool of load-balanced Lotus Notes boxes to provide webmail. One of the machines (currently, anyways) has a redirector set up so once you've logged in, if the machine you logged into isn't your mailserver it'll do a javascript-based redirect to send you to the right machine. It'd be nice if it did a 302 instead since that'd be MUCH easier to catch, but instead I just set up a stream profile and watch for the name of any of the machines it could redirect you to and replace them with the hostname on the Big-IP I'm proxying everything through. However, once I do that I need to ensure that all your future requests go through the mailserver it tried to redirect you to.
According to what I'm logging, this is working fine. According to what I'm actually seeing in the pool network statistics, and the fact that it can't find the mailfile, it isn't working.
when STREAM_MATCHED {
This is the mailserver you're being redirected to, its hostname specifically. Fix this to use string tolower later.
set mailserver [STREAM::match]
This name::lookup doesn't actually work, dunno why.
set serverip [NAME::lookup $mailserver]
set currpool [LB::server pool]
set currpoolmember [LB::server]
The Wiki says that pool commands MUST be in an if/else structure, so here's one.
if { $mailserver ends_with "jwt.com" } {
log "Mailserver matched jwt.com, setting pool to $mailserver instead of $currpool"
I set up pools with the names of each of the mailservers.
pool "$mailserver"
} else {
This shouldn't actually ever trigger, and doesn't seem to.
log "Mailserver didn't match jwt.com, setting pool to $currpool instead of $mailserver"
pool "$currpool"
}
}
Can someone perchance tell me what I'm missing/doing wrong that's preventing me from actually getting further requests from this client to go to the correct pool?
Much obliged,
Fish
11 Replies
- Deb_Allen_18Historic F5 AccountHi Fish -
Check this post for some confg steps necessary for getting name resolution within iRules working:
http://devcentral.f5.com/Default.aspx?tabid=28&view=topic&forumid=5&postid=1332 (Click here)
If you're still having trouble, post back with details on how you have configured the stream profile to watch for "the name of any of the machines".
(I don't believe there is a requirement that the pool be conditionally selected, although it more often than not is. I edited the wiki entry for pool (Click here) to remove that assertion and to add some more useful details about conditional pool selection. Further updates by those in the know would be much appreciated...)
HTH
/deb - Jamey_Price_105
Nimbostratus
I've worked around the inability to look things up in DNS, and am stuck now with an iRule in which, no matter what pool command I issue, nothing seems to happen.
Here's my rule where I set up my stream expression to look for any of the (currently two) possible mailservers the HTML could attempt to redirect me to and replace them with the name behind which I'm reverse-proxying webmail. This works fine, since I'm ending up on the correct URL. I'm just not ending up on the correct internal server.
when HTTP_RESPONSE {
if {[HTTP::cookie exists "LtpaToken"]}{
set cookie_value [HTTP::cookie "LtpaToken"]
HTTP::cookie remove "LtpaToken"
HTTP::cookie insert name "LtpaToken" value "$cookie_value" path "/" domain "teamdetroit.com"
STREAM::expression "@MAILvmw.jwt.com@webmail.teamdetroit.com@@HUBvmw.jwt.com@webmail.teamdetroit.com@"
log "Cookie path is [HTTP::cookie path "LtpaToken"] and domain is [HTTP::cookie domain "LtpaToken"]"
}
}
This is the current incarnation of my pool-related iRule. You'll note that the first thing I tried doing is totally short-circuiting anything and just manually sending the request to the pool I know during this test it should go to. Yeah, that doesn't work.
when STREAM_MATCHED {
pool MAILvmw.jwt.com member 10.8.128.3 80
set mailserver [STREAM::match]
set serverip [NAME::lookup $mailserver]
set currpool [LB::server pool]
set currpoolmember [LB::server]
set serverresp [NAME::response $mailserver]
log "Stream matched $mailserver, $serverip"
if { $mailserver ends_with "jwt.com" } {
log "Setting pool to $mailserver instead of $currpool"
pool $mailserver
} else {
log "Mailserver didn't match jwt.com, setting pool to $currpool instead of $mailserver"
pool $currpool
}
}
I've tried making multiple requests and watching the pool statistics for each of the three pools: The default pool, the pool it should send the request to, and the pool it shouldn't (but could if the mail admins were to do something silly, so I watch it anyways). The only pool where the statistics ever change is the default pool.
So, what do you think? Am I running into a bug for which I should call support, or am I doing something wrong?
Thanks,
Fish - William_Benett1
Nimbostratus
You have the exact same problem that I do. I posted something last week about wanting to LB based on a DNS response. The problem appears that you can only designate a pool in one of these three events: CLIENT_DATA, CLIENT_ACCEPTED, and HTTP_REQUEST.
Given that it would be extremely powerful to allow pool selection based on some DNS criteria, I can only assume that there is a technical limitation that is preventing the iRule processor from doing this. If the F5 people chose to limit this functionality, well, then that's just silly.
The solution that i'm going to try next is writing my own round robin load balancer(s). It seems that I can use the 'node' command to send the connection to a server. I'm not sure how this will really work out, though. - bl0ndie_127134Historic F5 AccountI wonder if you are making things harder that it should be. Sounds like you already have the stream filter configured to map the internal uri (mail server addresses) to the VIP.
If you enable cookie persistence, BigIP will do the heavy lifting of ensuring that the clients are directed to the node it connected to originally (nodes with the notes login). If cookie persistence does not work for some reason, you can always hand roll the persistence entries you self (as a bonus you could delete the persist entry when the user logsoff). There should be plenty of examples to show you how to do this. - Jamey_Price_105
Nimbostratus
Well nuts! I never noticed that stream_matched wasn't an valid event to issue a pool command in - largely because normally when you try to do something in an invalid event, you get errors in the log and your connection is reset, and here it just fails silently. Okay, I'm going to have to get creative and see what I can do here. If I come up with a solution, I'll post it here. Won't help with anyone who's doing things based on DNS, since I'm ignoring it at this point.
Fish - Jamey_Price_105
Nimbostratus
Bl0ndie, it's not a matter of cookies really, it's a matter of the internal server issuing a redirect, but instead of doing it server-side with a 301 or 302 that I can catch and handle it's doing it in javascript, which I have to replace in the page response with the host behind which I'm reverse-proxying and then subsequently manage to send the request to the proper internal server, which will at the very least be a different pool member than the initial server, or (and this seems simpler to me) a totally separate pool.
The easiest way for me to do this would be to be able to issue pool commands in the stream_matched event, where I have the data I need, but that just isn't an option. It'd be a GREAT idea for an enhancement, though - load balancing based on page content. S'very sexy.
Fish - William_Benett1
Nimbostratus
Fish, you might want to check your /var/log/ltm logfile for messages. I just figured out how to select a pool in the NAME_RESOLVED event. If you're getting an error "Address in use" in relation to that iRule try using LB::detach before you assign a pool.
I'm going to reply to my thread with a working iRule. - Deb_Allen_18Historic F5 AccountIt's worth noting that the list of valid events listed in the wiki for the pool command (or any other command, for that matter) is not necessarily exhaustive, only represents some events that have been positively identified as valid for the command in question.
I have added a number of events in which the pool command is also known to work. Please feel free to update any of the wiki pages as new information comes to light.
/deb - Simon_83666
Nimbostratus
Fish, did you get this resolved at the end ? I have exactly the same issue where I need to capture and translate the internal mail server names to one external address for the client and also making sure that the HTTP request from the client for directed to the right and same mail server every time... - Jamey_Price_105
Nimbostratus
Posted By sh710 on 08/12/2007 5:03 PM
Fish, did you get this resolved at the end ? I have exactly the same issue where I need to capture and translate the internal mail server names to one external address for the client and also making sure that the HTTP request from the client for directed to the right and same mail server every time...
Funny you should mention that. Not only did I manage to work around the problem, I won first place in last year's "iRule. Do you?" contest for it, customer category. http://devcentral.f5.com/Default.aspx?tabid=107
If you go to http://devcentral.f5.com/Default.aspx?tabid=108 which is linked from the previous page, you can see the iRule I submitted. In practice, it's actually a few different iRules that I put together into one for the contest, and I cleaned it up and threw a whackload of comments in to make it more understandable, but it's all there. I don't think it's changed much, if at all, since then either.
There is a small issue, though, that may or may not bite you with how I did it: If the cookie that holds the mailserver gets lost, and you're forced by the server to reauthenticate, on our systems it doesn't send you back through the redirector page where I grab the mailserver, so you can end up on the wrong server. That's not much of a problem here, because our users tend not to leave webmail open that long, but it's something to be aware of. If that's a problem, you could try sticking the info you need to keep in a global variable instead of cookie.
If there's anything I can clarify for you or any questions I can answer, just let me know.
Fish
Help guide the future of your DevCentral Community!
What tools do you use to collaborate? (1min - anonymous)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