cancel
Showing results for 
Search instead for 
Did you mean: 

IRule to select IRule doesn't work even if the condition triggers

sam_kal
Altostratus
Altostratus

Problem Statement:

Trying to create a I-Rule to forward traffic to a pool "pool-troubleshooting" in case a header is passed in a request, the "if" condition triggers as the logs are part of the loop but still the traffic goes to the default pool at Virtual server.

BIG-IP 14.1.2

 

IRule:

 

when HTTP_REQUEST {

 if { [HTTP::header exists testing] } {

      pool pool-troubleshooting

           foreach aHeader [HTTP::header names] {

               log local0. "Redirecting to troubleshooting pool HTTP REQUEST HEADER $aHeader: [HTTP::header value $aHeader]"

               }

       }

}

 

 

Logs:

 

 Rule troubleshooting-pool <HTTP_REQUEST>: Redirecting to troubleshooting pool HTTP REQUEST HEADER Host: example.com

 Rule troubleshooting-pool <HTTP_REQUEST>: Redirecting to troubleshooting pool HTTP REQUEST HEADER User-Agent: curl/7.68.0

 Rule troubleshooting-pool <HTTP_REQUEST>: Redirecting to troubleshooting pool HTTP REQUEST HEADER Accept: */*

 Rule troubleshooting-pool <HTTP_REQUEST>: Redirecting to troubleshooting pool HTTP REQUEST HEADER testing: True

 Rule troubleshooting-pool <HTTP_REQUEST>: Redirecting to troubleshooting pool HTTP REQUEST HEADER TLS-Version: TLSv1.2

 Rule troubleshooting-pool <HTTP_REQUEST>: Redirecting to troubleshooting pool HTTP REQUEST HEADER TLS-Cipher: EXXXXX

 

Any help in troubleshooting will be appreciated. 🙂

 

1 ACCEPTED SOLUTION

To know what pool was selected, maybe you have lot of pool selection logic or possibly the default may have been selected too, to know what's happening in HTTP_REQUEST, use this,

 

when HTTP_REQUEST { if { [HTTP::header exists testing] } { log local0. "Pre Pool selected is [findstr [LB::server pool] "" 8 ]" pool pool-troubleshooting foreach aHeader [HTTP::header names] { log local0. "Post Pool selected is [findstr [LB::server pool] "" 8 ]" log local0. "Redirecting to troubleshooting pool HTTP REQUEST HEADER $aHeader: [HTTP::header value $aHeader]" } } }

 

So if you see your intended pool not selected, you can do this,

when LB_SELECTED { if { [LB::server pool] == "/Common/DEFAULT-POOLNAME-443" && [active_members pool-troubleshooting] > 0 } { pool pool-troubleshooting LB::reselect } }

 

 

View solution in original post

5 REPLIES 5

Heino
Cirrus
Cirrus

There's the classic with checking the spelling of the pool, and if it is the right server in the pool. Checking if there's a preceeding or proceeding irule that "overwrites" your new settings.

 

That aside. I see no actual issue with your irule. Suggestions

  1. Try selecting the specific pool member: pool named_pool member named_member port even if there's only one server
  2. Use the node command: node x.x.x.x 80 (or whatever port)
  3. Try reselecting the pool in a later event.
when HTTP_REQUEST { set vtrouble False   if { [HTTP::header exists testing] } { set vtrouble True foreach aHeader [HTTP::header names] { log local0. "Redirecting to troubleshooting pool HTTP REQUEST HEADER $aHeader: [HTTP::header value $aHeader]" } } }   when LB_SELECTED { if { $vtrouble == True} { LB::reselect pool pool-troubleshooting } }

 

I'm pretty sure there's a different reselect command, but I can't recall it.

 

I mostly give above suggestions as I've run into a similar situation before, where changing the expression from pool to node solved the issue. No clue why. I had 30 other rules where I used the same pool command with a different pool.

 

Thanks for responding to the question and I got hint from your answer to check the proceeding and preceding rules. I assumed that moving rules up and down change their precedence but realized later that it was priority which basically defines that.

Tried first two options that didn't helped and then assigned a high priority to the condition/irule and it worked.

Thank you again.

To know what pool was selected, maybe you have lot of pool selection logic or possibly the default may have been selected too, to know what's happening in HTTP_REQUEST, use this,

 

when HTTP_REQUEST { if { [HTTP::header exists testing] } { log local0. "Pre Pool selected is [findstr [LB::server pool] "" 8 ]" pool pool-troubleshooting foreach aHeader [HTTP::header names] { log local0. "Post Pool selected is [findstr [LB::server pool] "" 8 ]" log local0. "Redirecting to troubleshooting pool HTTP REQUEST HEADER $aHeader: [HTTP::header value $aHeader]" } } }

 

So if you see your intended pool not selected, you can do this,

when LB_SELECTED { if { [LB::server pool] == "/Common/DEFAULT-POOLNAME-443" && [active_members pool-troubleshooting] > 0 } { pool pool-troubleshooting LB::reselect } }

 

 

Hei @jaikumar_f5​ 

As I mentioned in other reply I used the priority at the moment before actually checking your response. But I find your response to be the best and helpful for troubleshooting any such scenario. Thanks for the help.

I'm selecting this as the best response but would like to check with you, if setting the priority is a bad idea in this case?

Setting the priority is not a bad idea. ​It's always the design & requirements that define whether that app requires multiple irules & priorities in it.

There are environments where multiple irules would be used for different purpose. Some irules would be specific to security related & some would be related to app flow based.

Most times, security rules must be honoured than letting the traffic to flow through. So some orgs use the default irule order or some use the priority concept.

Lower priority events will be 1st executed then the higher priority events triggers. Though the lower events ​logic may be selected when processed, if there's an event with higher priority, it will be processed too & would override the manipulation. The default priority is 500.