Priority of policies in Citrix ADC / NetScaler Content Switching in combination with Load Balancing

P

In Theory, it’s easy: Load Balancing is stronger than Content Switching. I tested with 13.0 82.42 on a Citrix ADC VPX. With some surprise to me: There had been differences between the features tested. I tested with Responder Policies, Citrix ADC Bot Protection, and Citrix Web Application Firewall.


The setup

I used a content switching vServer (192.168.229.200) and a non-addressable load-balancing vServer. The load-balancing vServer had been bound to the Citrix ADC/NetScaler content-switching vServer using a content-switching policy (so it had not been the default vServer). I bound the test services (red, blue and green), provided by Wonderkitchen (a great Citrix ADC / NetScaler test environment)

add lb vserver lb_vs_test HTTP
add cs vserver cs_vs_test HTTP 192.168.229.200 80
add cs action cs_act_test -targetLBVserver lb_vs_test
add cs policy cs_pol_test -rule true -action cs_act_test
bind cs vserver cs_vs_test -policyName cs_pol_test -priority 100


 

Citrix ADC / NetScaler Responder Policies

Responder policies

I created two responder policies: One for the load-balancing vServer, one for the content-switching vServer. I bound either the built-in bypass (NOOP) or the built-in drop (DROP) action. To make things transparent, I also bound logging actions. During my tests, I exchanged NOOP and DROP (I didn’t use drop, as DROP is too slow for tests like that).

add audit messageaction log_cs WARNING "\"LB-Policy hit\""
add responder policy res_pol_lb HTTP.REQ.IS_VALID RESET -logAction log_lb

add audit messageaction log_cs WARNING "\"CS-Policy hit\""
add responder policy res_pol_cs HTTP.REQ.IS_VALID NOOP -logAction log_cs

Probably you wonder, why I’m using this stupid expression HTTP.REQ.IS_VALID instead of true? A friend had been afraid, “true” behaves differently from Citrix ADC / NetScaler policy expressions.

I bound all policies with a priority of 96, if not stated differently.

Maybe you think, it’s impossible to bind a responder policy with a terminating action with GOTOPRIORITY=NEXT? You’re right. But you may bind it with an action of NOOP and change the action after binding. That’s the trick I’ve used here. It may not make sense in real life, but helped me understanding, what’s going on.

Results

# Action CS Goto CS Action LB Goto LB Policy hit Result
1 RESET END RESET END CS Req. dropped
2 RESET END RESET NEXT LB, CS Req. dropped
3 NOOP END RESET END LB Req. dropped
4 NOOP END RESET NEXT LB, CS
Req. not dropped
5 RESET END NOOP END LB
Req. not dropped
6 RESET END NOOP NEXT LB, CS Req. dropped

So the result is no surprise to me. I assumed, load-balancing takes precedence over content-switching. So load-balancing policies should always overwrite content switching policies if both of them apply. That’s absolutely true. It works like expected, even though a RESET in combination with a GOTO NEXT is not officially supported by Citrix. In case 4, we don’t drop, as the load-balancing policy does not mandate to drop and has a goto END. In 5 we don’t drop, even though, load-balancing mandated dropping, as content-switching overwrites load-balancing. That’s not true for 6, so we drop.


 

Citrix ADC Bot Management

Bot policies

The setup is rather similar to the setup I used with Responder. Bot-Policies, of course, are a bit more complex. I just used blacklists.
add bot profile bot_prof_blokIP -blackList ON
add bot profile bot_prof_empty
bind bot profile bot_prof_blokIP -blackList -type IPv4 -value 192.168.229.1 -action LOG RESET -enabled ON -logMessage "\"IP blocked\""
bind bot profile bot_prof_blokIP -logExpression -name log_bot_prof_blokIP -expression "\"Profil bot_prof_blokIP \"" -enabled ON
bind bot profile bot_prof_empty -logExpression -name log_bot_prof_leer -expression "\"Profil: bot_prof_leer\"" -enabled ON

add bot policy bot_pol_lb -rule "HTTP.REQ.HOSTNAME.EQ(\"192.168.229.200\")" -profileName bot_prof_blokIP -logAction log_lb
add bot policy bot_pol_cs -rule "HTTP.REQ.HOSTNAME.EQ(\"192.168.229.200\")" -profileName bot_prof_empty -comment "\"BOT Contentswitching\"" -logAction "BOT Contentswitching"

Results

# action CS goto cs action lb goto lb policy hit result
1 bot_prof_blokIP END bot_prof_blokIP END LB Req. dropped
2 bot_prof_blokIP END bot_prof_blokIP NEXT LB, CS Req. dropped
3 bot_prof_empty END bot_prof_blokIP END LB Req. dropped
4 bot_prof_empty END bot_prof_blokIP NEXT LB, CS
Req. not dropped
5 bot_prof_blokIP END bot_prof_empty END LB
Req. not dropped
6 bot_prof_blokIP END bot_prof_empty NEXT LB, CS Req. dropped

Here, behavior is exactly the same as with Responders: It works like expected. In case 4, we don’t drop, as the load-balancing policy does not mandate to drop and has a goto END. In 5 we don’t drop, even though, load-balancing mandated dropping, as content-switching overwrites load-balancing. That’s not true for 6, so we drop.


 

Citrix ADC Web Application Firewall (WAF)

WAF Policies

Again, the setup is rather similar to the setup I used with Responder. I used the built-in WAF actions APPFW_DROP and APPFW_BYPASS.

add appfw policy appfw_pol_lb "HTTP.REQ.HOSTNAME.EQ(\"192.168.229.200\")" APPFW_DROP -logAction log_lb
add appfw policy appfw_pol_cs "HTTP.REQ.HOSTNAME.EQ(\"192.168.229.200\")" APPFW_DROP -logAction log_lb

bind cs vserver cs_vs_test -policyName appfw_pol_cs -priority 100
bind cs vserver lb_vs_test -policyName appfw_pol_lb -priority 100

Results

# action CS goto cs action lb goto lb policy hit result
1 APPFW_DROP END APPFW_DROP END LB Req. dropped
2 APPFW_DROP END APPFW_DROP NEXT CS Req. dropped
3 APPFW_BYPASS END APPFW_DROP END LB Req. dropped
4 APPFW_BYPASS END APPFW_DROP NEXT CS
Req. not dropped
5 APPFW_DROP END APPFW_BYPASS END LB
Req. not dropped
6 APPFW_DROP END APPFW_BYPASS NEXT CS Req. dropped

Again, the results are exactly the same as with Responders: It works like expected. In case 4, we don’t drop, as the load-balancing policy does not mandate to drop and has a goto END. In 5 we don’t drop, even though, load-balancing mandated dropping, as content-switching overwrites load-balancing. That’s not true for 6, so we drop.

Why don’t we see the load-balancer being hit with 2, 4, and 6? I have no idea. But it scares me a little bit!


About the author

Johannes Norz

Johannes Norz is a Citrix Certified Citrix Technology Advocate (CTA), Citrix Certified Instructor (CCI) and Citrix Certified Expert on Application Delivery and Security (CCE-AppDS).

He frequently works for Citrix international Consulting Services and several education centres all around the globe.

Johannes lives in Austria. He had been borne in Innsbruck, a small city (150.000 inhabitants) in the middle of the most beautiful Austrian mountains (https://www.youtube.com/watch?v=UvdF145Lf2I)

Add comment

By Johannes Norz

Recent Posts

Recent Comments