Jump to content

Listen Policy With Multiple CLIENT.SRC.IP To LDAP , All Others To RADIUS

Don Casey

Recommended Posts

Let me state right upfront I am a total newbie to Citrix and will probably impress you all with my depth of ignorance.


We need to configure our Citrix ADC to authenticate users either thru straight LDAP or MFA via RADIUS depending on Public IP address. There are (2) trusted public IPs that are the NAT addresses of our company's corporate offices. Most users connect to the Citrix Gateway from one of these two locations via Citrix Receiver and when doing so, will not require MFA. Some users will connect from home or various other locations via Citrix Receiver. Those IPs will not be known or may not be static.


We need the user not connecting from our corporate offices to authenticate thru a RADIUS server linked to our Watchguard AuthPoint Gateway. We have been able to configure and bind both LDAP and RADIUS authentication policies on the NetScaler virtual server, and we can get MFA working; however, we are unable to restrict MFA challenge to only users connecting from locations other than our "trusted" corporate offices. In other words, no MFA required if you are connecting from either corporate office.


In researching this issue, I was able to find article CTX211473 which explains how to create Listen Policies. It seems like this may be the solution, and Watchguard has recommended it as such. The documentation is helpful, but I am unclear on exactly how this approach will know when to process LDAP and when to process RADIUS if both authentication policies are bound and set as "primary".


Can someone shed some more light on this approach? Will it work with both Authentication Policies bound to the virtual server, or will I need an additional virtual server that processes all other IPs bound only to the RADIUS authentication Policy? The documentation seems to indicate both Authentication Policies can be bound to the same virtual server, but I'm not seeing how it knows when to use LDAP vs. RADIUS based on the IP address.


Again, I apologize if I am unable to clearly state my goal and challenge. Any insight would be greatly appreciated.

Link to comment
Share on other sites

If its one vserver doing LDAP for some IPS and LDAP/Radius for other source IPs, I'm not sure listen policies are needed.


You would build the <source ips> into the conditional flow for the LDAP only vs the LDAP/Radius requirement. Your authentication policies would have expressions based on source ips and not just a true expression.


Not a full mockup (sorry for only partial describing policies):

First factor (default vserver binding):

priority 100:  authe_pol_ldap_trustedoffices  "client.ip.src.in_subnet(<x.x.x.x/24>) || client.ip.src.in_subnet(<y.y.y.y/24>)" and appropriate action (no next-factor specified); policy goto: end; no next-factor binding.

priority 200:  authe_pol_allothers_2Aldap true  (or use negation of subnet clause above);  next factor: 2FA_radius


Next Factor (Policy Label):  2FA_radius

priority 100:  authe_pol_allothers_2Bradius true ....


Basically, if your trustedoffices/ldaponly policy is hit, it is the only policy required. Stops processing and no trigger to next factor for radius.

If not, then the 2Aldap flow is processed and it requires the next factor for radius is also processed.





Link to comment
Share on other sites

Thank you for the suggestion @Rhonda Rowland


If I understand you correctly, I would modify the existing LDAP Authentication Policy to reflect conditional branching to my RADIUS policy as opposed to the current value of ns_true? I'm a bit confused on how many Authentication Policies are actually used. One, two or three? Also, since LDAP only logons are always coming from one of two public IPs (NATed Branch Office locations), could I substitute "Client.IP.Src.EQ( || Client.IP.Src.EQ(" instead of the "in_subnet values?


Again thank you for your assistance and please forgive me if my questions sound ignorant.

Link to comment
Share on other sites

If you are using classic engine, your options are more limited.

If you are integrated with an authentication vserver using the advanced policy engine, then we can discuss nfactor requirements.

Are you going to be able to use advanced policies by integrating gateway with an authentication vserver or are you going to be on classic engine only? (if class, note, you are approaching a deprecation which means you will have to reconfigure when you do upgrade to 13.1 or later eventually.)


If you have to use the gateway (classic engine only), then listen policies and two separate vservers may be required. 

