Forum Discussion

Dan_Rogers_1933's avatar
Dan_Rogers_1933
Icon for Nimbostratus rankNimbostratus
Apr 04, 2011

Help with cross-vip persistence, one ssl vip and wildcard pool

I've been trying to get this iRule to work and have followed many other (much older examples) in this forum and some blog posts:

Basically, we have 4 VIP's:

1. Port 443 with ssl client profile (clear text from LTM to server)

2. Port 80

3. Port 1443

4. Port 8444

All pointing to the same pool, which is a wildcard pool

VIPs 1 and 2 map to 8443 in the iRule

What happens is when the client connects to 443, the session is created, but the next request to say port 8444 or 1443 go to a different node in the pool and a new persistence record is created for this new connection.

I've tried many different iterations and so far I can't crack it. I hope someone here can help


when CLIENT_ACCEPTED { 
set def_pool [LB::server pool]
set retries 0

 Calculate destination port based on destination port and IP address 
    switch [TCP::local_port] {
       80  { set port 8443 }
       443 { set port 8443 }
   default { set port [TCP::local_port] }
    }
 check for existing persistence record 
 if it exists, directly select node by address:port
set persist "[IP::client_addr] any virtual"
log local0. "\$persist = $persist"
set server [session lookup uie [list $persist]]
 
if {($server != "") && ($port != "")}{
log local0. "Found record [IP::client_addr]:[TCP::client_port] -> [IP::local_addr]:[TCP::local_port] -> $def_pool $server:$port"
pool $def_pool member $server:$port
node $server $port
}
} 
 when SERVER_CONNECTED { 
     Debug logging. Remove/comment out this event when done testing 
    log local0. "Connected [IP::client_addr]:[TCP::client_port] -> [IP::server_addr]:[TCP::server_port]" 
 }
when LB_SELECTED {
 add/refresh session table entry (5 min timeout)
if {$server >= "1"}{
log local0. "[IP::client_addr]:[TCP::client_port] -> [IP::local_addr]:[TCP::local_port] persistent to = $server"
} else {
set server [IP::client_addr]
set persist "[IP::client_addr] any virtual"
set server [session lookup uie [list $persist]]
if {$server != ""}{
session add uie [list $persist] $server 300
log local0. "Add Record uie $persist $server:any 300"
} else {
LB::reselect
log local0. "no server selected"
}
}
}
when LB_FAILED {
 set server [session lookup uie {[IP::client_addr] any virtual}]
 if connection fails, log & reselect a new server in same pool, up to the number of available servers
if { $retries < 1 } {
persist none
LB::mode rr
LB::detach
LB::reselect
incr retries
log local0. "Selected server $server:$port did not respond. Re-selecting node"
log local0. " -> [IP::client_addr]:[TCP::client_port] -> [IP::local_addr]:[TCP::local_port]"
}
}

3 Replies

  • Since you have one pool and multiple VIPs, I assume you are trying to persist on the server IP only.

     

    Why not just save the IP in the persistence table since you know everything else?

     

  • Grigory_Eremen1's avatar
    Grigory_Eremen1
    Historic F5 Account
    I guess you need to specify what is a goal of your iRule. It appears for me that you are trying ot implement source address affinity persistence across multiple virtual servers. If this is correct then why just you don't create custom persistence profile and enable match across services and across virtual servers then assign it all four your VS here.
  • Yes. You are correct the first goal is source address persistence and the other goal is to do port mapping for two ports and send traffic to a single node for all ports defined across the 4 VIPs. When I first dove into this everything I found said if you want to do port mapping and persistence across virtuals to a single node in a pool you have to use an irule (granted it was a very old post). I've since found a video post from Deb and Colin that described what seems to be a much simpler solution. Disable port translation for the virtuals that don't need port mapping, and add nodes to the pool with the translated port, then attach a custom persistence profile to match across virtuals. I've tried this before with a combination of an irule and the seperate persistence profile but that did not work. Once I watched the video (just found it about 40 mins ago) I learned something new and wonderful; you don't have to send traffic to the pool member on the port configured in the pool. If you disable port translation on the virtual, then the LTM will forward what ever port you requested down to the server even if it's not what you setup in the pool. I never realized it did that, I thought that check box was really only useful when you had wildcard pools.