19-Jul-2022 17:48
Dears,
unfortunately I did not find a fitting post to my problem:
We have two or more servers they creating a JSESSIONID where the id of the server is added on the end like so:
7B0DE3926CF23C27DFF9C80BE604B009.serverID0
5C38A6262816E6E3A6BBB0B3ABB42D3A.serverID1
(we are using the -DjvmRoute=... on the tomcat)
Is it possible, that every JSESSIONID with the ending serverID0 is always routing to server 0 and serverID1 to server 1?
The rootcause is, that if the routing switches for a user, they logged in 3 days before, they has to loggin again, although there is a valid security context on tomcat available on the "right" server...
19-Jul-2022 19:46 - edited 19-Jul-2022 19:46
# first create 3 pool,name is pool_node0, pool_node1, pool_default
# pool_node0 member 10.1.1.10:80 monitor tcp
# pool_node1 member 20.1.1.20:80 monitor tcp
# pool_default member 10.1.1.10:80 20.1.1.20:80 monitor tcp
iRuels code:
when RULE_INIT {
array set static::pool_array {
0 pool_node0
1 pool_node1
}
}
when HTTP_REQUEST {
if { [HTTP::cookie exists "JSESSIONID"] } {
set node_x [findstr [HTTP::cookie "JSESSIONID"] "serverID" 8 1]
log local0. "node_x is $node_x"
if { [active_members [lindex [array get static::pool_array $node_x] 1]] == 0 } {
pool pool_default
} else {
pool [lindex [array get static::pool_array $node_x] 1]
}
} else {
pool pool_default
}
}
19-Jul-2022 22:00
PLAN B:
Firstly, create 2 pool:
pool_web member is 10.10.10.1:80 10.10.10.2:80
pool_default is standby(its member is 20.20.20.1:80 20.20.20.2:80) when pool_web all members is down
Dynamically add elements to the array according to pool member select
# create pool_web member is 10.10.10.1:80 10.10.10.2:80
# create pool_default is standby(its member is 20.20.20.1:80 20.20.20.2:80) when pool_web all members is down
when RULE_INIT priority 500 {
array set static::pool_array {}
}
when HTTP_RESPONSE priority 500 {
set node_ip [IP::server_addr]
set node_port [TCP::server_port]
log local0. "node_ip is $node_ip, port is $node_port"
if { [HTTP::cookie exists "JSESSIONID"] } {
# serverID0,serverID1
set node_x [findstr [HTTP::cookie "JSESSIONID"] "serverID" 8 1]
log local0. "node_x is $node_x"
# dynamic add element in array ,key is ID, value is pool member
set static::pool_array($node_x) "$node_ip:$node_port"
log local0. "response event pool array is [array get static::pool_array]"
}
}
when HTTP_REQUEST priority 500 {
if { [HTTP::cookie exists "JSESSIONID"] } {
set server_x [findstr [HTTP::cookie "JSESSIONID"] "serverID" 8 1]
log local0. "server_x is $server_x"
if { [active_members pool_web] == 0 } {
log local0. "exists cookie, select slave pool pool_default"
pool pool_default
} else {
# 0 10.10.10.1:80
# 1 10.10.10.2:80
if { [array get static::pool_array $server_x] != "" } {
set mem_ip [getfield [lindex [array get static::pool_array $server_x] 1] ":" 1]
set mem_port [getfield [lindex [array get static::pool_array $server_x] 1] ":" 2]
if { [LB::status pool pool_web member $mem_ip $mem_port] eq "up" } {
pool pool_web member $mem_ip $mem_port
} else {
pool pool_web
}
} else {
reject
log local0. "client send fake invalid cookie JSESSIONID!"
}
}
} else {
if { [active_members pool_web] == 0 } {
pool pool_default
log local0. "no cookie, select slave pool pool_default"
} else {
pool pool_web
}
}
log local0. "request event pool array is [array get static::pool_array]"
}
19-Jul-2022 23:09
plan C:
Creating the universal persistence profile
To create a universal persistence profile and reference the persistence iRule you created in the previous procedure, perform the following procedure:
iRules code:
when HTTP_RESPONSE priority 500 {
if { [HTTP::cookie exists "JSESSIONID"] } {
# serverID0,serverID1, length is 9
set node_x [findstr [HTTP::cookie "JSESSIONID"] "serverID" 0 9]
log local0. "node_x is $node_x"
# persist add uie, key is serverIDX, timeout is 1800s
persist add uie $node_x 1800
}
}
when HTTP_REQUEST priority 500 {
if { [HTTP::cookie exists "JSESSIONID"] } {
set server_x [findstr [HTTP::cookie "JSESSIONID"] "serverID" 0 9]
set value [persist lookup uie $server_x]
if { $value != "" } {
persist uie $server_x
}
}
}
20-Jul-2022 00:10
I wrote this one a while ago (there is room for improvement with the array access):
when RULE_INIT {
array set static::srvid_node {
node1 172.29.32.160
node2 172.29.32.161
node3 172.29.32.162
node4 172.29.32.163
}
set static::debug_map_srvid 1
}
when HTTP_REQUEST {
set original_request "[IP::client_addr]:[HTTP::method]:[HTTP::uri]:HTTP/[HTTP::version]"
if {([HTTP::cookie exists JSESSIONID])} {
set session_id [HTTP::cookie value JSESSIONID]
set node_id [getfield ${session_id} . 2]
set node_ip [getfield [array get static::srvid_node ${node_id}] " " 2]
if {(${node_ip} ne "")} {
if {(${static::debug_map_srvid} > 0)} { log local0. "info: valid header-cookie JSESSIONID found (${session_id}) in request (${original_request}); mapping to ${node_ip}" }
} else {
log local0. "error: broken header-cookie JSESSIONID found (${session_id}) in request (${original_request}); balancing to default pool ([LB::server pool])"
pool [LB::server pool]
return
}
} elseif {([findstr [HTTP::path] JSESSIONID 11] ne "")} {
set session_id [findstr [HTTP::path] JSESSIONID 11]
set node_id [getfield ${session_id} . 2]
set node_ip [getfield [array get static::srvid_node ${node_id}] " " 2]
if {(${node_ip} ne "") and (${static::debug_map_srvid} > 0)} {
log local0. "info: valid url-cookie JSESSIONID found (${session_id}) in request (${original_request}); mapping to ${node_ip}"
} else {
log local0. "error: broken url-cookie JSESSIONID found (${session_id}) in request (${original_request}); balancing to default pool ([LB::server pool])"
pool [LB::server pool]
return
}
} else {
if {(${static::debug_map_srvid} > 0)} { log local0. "info: no addressed node found in request (${original_request}); balancing to default pool ([LB::server pool])" }
pool [LB::server pool]
return
}
if {([LB::status pool [LB::server pool] member ${node_ip} 80] equals "down")} {
log local0. "warning: addressed node (${node_ip}) in request (${original_request}) is unavailable; sending 503"
HTTP::respond 503 noserver Server "test service" Connection Close Date "[clock format [clock seconds] -format {%a, %b %d %Y %H:%M:%S %Z} -gmt 1]"
return
} else {
pool [LB::server pool] member ${node_ip}:80
return
}
}
when HTTP_RESPONSE {
if {([HTTP::cookie exists JSESSIONID]) and ($static::debug_map_srvid > 0) and ([info exists original_request])} {
log local0. "info: response cookie JSESSIONID ([HTTP::cookie value JSESSIONID]) found in response for request (${original_request})"
}
}
when LB_FAILED {
# Ausloesung des Events bei Nichtverfuegbarkeit innerhalb Monitoring Timeout
if {${static::debug_map_srvid} > 0} {
log local0. "error: selected server not available (${node_ip}:80) for request (${original_request}); sending 503"
}
HTTP::respond 503 noserver Server "test service" Connection Close Date "[clock format [clock seconds] -format {%a, %b %d %Y %H:%M:%S %Z} -gmt 1]"
return
}