Jump to content
Welcome to our new Citrix community!

Restrict access to desktops to specific Active Directory group

Matthew Weiner

Recommended Posts

I'm kind of beating my head against the wall trying to figure this one out.  I have members of an Active Directory group that I'd like to restrict access to only applications via the NetScaler, not a full desktop.  I tried using the AAA group extraction and a session policy to point to a different store thinking that may work, but it didn't.  I'm trying to avoid using SmartAccess as the documentation is so scattershot and contradictory I figure I'd probably break what I have working now (a very simple config of if a member of a given AD group - get access to resources).


The documentation made it look like I could point it to a different store by binding a session policy to an AAA group (the group extraction from AD works, I verified that in the CLI) but it gives me the same store I have configured by default in the gateway virtual server


So what I want to do is the following:

From inside my organization, allow access to all items (I use an IP based authentication policy for this)

From outside my organization allow access to only a certain delivery group with the items required.  The problem is that if I add them to my "default" AD group for remote access they will be able to see the applications and desktops.  I want to be able to add them to another group that restricts them down to not be able to see all the delivery groups and only the one they need.


Any assistance would be much appreciated.

Edited by mlweiner
Link to comment
Share on other sites

As you mentioned, SmartAccess is one way to do it. Another way is to configure BrokerAccessPolicy through Powershell on your Citrix Delivery Controller. See https://developer-docs.citrix.com/projects/delivery-controller-sdk/en/latest/Broker/Set-BrokerAccessPolicyRule/.


Basically, whenever you create a Delivery Group there will be 2 BrokerAccessPolicy rules attached to it by default, one for internal access (directly through Storefront) and one for external access (through Netscaler). On your Delivery Group 'A' which contains Apps and Desktops that you don't want to show to external users, you can configure the external BrokerAccessPolicy tied to this DeliveryGroup with the parameter 'ExcludedUsers' and specify the 'another group' (that you refer to above) to prevent those users from seeing any Apps or Desktops from that DeliveryGroup when they logon through Netscaler.


You then create a new Delivery Group 'B' which is specifically meant to only contain those Apps and Desktops that you want your external users to see, and you can do this by specifying the 'IncludedUsers' parameter on the external BrokerAccessPolicy (for this Delivery Group) and specify the 'another group' you referred to.


Benefit of above is that all the config is done on the delivery controller, while SmartAccess is a bit messy and relies on policy names on Netscaler matching the specified name on Delivery Controller etcetera. 


Link to comment
Share on other sites

Unfortunately that won't work many of these users use Chromebooks and have to go through the Netscaler while on-premise due to client limitations so I have to figure out how to allow the users to access the desktop through the Netscaler while in the internal network, but filter their access outside.  At this point I'm thinking SmartAccess is the only way to do it.


I have the Active Directory group extraction and AAA group part working, I can see a test user on the group via the CLI.  I've also got the bare bones of SmartAccess working - the policies that are showing up are visible in Director.  Right now they have no outside access but access to all allowed resources internally by an IP allow policy rule.  I've looked at the SmartAccess filters in Director for an IP range allowed user and see no matching policy (other policies are there) for the authentication.


So I'm guessing I'll have to do two things to get this to work - one is to figure out how to get a SmartAccess policy visible for the IP range Netscaler allow so I can ensure they can see their desktop from inside the organization.  The second would be a policy that would identify the users in this AD group to allow them in but restrict visibility of the desktop and just allow the application delivery group they require.

Link to comment
Share on other sites

SmartAccess rules are properties of the Delivery Group (or the published App itself). It's the easiest way to configure resources that are allowed internally (without gateway) and not allowed externally (with Gateway).  Unless I'm missing a nuance of your requirement that would change why this condition isn't quite what you want.  


If only some users need to be affected by this, you might need to consider publishing the separate resources for GroupA with smartAccess conditions and separate resources for GroupB without smart access.  But unless I'm missing a requirement, I don't think that's a problem.


Once SmartAccess is ocnfiugred in the resource properties, you need to also enable the TRustXMLRequests setting the XD/CVAD site properties (via powershell).  And configure a CALLBACK address in your storefront's gateway integration settings.  For the basic on network/off network requirement, you don't even need to pass gateway policy results to the CVAD environment, just the gateway/non-gateway smart access setting (basically, you do not need to also identify the gateway vpn vserver or session policy name).


If I'm missing part of your requirements, please clarify and we can adjust.  But basic with gateway vs internal can be done without EPA scans and works regardless of device type.


More complicated scenarios may need additional policies on gateway, to pass results to the CVAD site and then you would configure the Gateway "with conditions" settings in Smart Access.  Or even have separate gateways for internal/external users.



