Recently I had the pleasure to implement the Always On VPN mechanism from Citrix ADC. As there are three different technical possibilities, I will give you some insights about my deep dive, which should be an extension for Citrix Product documentation or other available posts about this topic.
Citrix ADC’s Always On is a great alternative to often used solutions like Microsoft’s. I think the biggest difference is the protocol – there is no PEAP/IKEv2, everything is handled as SSLVPN, using straight https 443. This can be a benefit when using port-restricted networks like Hotel or Public WiFi.
We have to difference between the following three setup options:
- Always On VPN before Windows Logon (aka the machine tunnel)
- Always On VPN after Windows Logon (aka the user tunnel)
- The combination of 1 + 2 for full Always On capabilities
I’ve created a script which is doing most of the configuration, but let’s get into some details, which settings I’m configuring and why.
I’m using two different EPA settings, one scan for the Machine Tunnel and the second when the User Tunnel is auto-established (with SSO). The product documentation is using username + password LoginSchema for SSO, that’s part of the supported Auto-Logon mechanism. My consideration is security – a aser is able to request the AOVPN GW-Page via Browser and is only prompted with username + password, that’s not enough in these days.
Luckily, EPA Device-Cert scan + username and password (which is filled of the Auto-Logon) is working fine. It is also working fine when using a User-Cert instead of Device-Cert scan with EPA. You just have to think about if you would like to enroll a Device and a User-Cert per client.
Next config is to differ Client-IP Pools between Machine Tunnel and User Tunnel, as mostly the Machine Tunnel should only get access to ADS / DNS / Software-Deployment-Servers / RemoteHelp / WSUS / … while User Tunnel get access to different application servers where the user has to work with. I’m creating a local AAA Group called AAA_local_device_tunnel and bind a separate intranet IP range. The AAA group is bound to the Machine Tunnel EPA Scan with the -default EPAGroup command.
#script for creating AlwaysOn VPN Config which includes a Machine-Tunnel and User-Tunnel with separated Client-IP Pools, Auto-Logon and two times EPA Device-Cert Scan #replace 10.103.117.17 with your Machine-Tunnel Client-IP Pool #replace 10.103.117.18 with your User-Tunnel Client-IP Pool #create your own LDAPS action and bind to Adv_Pol_LDAPS Policy #binding your complete PKI Certificates is a must have for a successful EPA Scan #use your preferred loginschema XML for UsernameAndPassword.xml #replace contoso.local with your internal Active-Directory FQDN ############################################################################################################################# #General Settings add dns suffix contoso.local #AAA Settings add authentication vserver AAA_vServer_AO_MachineTunnel_NA SSL 0.0.0.0 -certkeyNames "FRLAB-RootCA,FRLAB-IssuingCA" add authentication authnProfile AAA_Prof_AO_MachineTunnel -authnVsName AAA_vServer_AO_MachineTunnel_NA bind ssl vserver AAA_vServer_AO_MachineTunnel_NA -certkeyName FRLAB-RootCA -CA -ocspCheck Optional bind ssl vserver AAA_vServer_AO_MachineTunnel_NA -certkeyName FRLAB-IssuingCA -CA -ocspCheck Optional add authentication epaAction PreAuth_AOVPN_UserEPA_DeviceCert -csecexpr "sys.client_expr(\"device-cert_0_0\")" add authentication Policy Adv_Pol_AOVPN_UserEPA_DeviceCert -rule true -action PreAuth_AOVPN_UserEPA_DeviceCert add authentication policylabel NoSchema-ChooseCert -loginSchema LSCHEMA_INT add authentication loginSchema Schema_OnlyUsernameAndPassword -authenticationSchema "/nsconfig/loginschema/Customer/UsernameAndPassword.xml" add authentication policylabel LDAP_UsernameAndPasswordOnly -loginSchema Schema_OnlyUsernameAndPassword bind authentication policylabel LDAP_UsernameAndPasswordOnly -policyName Adv_Pol_LDAPS -priority 100 -gotoPriorityExpression END bind authentication policylabel NoSchema-ChooseCert -policyName Adv_Pol_AOVPN_UserEPA_DeviceCert -priority 100 -gotoPriorityExpression NEXT -nextFactor LDAP_UsernameAndPasswordOnly bind authentication vserver AAA_vServer_AO_MachineTunnel_NA -policy Adv_Pol_AOVPN_EPA_DeviceCert -priority 100 -gotoPriorityExpression NEXT bind authentication vserver AAA_vServer_AO_MachineTunnel_NA -policy Adv_Pol_AOVPN_UserTunnel -priority 110 -nextFactor NoSchema-ChooseCert -gotoPriorityExpression NEXT add aaa group AAA_local_device_tunnel bind aaa group AAA_local_device_tunnel -intranetIP 10.103.117.17 255.255.255.255 add authentication epaAction PreAuth_AOVPN_EPA_DeviceCert -csecexpr "sys.client_expr(\"device-cert_0_0\")" -defaultEPAGroup AAA_local_device_tunnel add authentication Policy Adv_Pol_AOVPN_EPA_DeviceCert -rule is_aoservice -action PreAuth_AOVPN_EPA_DeviceCert add authentication Policy Adv_Pol_AOVPN_UserTunnel -rule is_aoservice.not -action NO_AUTHN #Gateway vServer Settings add vpn alwaysONProfile AOVPN-Prof -clientControl ALLOW add aaa user jakobj bind aaa user jakobj -intranetIP 10.103.117.18 255.255.255.255 add vpn sessionAction VPN_With_SplitTunnel -dnsVserverName LB_vServer_DNS_NA -splitDns BOTH -sessTimeout 480 -splitTunnel ON -localLanAccess ON -transparentInterception ON -defaultAuthorizationAction ALLOW -proxy OFF -clientCleanupPrompt OFF -forceCleanup none -icaProxy OFF -ClientChoices OFF -iipDnsSuffix frlab.cloud -WindowsPluginUpgrade Never -MacPluginUpgrade Never -LinuxPluginUpgrade Never -iconWithReceiver ON -alwaysONProfileName AOVPN-Prof add vpn sessionPolicy ADV_Pol_VPN_With_SplitTunnel true VPN_With_SplitTunnel bind aaa user jakobj -policy ADV_Pol_VPN_With_SplitTunnel -priority 5 -gotoPriorityExpression NEXT add vpn vserver GW_vServer SSL 192.168.10.5 443 -dtls OFF -certkeyNames "FRLAB-RootCA,FRLAB-IssuingCA" -Listenpolicy NONE -authnProfile AAA_Prof_AO_MachineTunnel bind ssl vserver GW_vServer -certkeyName FRLAB-RootCA -CA -ocspCheck Optional bind ssl vserver GW_vServer -certkeyName FRLAB-IssuingCA -CA -ocspCheck Optional add vpn intranetApplication "LAB APP" ANY 10.103.117.0 -netmask 255.255.255.0 -destPort 1-65535 -interception TRANSPARENT bind vpn vserver GW_vServer -intranetApplication "LAB APP" save config
All Always On VPN settings for the Citrix Secure Access Client are controlled via registry at HKLM\Software\Citrix\Secure Access Client and let’s check the differences and which settings are controlled by ADC when connecting and which you have to set by manual (or controlled via software deployment / GPO / …)
The most important setting is REG_DWORD AlwaysOnService, which isn’t automatically handled by ADC. You have to create the key by manual.
1 = Establish machine tunnel but not user tunnel
2 = Establish machine tunnel and replaced by user tunnel after logon to Windows
Settings for Always On VPN before Windows Logon (aka the machine tunnel):
The necessary settings are set automatically after the next user-login to the SSLVPN Gateway, so the Machine Tunnel will initiate after next reboot of the client.
This is how the Machine Tunnel looks like on ADC active sessions – the username is the Client-FQDN, this is pulled of the Common Name (CN) field of the device cert. If a device tries to log in with empty CN device certificates, its VPN session is created with the user name as “anonymous”. In a Client-IP Pool (IIP) setup (which I’m always using to differ between AD-Groups and corresponding IP-Pools), if multiple sessions have the same user name, previous sessions are disconnected. So, when IIP is enabled, you notice the functionality impact because of an empty common name.
Settings for Always On VPN after Windows Logon (aka the user tunnel):
The necessary settings are set automatically after the next user-login to the SSLVPN Gateway, so the User Tunnel will initiate after next reboot and Windows-Login of the client, as the Secure Access Client is using the local credentials as SSO. The difference to the Machine Tunnel is the missing AlwaysOnService REG_DWORD
Settings for Always On VPN before Windows Logon (aka the machine tunnel) followed by Always On VPN after Windows Logon (aka the user tunnel):
Look and Feel
As already shown in Citrix Product documentation, the Citrix Secure Access Client Logo is appearing in Windows credentials manager, giving information about the Machine Tunnel (aka service mode) connection state:
After logon to Windows and only using the Machine Tunnel, you will notice a limited Secure Access Client menu, there are no secured applications shown or no way to disconnect the session – as it’s “Always On” 🙂
When using Machine Tunnel + User Tunnel or only User Tunnel, after logon to Windows, you will notice the following popup, when DNS resolution for suffixList cannot be resolved or resolves in non-private-IPs.
…followed by the User Tunnel connection established popup. The Client Control setting in ADC AlwaysOn Profile chooses whether the user is able to disconnect the session, or not.
- If the Auto-Login (SSO) mechanism after successful login to your Windows Account on your client isn’t working, check the permissions on C:\ProgramData\Microsoft\Crypto\RSA\MachineKeys and the underlying files, as the Secure Access Client is using these MachineKeys for SSO.
- Rollout or install the Secure Access Client as administrator, otherwise the inbuilt EPA-Agent isn’t able to access the client device certificate and the EPA-Check will fail.
- The Client-Registry REG_SZ suffixList is the DNS-Suffix which you configured in your ADC Setup. This is used by the AOVPN Service to check if the Secure Access Client is able to resolve the FQDN with a private or public IP, to choose if a VPN connection has to initiate (external) or not (when connected directly internal). Set your ADS FQDN with add dns suffix contoso.local.
- In ADC 13.0 build 71.44 and newer, the Secure Access Client for Windows supports Secure DNS update, which is disabled by default. I highly recommend to enable the setting within the Client-Registry REG_DWORD secureDNSUpdate and set it to 1 (When you set the value to 1, the plug-in tries the unsecure DNS update first. If the unsecure DNS update fails, the VPN plug-in tries the secure DNS update. To try only the secure DNS update, you can set the value to 2)
- When using Citrix ADC native OTP as a second factor during your AOVPN login-mechanism, see Julian Mooren’s Post about a necessary traffic policy.
- Create a dedicated traffic policy when using AOVPN / SSLVPN – otherwise the bearer authorization header get dropped and SSO to OAuth Webapps will fail.
Citrix ADC Always On is a great alternative Always On VPN solution. To note some cost hints, ICA Only mode has to be false – which means the Universal Licenses come to play. ADC Standard edition brings 500, Advanced 1000 and Premium unlimited concurrent universal licenses. Don’t forget these limitations when sizing a machine AND user tunnel Always On VPN architecture, as both tunnels consume licenses.