Showing posts with label citrix. Show all posts
Showing posts with label citrix. Show all posts

Monday, October 12, 2015

Netscaler Gateway - Configure inside/outside access rules based on AD Groups

I fought with this one for awhile. Like many others, the client had remote access configured to run through a Netscaler to a Web Interface server. And also like many others, we had to migrate this one toward Netscaler + Storefront. The detail here was that the client had two groups of users: Those allowed to work from home, and those who were not. This was controlled by AD membership in a security group.

On the older setup, the membership was checked after the netscaler, at the web-interface server. So after much thinking, more coffee, and a couple applications of forehead to desk, I determined I was going to use session policies to determine which IP address the client was coming from, and filter on AD group if the client was coming from the IP of the firewall.

I'm not covering certificate configuration, or look and feel, there are quite a few blogs that have covered these topics better then I could have done. This is about session policies and security.


Configure AAA Groups

  1. After Setting up your Gateway vServer, make sure you configure your AD Domain under the "Authentication" panel of your vserver.
  2. Navigate to "Netscaler Gateway" -> "User Administration" -> "AAA Groups".
  3. Add a new group (The name you enter here has to match your AD Security group name EXACTLY, it's case sensitive. If there was a place to use copy and paste, this is one of them.)
  4. On the next screen, click "Authorization Policies" on the right bar.


  5. Click on "No Authorization Policy"
  6. Click "Add Binding"
  7. Click the "+" Next to "Select Policy" (after the first time, you can choose the created policy for any other AD groups)
  8. Give it a name like "Auth_Policy_Allow", make sure the action is set to "Allow" and enter "ns_true" (no quotes) for the Expression, then click "Create".
  9. Click "Bind"
  10. Click "Close"
  11. Repeat Steps 3-10 above for any other AD Groups you may have.

Configure Session Profile

  1. Within your Gateway vServer, navigate to the Policies tab, Click the "+" in the upper right to add. (If the Policies tab is not shown, add it from the "Advanced Settings" pane on the right.)
  2. Select "Session" and "Request", then click "Continue".
  3. Click "Add Binding"

  4. Click the "+" to the right of "Select Policy".
  5. Click the "+" next to the "Profile" selector.
  6. Give the Profile a name. As best as I understand, the Profile controls some of the connection settings, the Policy controls when the bound profile is used. The Binding links the previous two to a vServer, in an order of application. This may help you choose your name.
  7. Click the "Security" tab.
    - Check "Default Authorization Action" and set to "Deny" (This is why we set the auth policy on the AAA groups)
    - Check "Advanced Settings"
    - Check "Authorization Groups" and move any AAA groups form the left to the right to give them access.
  8. Click the "Published Applications" tab, and configure with your storefront Web Interface Address (your settings may differ)
  9. Click "Create" to save your Session Profile.
  10. Now your profile will be set, you need to name your Policy, and set an expression. If all your external traffic comes from a single IP, say.... 192.168.0.1 then your expression would be:

    REQ.IP.SOURCEIP == 192.168.0.1

    If your external traffic comes from a subnet, IP range, or a few scattered IPs, you'll need to build a bigger expression.
  11. Now that your profile and policy is set, you have to give it a Priority Number. I don't claim to have a full understanding of how Netscaler Priorities work, but I do know that the Deny binding number needs to be LOWER then the Allow binding (which we still have to create). Pick your number, and choose "Bind".
  12. Now redo the above steps, for your internal traffic, BUT
    - Leave out the security config (step 7)
    - For the policy expression (step 10)  enter:  ns_true
    - For the binding priority, go one lower (if you picked 100, go with 99
At this point, you should have a Gateway vServer that allows logins for all internally, but requires your AD membership when coming from outside addresses. If you need to test without actually going outside your network, you can use a different expression to treat your admin subnet or IP address as "outside". This expression allows you to filter on a subnet instead, just make sure you don't lock out anyone important :D

REQ.IP.SOURCEIP == 192.168.2.0 -netmask 255.255.255.0     













Tuesday, April 8, 2014

get-XALoadDetails

I wanted a tool to be able to pull load information from the different cmdlets available in the XenApp powershell snapin, I also took the opportunity to learn how powershell modules work. Grabbing from get-xaserver, get-xaloadevaluator, and get-xaserver it produces the following output:

LoadEval LoginStatus   Load     Sessions Max ServerName
-------- -----------   ----     -------- --- ----------
Default  AllowLogOns   2100           21 100 XenAppSvr

It accepts pipeline input (from get-xaworkergroupserver for instance) and includes handling for the snap-in to avoid the getting the snap-in scope-locked.



xenModules.psm1
<?ps
#Requires -version 2.0
#Requires –PSSnapin Citrix.XenApp.Commands


function get-XALoadDetails{
    #.Synopsis
        # Gathers XenApp Load Evaluation Data into a single object
    #.Description
        # Gathers XenApp Load Evaluation Data into a single object, useful for determining load balancing behavior. Requires Citrix Xenapp Powershell snapin.
    #.Parameter Server
        # Server to pull load Evaluation data from, or enter * or all, to poll the entire farm.
    #.Parameter HandleSnapin
        # Loads and unloads the Citrix.XenApp.Commands snapin for the script. Default is false.
    #.Example
        # Show Load Balancing Details for server "2K8-Hamster"
        # Get-XALoadDetails -Server 2K8-Hamster
    #.Example
        # Show Load Balancing Details for all XenApp Servers
        # Get-XALoadDetails -Server All
 
  [cmdletbinding()]
    param(
            # Target Server, or * to pull all Xen Servers
            [Parameter(Position=0, Mandatory=$True, ValueFromPipeline=$True)]
            [string[]]$server,
            # Handle loading the snapin? Default is no.
            [Parameter(Position=1, Mandatory=$False)]
            [Alias("LS")]
            [switch]$handleSnapin
       )
    BEGIN{
        #Handling the Citrix Snapin. If the $handleSnapin is called, CHECK to see if the snapin is loaded before continuing
        #If the snapin was already loaded, set $handleSnapin to $false
            if($handleSnapin -eq $true){
                if ((Get-PSSnapin -name Citrix.XenApp.Commands -ErrorAction SilentlyContinue) -eq $null){
                    Add-PSSnapin Citrix.XenApp.Commands
                    }ELSE{
                    $handleSnapin = $false
                    }
            }
 
        #{Add-PSSnapin citrix*}
        $allLoads = Get-XAServerLoad #grab load info ONCE
        
         
         
                                                         
    }PROCESS{
        
        [string[]]$servers = " "
        if ($server -eq "*" -or $_ -eq "all")
            {$servers = Get-XAServer | sort ServerName | select -expand servername}
            ELSE
            {$servers = $server}
                
        
          #if (($server -eq "*") -or ($server -eq "all")){$server = Get-XAServer | sort ServerName | select -expand servername}
          $servers
        foreach ($server in $servers){
        if((Test-Connection -count 1 ($server) -quiet) -eq $true){
            "yup"
            $3in1 = get-xaserver ($server) -full | select ServerName, SessionCount, LogOnMode
            $allEvals = get-xaloadevaluator -server ($3in1.ServerName) | select ServerUserLoad, LoadEvaluatorName
            $obj = New-Object PSObject -Property @{
                MaxSessions = $allEvals.ServerUserLoad
                LoadEvaluator = $allEvals.LoadEvaluatorName
                LoginStatus = $3in1.LogOnMode
                Load = $allLoads | where{($3in1.ServerName) -eq $server.ServerName} | select -expand Load
                Sessions = $3in1.SessionCount
                ServerName = $3in1.Servername
                }
            $obj.pstypenames.Insert(0,'xenModule.LoadDetails')
            $obj
             
            }

        }
 
    }END{
    #Remove PSSnapin if it wasn't loaded before, to avoid scope locking
    if($handleSnapin -eq $true){Remove-PSSnapin Citrix.XenApp.Commands
        }
    }
 
}##End of get-XALoadDetails Function
export-modulemember -function get-XALoadDetails


xenModules.psd1
<?ps
#Requires –PSSnapin Citrix.XenApp.Commands
#
# Module manifest for module 'xenModules'
#
# Generated by: Jared Shippy
#
# Generated on: 04/03/2014
#

@{

# Script module or binary module file associated with this manifest
# RootModule = ''

ModuleToProcess = 'xenModules.psm1'

# Version number of this module.
ModuleVersion = '1.0'

# ID used to uniquely identify this module
#GUID = 'd0a9150d-b6a4-4b17-a325-e3a24fed0aa9'

# Author of this module
Author = 'Jared Shippy'

# Company or vendor of this module
#CompanyName = 'Unknown'

# Copyright statement for this module
#Copyright = '(c) 2012 User01. All rights reserved.'

# Description of the functionality provided by this module
# Description = ''

# Minimum version of the Windows PowerShell engine required by this module
#PowerShellVersion = '2'

# Name of the Windows PowerShell host required by this module
# PowerShellHostName = ''

# Minimum version of the Windows PowerShell host required by this module
# PowerShellHostVersion = ''

# Minimum version of the .NET Framework required by this module
# DotNetFrameworkVersion = ''

# Minimum version of the common language runtime (CLR) required by this module
# CLRVersion = ''

# Processor architecture (None, X86, Amd64) required by this module
# ProcessorArchitecture = ''

# Modules that must be imported into the global environment prior to importing this module
# RequiredModules = @()

# Assemblies that must be loaded prior to importing this module
# RequiredAssemblies = @()

# Script files (.ps1) that are run in the caller's environment prior to importing this module
# ScriptsToProcess = @()

# Type files (.ps1xml) to be loaded when importing this module
# TypesToProcess = @()

# Format files (.ps1xml) to be loaded when importing this module
FormatsToProcess = @('xenModules.Format.ps1xml')

# Modules to import as nested modules of the module specified in RootModule/ModuleToProcess
# NestedModules = @()

# Functions to export from this module
FunctionsToExport = '*'

# Cmdlets to export from this module
CmdletsToExport = '*'

# Variables to export from this module
VariablesToExport = '*'

# Aliases to export from this module
AliasesToExport = '*'

# List of all modules packaged with this module
# ModuleList = @()

# List of all files packaged with this module
# FileList = @()

# Private data to pass to the module specified in RootModule/ModuleToProcess
# PrivateData = ''

# HelpInfo URI of this module
# HelpInfoURI = ''

# Default prefix for commands exported from this module. Override the default prefix using Import-Module -Prefix.
# DefaultCommandPrefix = ''

}


xenModules.Format.ps1xml
<?xml



  

  HashTable
  
    XenModule.LoadDetails
  
  
    
      
        
        8
      
      
        13
      
      
        8
      
      
        8
        Right
      
      
        
        3
      
      
        10
      
    
    
      
        
           
             LoadEvaluator
           
           
             LoginStatus
           
           
             Load
           
           
             Sessions
           
           
              MaxSessions
           
           
             ServerName