Link to comment
Share on other sites

It is a little more cumbersome than that, unfortunately.  The issue is with the Chromebooks all the traffic has to go through the gateway due to the client limitations on it, so what I need to do is be able to differentiate traffic that originates in my internal network and goes through the gateway and members of this group that go through the gateway to grant permissions accordingly.  These users need to be able to pick up a Chromebook inside my network and connect through the gateway to all resources, including a desktop.


I've got the bare bones of SmartAccess working, the TrustXMLRequests and all that, I can see policies in Director that are being sent by the gateway.  The place where I appear to be hanging up is how to create policies based on those two conditions to filter on the Delivery Groups.

Link to comment
Share on other sites

In this case, you would need the Gateway to run two session policies, based on client.ip.src.in_subnet("x.x.x.x/yy")  where X is your subnet and /yy is your subnet mask (/24 for example) or other operator.  You will then use the session policies on the gateway to pass the "in network" or external criteria to XD as it the CVAD site's IP filters won't work as all traffic comes from the same Gateway SNIP (from the CVAD perspective).


Option 1: is two separate session policies.  Option2 is separate vpn vservers for "in network" vs "off network" which then allows you to filter on different vpn vservers in the CVAD SmartAccess policies.  Option 1 is probably simpler for you.


To confirm your requirements: (If this isn't correct, we can revise, but the below example, should get the initial filter working so you can continue to tweak)

  • Non Chromebook users: internal users do NOT go through gateway, so will not be affected by gateway filters.
  • Chrome Users INTERNAL network, will go through Gateway and be ALLOWED access to resources.
  • Chome Users EXTERNAL network, will go trhough same Gateway and BE DENIED access to resources.


Option 1:

Create a session policy to identify (internaluser) || !chromebook 

If internaluser, chromebook doesn't matter --> get resources; If chromebook, then result is true only if internal user; otherwise expression is false if chromebook && external.



client.ip.src.in_subnet(x.x.x.x/yy) || !http.req.header("user-agent").set_text_mode(ignorecase).contains("<chromebook>") 

# NOTE:  I'm assuming chromebook users present a user-agent header that will have some sort of string that will identify chromebook; but also note user-agent's can be spoofed so its not a robust requirement.

# You can use the in_subnet operator to identify a subnet mask: or you can use a variety of ip range comparison operators depending on complexity.

# If you can't reply distinguish chromebook users via user-agent header, then we might need to look at separate vpn vservers to make this easier to separate, but this should work.


session_prof_null  this can be blank with no configured settings as it is not necessarily needed to set any profile settings).  Other session policies can contribute the ICA Proxy and other gateway settings IF they don't vary for this situation.

Bind this policy to your vpn vserver for gateway.


Additional session policies can be created if needed. This policies job is to run an expression the Gateway can look at and resolve as either TRUE or FALSE. The result is then passed to CVAD and if CVAD sees the gateway policy is TRUE then access is granted to the resource.



Then on your CVAD resources, when you configure SmartAccess:

Enable:  connections not going through gateway (internaluser) - all non gateway connections will get resources.

Enable: connections through gateway (externaluser) AND configure the addtional filter criteria.  Now only gateway connections, meeting this criteria will be granted access (so only some external users).

For "Access Gateway Farm" enter the name of the vpn vserver:  vpn_vsrv_gateway (the entity name on the NS and not its assigned FQDN).

Then for policy name, enter the name of the exact session policy that will result in TRUE when access to resources from a gateway connection should be allowed:  session_pol_internaluser (from above example).


I believe if you have more than one gateway vserver/policy name they are OR conditions, but you would need to test as this is the part we might need to finesse to solve your conditions here.  Meaning the user needs to meet one of the vpn/policy pairs not all of them...again, test to confirm.


This might allow you to see the results; then we can tweak the policy requirements to meet your exact needs if this isn't quite correct.













Link to comment
Share on other sites

I think that could work!  So if I filter to show that it's internal I can use that as an allow filter for the desktop and then I don't have to worry about the active directory group extraction for the application delivery groups that they need to see, since if they connect externally that session policy would be false and the desktop would be hidden.


Am I following correctly?

Link to comment
Share on other sites

YES, I think you have it right.  The logic is hard to follow sometimes :) , but if you want a truth table, I've made one below.


This way, if the criteria is actually about device type and network only, and not based on user groups at all, then you can skip worrying about group membership on the gateway (unless other settings depend on it) and just use normal group publishing in CVAD to make the decision.

IF there is an aspect where groups need to factor in to the decision the gateway is making, we can in fact do that...but it is more complicated. So i tried to avoid it, in this first pass.