If you can use the gateway with authentication vserver (advanced engine), then nfactor policies become possible.  

This would likely be done with three policies one for ldap only and one requring ldap and then radius.


On the other question:

The IP-based OR clause would work instead of in_subnet could be used.  This again depends on whether we can use advanced vs. classic expressions.



Link to comment
Share on other sites

  • 6 months later...

hi, let me continue on this a bit older topic, i have faced some kind of issues combining 2 or more expressions with client.ip.src.in_subnet clause. im using advanced policy, AAA vserver, with nfactor for ldap internal subnets filtering and radius for the same with negotiation.  radius policy has priority over ldap filtering, it should false and go to next policy ldap with ldap nfactor login if coming from internal subnets. this is working only if i add 1 expression for subnet, if im using more subnets in policy expression with operator OR ( || ) it never works and routes internal users based on the radius policy to nfactor 2FA login page.

any hint how to set it up correctly?

example of policy:

add authentication Policy pol_TwoFactor -rule "CLIENT.IP.SRC.IN_SUBNET(xx.xx.xxx.xx/16).NOT || client.IP.SRC.IN_SUBNET(xx.xx.0.0/16).NOT || client.IP.SRC.IN_SUBNET(xx.xx.0.0/17).NOT" -action NO_AUTHN

add authentication Policy pol_SelectUserSourceIP -rule "client.IP.SRC.IN_SUBNET(xx.xx.xx.xx/16) || client.IP.SRC.IN_SUBNET(xx.xx.0.0/16) || client.IP.SRC.IN_SUBNET(xx.xx.0.0/17)" -action NO_AUTHN

binding to policy label both auth policies as:

bind authentication policylabel CheckUserIP_label -policyName pol_TwoFactor -priority 90 -gotoPriorityExpression NEXT -nextFactor RadiusAuth
bind authentication policylabel CheckUserIP_label -policyName pol_SelectUserSourceIP -priority 100 -gotoPriorityExpression NEXT -nextFactor DomainAuth

to summarize, current result is always routed to RadiusAuth if coming from internal subnet and using e.g. 3 IN_SUBNET clauses in policy. If only 1 expression/clause for IN_SUBNET is used, it works correctly and returns DomainAuth if coming from internal subnet.

Thanks for reading this.



Link to comment
Share on other sites

If I understand your issue, you want certain users to be TwoFactor and you want other users to not require a second authentication.

You want the Two Factor to apply to IPS not in the list of specified subnets.  You want domain only for the ones in the subnet only.

And your 2FA policy is failing with more than one clause. If I've interpreted what you are trying to do correctly, then the expression is based on the wrong boolean logic.  I'm only looking at the the logic and not the rest of nfactor.


Let's say you have 4 subnets: A, B, C, D

And Example 1: The IP address E is not in any of the subnets.


If you only do two-factor for IPs NOT in one of the identified Subnets, then you need an expression based on:

Not(A || B || C || D) 

which is equivalent to:

!A && !B && !C && !D


IF IP Address E is not in any of the subnets:  Then the expression  (!A && !B && !C && !D) is TRUE so  you will do the 2FA.

If IP Address F is in subnet A (Or any other):  The the expression (!A && !B && !C && !D) is FALSE, so the 2FA will not occur.


Translating the above clause to your subnet expression, there are several ways to write this, but your boolean operator was backwards above. You needed Ands and not Ors.:

Example 1a:

client.ip.src.in_subnet(x.x.x.x/16).NOT && client.ip.src.in_subnet(x.x.x.x/16).NOT  && client.ip.src.in_subnet(x.x.x.x/16).NOT

Example 1b:

!client.ip.src.in_subnet(x.x.x.x/16) && !client.ip.src.in_subnet(x.x.x.x/16)  && !client.ip.src.in_subnet(x.x.x.x/16)

Example 1c:

!(client.ip.src.in_subnet(x.x.x.x/16) || client.ip.src.in_subnet(x.x.x.x/16)  || client.ip.src.in_subnet(x.x.x.x/16))










Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
  • Create New...