Forum Discussion

st0n3_87491's avatar
st0n3_87491
Icon for Nimbostratus rankNimbostratus
Aug 13, 2009

Persistence based on IMAP-User

Hi there,

as topic say I would like to have a persistence to a node based on his IMAP-Userlogin.

I managed to find out this using a stream Profile and wrote this iRule so far:

  
 when CLIENT_ACCEPTED {  
 STREAM::expression @LOGIN\.*@  
 STREAM::enable   
 event STREAM_MATCHED enable  
 }  
 when STREAM_MATCHED {  
 set match [getfield [STREAM::match] " " 2]  
 set client "[IP::client_addr]:[TCP::client_port]"  
 set vip [IP::local_addr]:[TCP::local_port]  
 set node "[IP::server_addr]:[TCP::server_port]"  
 log local0.info "$match $client $vip $node"  
 STREAM::disable  
 }  
 

This iRule now just logs

  
 Jul 15 19:08:54 tmm tmm[1867]: Rule persistence_irule_user : nocppp XX.XX.XXX.XXX:XXXXX(CLIENT-IP: PORT) XXX.XXX.XXX.XXX:XXX(VIP-IP: PORT) XXX.XXX.XXX.XXX:XXXX(NODE-ID: PORT)  
 

As already mentioned in the next step I would like to have a persistance based on that LOGIN/Client-IP: PORT.

How can I manage this?

Next question is what happens to the persistent requests when the node goes down?

Maybe there are totally other solutions for that...because I have a performance issue on that solution, too.

Thanks in advance

Christian

14 Replies

  • hoolio's avatar
    hoolio
    Icon for Cirrostratus rankCirrostratus
    Sorry, I'm confusing myself and you... the rule as it is is adding a persistence record based on the LOGIN in the request payload. The latest update I added tries to look that persistence record up using the client IP address. That won't exist as it wasn't added with the client IP as the persistence key.

    Can you try this? I'd test it myself but I'm short on time at the moment.

    Aaron

     
     when CLIENT_ACCEPTED { 
      
         Time in seconds to maintain the persistence record in LTM's session table 
        set timeout 1800 
      
         Define STREAM expression and enable STREAM filter to check for the login 
        STREAM::expression {@LOGIN\.*@} 
        STREAM::enable 
     } 
     when STREAM_MATCHED { 
      
        log local0. "[IP::client_addr]:[TCP::client_port]: Matched: [STREAM::match]" 
      
         Save the matched value 
        set imap_login [getfield [STREAM::match] " " 2] 
      
         Check if $imap_login isn't empty 
        if { $imap_login != "" }{ 
      
            $imap_login isn't empty...so let's continue 
            log local0. "IMAP Login Information found...continuing" 
      
            The iRule parser doesn't allow the persist command in STREAM_MATCHED. 
            It works though, so hide the command from the parser 
           set persist_cmd "persist uie $imap_login $timeout" 
           log local0. "[IP::client_addr]:[TCP::client_port]: Parsed: $imap_login \$persist_cmd: $persist_cmd" 
      
           eval $persist_cmd 
           persist uie $imap_login 
      
           log local0. "[IP::client_addr]:[TCP::client_port]: Added persistence record for $imap_login on server [IP::server_addr]:[TCP::server_port]. Exiting event for this response." 
           event STREAM_MATCHED disable 
      
        } else { 
            $imap_login is empty...let's stop this here 
           log local0. "no IMAP Login Information found...aborting" 
        } 
     } 
     when LB_SELECTED { 
      
        log local0. "[IP::client_addr]:[TCP::client_port]: Selected server [LB::server]" 
     } 
     when SERVER_CONNECTED { 
      
        log local0. "[IP::client_addr]:[TCP::client_port]: Connected server [IP::server_addr]" 
     } 
     

  • I think IMAP client and server has to chat a little before client tell server the login name.

     

    using stream profile might be too late.

     

    I believe you may have to do something like this smtp irule example. (let LTM chat to IMAP client until it knows login name, then pick server and repeat same conversation)

     

     

    http://devcentral.f5.com/wiki/default.aspx/iRules/SMTPProxy.html

     

     

    sorry if I misunderstood any thing.

     

    Nat
  • hoolio's avatar
    hoolio
    Icon for Cirrostratus rankCirrostratus
    Hi Nat,

     

     

    That makes sense. It's a good suggestion. Unfortunately I don't have an IMAP server handy or the time to test this... and I imagine faking the IMAP server response from an iRule is going to be fairly technical for someone new to iRules.

     

     

    I can try testing this sometime, but I don't see it happening in the next week or two.

     

     

    Aaron
  • you may try this...

    this irule uses a lot of shortcut. it assumes that client just makes tcp connection and send capability command. For simplicity, the capability command is tripped off and is not forwarded to server.

        
     when CLIENT_ACCEPTED {  
         TCP::respond "* BIG-IMAP ready\r\n"  
         set state "capability"  
          assume client will send capability as next command  
         TCP::collect  
     }  
     when CLIENT_DATA {  
         switch $state {   
             "capability" {  
                 TCP::respond "* CAPABILITY IMAP4 IMAP4rev1 IDLE LITERAL+ LOGIN-REFERRALS MAILBOX-REFERRALS NAMESPACE AUTH=NTLM\r\na0000 OK CAPABILITY completed.\r\n"  
                 set state "login"  
                  assume client will send login as next command  
                 TCP::payload replace 0 [TCP::payload length] ""  
                 TCP::collect  
             }  
             "login" {  
                  find username and make load balancing decision here 
                 log local0.alert "[TCP::payload]" 
                 TCP::release  
             }  
         }  
     } 
     

    you may have to change capability message (the specific line below) to match your server. Dont forget to put \r\n (or CRLF) as necessary.

    TCP::respond "* CAPABILITY .... "

    Nat