Note: After publishing, I decided to rework this blog post a bit to separate the AD-integrated Duo configuration from the Duo-only configuration. This should make the post easier to follow.
In my last post, I went through the steps for deploying a Horizon Access Point/Unified Access Gateway using the PowerShell deployment script. That post walked through the basic deployment steps.
The Unified Access Gateway supports multiple options for two-factor authentication, and many real-world deployments will use some form of two-factor when granting users access to their desktops and applications remotely. The Unified Access Gateway supports the following two-factor authentication technologies:
- RSA Secur-ID
- Certificate Based/Smart-Cards
Because I’m doing this in a lab environment, I decided to use a RADIUS-based technology for this post. I’ve been using Duo Security for a while because they support RADIUS, have a mobile app, and have a free tier. Duo also supports VMware Horizon, although they do not currently have any documentation on integrating with the Access Point/Unified Access Gateway.
Duo Security for Multi-factor Authentication
Duo Security is a cloud-based MFA provider. Duo utilizes an on-premises Authentication Proxy to integrate with customer systems. In addition to providing their own authentication source, they can also integrate into existing Active Directory environments or RADIUS servers.
When using Active Directory as the authentication source, Duo will utilize the same username and password as the user’s AD account. It will validate these against Active Directory before prompting the user for their second authentication factor.
Understanding Unified Access Gateway Authentication Path
Before I configure the Unified Access Gateway for two-factor authentication with Duo, let’s walk through how the appliance handles authentication for Horizon environments and how it compares to the Security Server. There are some key differences between how these two technologies work.
When the Security Server was the only option, two-factor authentication was enabled on the Connection Servers. When users signed in remotely, the security server would proxy all authentication traffic back to the connection server that it was paired with. The user would first be prompted for their username and their one-time password, and if that validated successfully, they would be prompted to log in with their Active Directory credentials. The reliance on connection servers meant that two sets of connection servers needed to be maintained – one internal facing without multi-factor authentication configured and one external facing with multi-factor configured.
Note: When using Duo in this setup, I can configure Duo to use the same initial credentials as the user’s AD account and then present the user with options for how they want to validate their identity – a phone call, push to a mobile device, or passcode. I will discuss that configuration below.
The Unified Access Gateway setup is, in some ways, similar to the old Security Server/Connection Server setup. If 2FA is used, the user is prompted for the one-time password first, and if that is successful, the user is prompted for their Active Directory credentials. But there are two key differences here. First, the Unified Access Gateway is not tied to a specific Connection Server, and it can be pointed at a load-balanced pool of connection servers. The other difference is 2FA is validated in the DMZ by the appliance, so 2FA does not need to be configured on the Connection Servers.
Horizon has a couple of multi-factor authentication options that we need to know about when doing the initial configuration. These two settings are:
- Enforce 2-factor and Windows user name matching (matchWindowsUserName in UAG) – enabled when the MFA and Windows user names match.
- Use the same username and password for RADIUS and Windows authentication (WindowsSSOEnabled in UAG) – Used when the RADIUS server and Windows have the same password. When this setting is enabled, the domain sign-on prompt is skipped.
If my two-factor authentication system supports Active Directory authentication, I can use my Windows Username and Password to be authenticated against it and then receive a challenge for a one-time password (or device push). If this second factor of authentication is successful, I will be automatically signed into Horizon.
The Duo environment needs to be configured before Horizon MFA can be set up. Duo requires an on-premises authentication proxy. This proxy acts as a RADIUS server, and it can run on Windows or Linux. The steps for installing the Duo authentication proxy are beyond the scope of this article.
Once the authentication proxy is installed, it needs to be configured. Duo has a number of options for configuration, and it’s important to review the documentation. I’ll highlight a few of these options below.
The first thing we need to configure is the Duo client. The client determines what type of primary authentication is performed. Duo supports three methods:
- ad_client: Duo uses Active Directory for primary authentication. Users sign in with their Active Directory username and password.
- radius_client: Duo uses the specified RADIUS server, such as Microsoft NPS or Cisco ACS, for primary authentication.
- duo_only_client: Duo does not perform primary authentication. The authentication proxy only performs secondary authentication, and primary authentication is handled by the configured system.
I don’t have a RADIUS server configured in my lab, so I did testing with both the ad_client and the duo_only_client. I prefer a single sign-on solution in my lab, so this setup will be configured with the ad_client.
The authentication proxy configuration is contained in the authproxy.cfg file located in C:\Program Files (x86)\Duo Security Authentication Proxy\conf. Open this file in a text editor and add the following lines:
Duo includes a number of options for configuring an Active Directory client, including encrypted passwords, LDAPS support, and other security features. The configuration above is a simple configuration meant for a lab or PoC environment.
Before the RADIUS server settings can be configured, a new application needs to be created in the Duo Administration Console. The steps for this are:
1. Log into the Duo Admin Console.
2. Click Applications
3. Click Protect an Application
4. Scroll down to VMware View and select “Protect this Application.”
5. Copy the Integration Key, Secret Key, and API Hostname.
6. Change the username normalization option to “Simple.”
7. Click “Save Changes.”
The next step is to configure the authentication proxy as a RADIUS service. Duo also has a number of options for this. These determine how Duo interacts with the client service. These options include:
- RADIUS_Auto: The user’s authentication factor, and the device that receives the factor, is automatically selected by Duo.
- RADIUS_Challenge: The user receives a textual challenge after primary authentication is complete. The user then selects the authentication factor and device that it is received on.
- RADIUS_Duo_Only: The RADIUS service does not handle primary authentication, and the user’s passcode or factor choice is used as the RADIUS password.
Duo also has multiple types of authentication factors. These options are:
- Passcode: A time-based one-time password that is generated by the mobile app.
- Push: A challenge is pushed to the user’s mobile device with the Duo mobile app installed. The user approves the access request to continue sign-in.
- Phone Call: Users can opt to receive a phone call with their one-time passcode.
- SMS: Users can opt to receive a text message with their one-time passcode.
RADIUS_Challenge will be used for this setup. In my testing, the combination of an ad_client and RADIUS_Auto meant that my second authentication factor was a push to the mobile app. In most cases, this was fine, but in situations where my laptop was online but my phone was not (such as on an airplane), meant that I was unable to access the environment. The other option is to use RADIUS_Duo_Only with the Duo_Only_Client, but I wanted a single sign-on experience.
The RADIUS server configuration for the Horizon Unified Access Gateway is:
ikey=[random key generated by the Duo Admin Console]
skey=[random key generated by the Duo Admin Console]
api_host=api-xxxx.duosecurity.com [generated by the Duo Admin Console]
radius_ip_1=IP Address or Range
The above configuration is set to fail secure. This means that if the Duo service is not available, users will be unable to log in. The other option that was selected was a short prompt format. This displays a simple text message with the options that are available and prompts the user to select one.
Save the authproxy.cfg file and restart the Duo Authentication Proxy service for the new settings to take effect.
The next step is to configure the Unified Access Gateway to use RADIUS. The following lines need to be added to the [Horizon] section:
A new section needs to be added to handle the RADIUS configuration. The following lines need to be added to create the RADIUS section and configure the RADIUS client on the Unified Access Gateway. If more than one RADIUS server exists in the environment, you can add an _2 to the end of hostname and auth_port.
hostName=IP.to.RADIUS.Server [IP of the primary RADIUS server]
Save the UAG configuration file and deploy, or redeploy, your Unified Access Gateway. When the deployment completes, and you log in externally, you should see the following screens:
So what if I don’t want an AD-integrated single sign-on experience? What if I just want users to enter a code before signing in with their AD credentials. Duo supports that configuration as well. There are a couple of differences compared to the configuration for the AD-enabled Duo environment.
The first change is in the Duo authentication proxy config file. No AD client configuration is required. Instead of an [ad_client] section, a single line entry of [duo_only_client] is required. The RADIUS Server configuration can also mostly stay the same. The only required changes are to change the client from ad_client to duo_only_client and the section name from [radius_server_challenge] to [radius_server_duo_only].
The Access Point configuration will change. The following configuration items should be used instead:
authMethods=radius-auth && sp-auth