There are a lot of different ways to do this; so if it needs to be revised more, we'll keep trying.



You have two internal scenarios:  real internal users who don't go through gateway and for which the CVAD site sees are in fact internal and so aren't affected by this (unless you uncheck the internal access).  This won't be affected by SmartAccess as long as internalaccess is enabled and then groups publishing will determine who sees what.


Then you have everyone else:

nonchromebook/gateway users/who have to be external:  NO restricted access

chromebook/gateway users/internal network:  NO restricted access

chrombeook/gateway users/external network: restricted


So, if I did the logic right, the policy TRUE results in you getting resources via the gateway connection.  So, I tried to write it where if chromebook && external it is false. All other scenarios should be allowed.


So, for this example, when the Gateway policy is TRUE for external users, you GET resources. When its FALSE, you don't:

client.ip.src.in_subnet(x.x.x.x/yy) || !http.req.header("user-agent").set_text_mode(ignorecase).contains("<chromebook>") 

I'm going to simplify this as A || !B


If A is ....                         *   If B is ....                     * then  A || !B is ....            * Policy results is ....

<internal network>    *   chrombeook            *    T || !T == T                        true (get resources)  

<internal network>    *   other                         *     T || !F == T                        true (get resources)

<external network>    *  chromebook            *     F || !T == F                         false (deny resources)  (chromebook && external)

<external network>    *  other                          *     F || !F == T                        true (get resources)  not chromebook && external


Non-gateway/internal only users won't be processed by this the with Gateway, meeting condition filter.



Link to comment
Share on other sites

Well, I got a bit further.  Now I'm getting an error "Advanced VPN Session Policy cannot be bound if Classic VPN Session Policy is already bound to any entity"


I'm guessing I'm going to have to go through and rewrite all my old policies that are in the classic syntax to fix this?

Link to comment
Share on other sites

Sorry, forgot about that.  You have two choices, you can change these policies to classic engine now, if you don't want to rewrite the others yet.

Or you change everything to advanced engine.  The policies that would be affected would be any session policies currently bound to the vpn vserver and/or AAA groups/AAA users.

Eventually, you'll have to move everything to advanced engine when the classic engine deprecates...


To do this in classic syntax,  it would be like this (though check my work, as I don't have an interface in front of me):

req.ip.source x.x.x.x -netmask y.y.y.y || !req.http.header user-agent contains <chromebook>



Also, to clarify, you would have to create NEW policies with classic expressions. You can't change the existing one's from classic to advanced or vice versa.

So you can have all your original policies with their original names, and make new instances:  <policyname>_adv 

Profiles don't change at this point.

Edited by Rhonda Rowland
updated note
Link to comment
Share on other sites

I think I'll just rewrite them, I don't have too many and at least to me the new syntax is a lot more logical to follow.


If I ultimately wanted to use SmartAccess with Active Directory group extraction (there is likely going to be an edge case eventually for a user where they'll need a desktop and be external) I'd have to bind a session policy to the AAA group?  I have the group extraction part working with AAA (a little cumbersome but really not very difficult), I'm just having trouble with the SmartAccess policy section and I can't seem to find any documentation at all on SmartAccess around groups / users.


Thanks so much for your help!  I think I'm very close to getting this working now.

Link to comment
Share on other sites

So, here's the thing, if you use authorization or authentication policies on the Gateway, you can move users into effectively temporary groups on the gateway. The gateway will then be able to process policies based on this temporary group membership.  But this will NOT be seen on the CVAD side.  OR you can bind policies based on their actual AD groups via AAA groups and group extraction.


But yes it is possible to have gateway policies that apply based on different AAA group memberships.  This could be passed to CVAD based on which vpn vserver/session policy results in true.  Just the gateway temporary groups wouldn't be seen on the CVAD side.


In this case, you can bind session policies based on the AAA group (via group extraction) or use authentication or session policies to move users into a temporary group and then they receive the policies of those temporary groups. Be sure that these policies have higher priorities than policies on other groups to override.

In the advanced engine, though you have one more way to do this that might be simpler.  You can use the http.req.user.<object> to retrieve the users group membership or other criteria. So policies can be bound to a vpn vserver but also based on the users AAA group membership.   For simple filtering, this is easier than policies per group.

If you need temporary group membership than the other methods work. (I realized, i might have answered a more complex scenario that you brought up...sorry.)



In some cases, depending on the complexity, it might be worth exploring when do you want all users/scenarios on one vpn vserver vs having separate vpn vservers/access points to more easily separate the scenarios.  Both are possible. Some will be easier than others, given your requirements.


Best of luck though. Hopefully, this gets you what you need.

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...