Horizon Cloud on Azure – Duo Multi Factor Authentication Setup

We have already discussed how to use Windows NPS as Radius server in this article

Now let’s discuss how to setup duo as RADIUS server and integrate the same with Horizon Cloud on Azure.

We will use Ubuntu server as a Duo authentication proxy for this demonstration

  1. Install Duo authentication proxy
  2. Directory sync configuration in Duo admin console
  3. Duo admin console configuration for Horizon
  4. Configure Duo authentication proxy to support Horizon Cloud on Azure
  5. Add 2FA support in Horizon Admin console
  6. Authentication flow when Duo auth enabled
  7. How to check the logs for troubleshooting duo issues
Install Duo authentication proxy

Install the Duo Authentication Proxy in an Ubuntu server machine by following the DUO Documentation

Follow the below requirements for a successful authentication proxy setup

  • Create a Host A & PTR records for the Linux machine
  • Update the correct DNS server IPs in Linux machine /etc/resolv.conf file
  • Create a Read only domain user account for Duo Auth proxy and domain communication
  • Make sure Duo authentication proxy configured with static IP
  • Let’s have at least 1 vCPU & 1 GB RAM assigned to the Linux machine

The auth proxy installation will take at least 20 mins to complete

Directory sync configuration in Duo admin console
New to Duo

If you are new to DUO, first configure the Ad Sync

  • Login to Duo admin console
  • Click on Users –> Directory Sync –> Active Directory –> Add New Active Directory Sync


  • In the next screen it will ask you to install auth proxy
  • Since we already installed the auth proxy, either download the pre-configured file or note the Integration key, Secret key & API hostname.
  • Take an SSH to Duo auth proxy server
  • If Duoauthproxy already started, please stop using the below command
    Sudo /opt/duoauthproxy/bin/authproxyctl stop
  • Now login to auth proxy server and open authproxy.cfg file
    Sudo vim /opt/duoauthproxy/conf/authproxy.cfg
  • Comment all the lines and construct the below info and save the configuration

[cloud]
ikey=XXXXJTEPXXXXXXXX (Auth proxy integration key)
skey=xXXXXXXXXrRv6y5yXXXXXXXX (Auth proxy security key)
api_host=api-xxxxxx.duosecurity.com (Auth proxy api hostname)
service_account_username=svc_duo (Service account name)
service_account_password=XXXXXX (Service account password)

[ad_client]
host=XXX. XX. XX. XX (AD Server IP)
service_account_username=svc_duologin (Service account name)
service_account_password=XXXXXX (Service account password)
search_dn=CN=Users,DC=test,DC=com (DN of Users OU)

  • Start the Duoauthproxy
    Sudo /opt/duoauthproxy/bin/authproxyctl start
  • Click on Test connection and verify it’s passed

  • Once the test is passed, proceed with AD Directory configuration as mentioned in below screenshot

  • Leave the Synced attributes as default
  • Select the groups that you are limiting the sync with Active Directory and Save
Already using DUO

If AD sync is already configured, you can skip this step but please note the Authentication proxy’s Integration key, Secret key & API hostname

Duo admin console configuration for Horizon
  • Login to Duo admin console and click on Applications


  • Click on Protect Application


  • Seach as “VMware” and click on Protect


  • Please note the Integration key, Secret key & API hostname
    These details are required to configure Duo auth proxy


  • For this article I am going with default Policy configuration – no edits
  • In the Settings section, add the group where all the VDI users belongs to so that whoever part of this group duo login will go through


  • Click on Save to complete this configuration
Configure Duo authentication proxy to support Horizon Cloud on Azure
Duo auth proxy configuration
  • Login to the Duo auth proxy installed machine.
    In my case it’s an Ubuntu Server v18.04
  • All the Duo configuration (if we go with installation defaults) located in below path
    /opt/duoauthproxy/conf
  • If Duoauthproxy already started, please stop using the below command
    Sudo /opt/duoauthproxy/bin/authproxyctl stop
  • Copy all the contents from the file and add details as per your configuration

[cloud]
ikey=XXXXJTEPXXXXXXXX (Auth proxy integration key)
skey=xXXXXXXXXrRv6y5yXXXXXXXX (Auth proxy security key)
api_host=api-xxxxxx.duosecurity.com (Auth proxy api hostname)
service_account_username=svc_duo (Service account name)
service_account_password=XXXXXX (Service account password)

[ad_client]
host=XXX. XX. XX. XX (AD Server IP)
service_account_username=svc_duologin (Service account name)
service_account_password=XXXXXX (Service account password)
search_dn=CN=Users,DC=test,DC=com (DN of Users OU)

[radius_server_challenge]
ikey=XXXXXXXGJ6UAXXXXXX (Integration key – VMware View)
skey=XXXXXXXXxZRSXXXXXXXXXX (Secret key – VMware View)
api_host=api-XXXXXX.duosecurity.com (API hostname – VMware View)
failmode=safe
client=ad_client
radius_ip_1=10.XX.XX.3 (UAG DMZ IP)
radius_ip_2=10.XX.XX.4 (UAG DMZ IP)
radius_ip_3=10.XX.XX.5 (UAG DMZ IP)
radius_ip_4=10.XX.XX.6 (UAG DMZ IP)
radius_secret_1=XXXXXXX (Provide a password and note it for future)
radius_secret_2=XXXXXXX (Provide a password and note it for future)
radius_secret_3=XXXXXXX (Provide a password and note it for future)
radius_secret_4=XXXXXXX (Provide a password and note it for future)
port=1812

  • Start the Duoauthproxy
    Sudo /opt/duoauthproxy/bin/authproxyctl start
  • Check the connectivity log to see the connectivity to AD is successful.
    /opt/duoauthproxy/log/connectivity_tool.log
Troubleshooting AD connectivity Issues

Most of the times we see AD connectivity issues from the Duo auth proxy server. Use ldapsearch to check whether you can fetch user info from the server

ldapsearch -H ldap://ADIP -D svc_duo -w XXXXXX -b”DC=test,DC=com” “(&(objectclass=user) (userprincipalname=sandeep@test.com))” memberof primarygroupid &

Add 2FA support in Horizon Admin console
  • Login to Horizon admin console
  • Click on Settings –> Capacity
  • Click on the POD Name where you are planning to enable 2FA
  • Click on Edit and go to Gateway Settings and enter required details then SAVE & EXIT



  • Now we have 2FA is configured

Authentication flow when Duo auth enabled
  1. Users enter the AD credentials in the login portal
  2. Duo auth proxy forwards the request to AD server and validate the credentials
  3. Once credentials are verified, shows the Duo pre-auth page
  4. Enter the passcode from Duo app or type ‘push’ to send the notification for approval
  5. Once Duo auth is verified from Duo server, you will be shown with the entitlements

A rough (not accurate) diagram shown below
For a complete diagram please check DUO website

One thing to note here is all requests from UAG goes from DMZ IP
Sample logging is below/opt/duoauthproxy/log/authproxy.log

: In case of failure :

2021-05-20T14:26:09.020028+0000 [duoauthproxy.lib.log#info] Sending request from UAG DMZ IP to radius_server_challenge
2021-05-20T14:26:09.020934+0000 [duoauthproxy.lib.log#info] Received new request id 227 from ('UAG DMZ IP', 20152)
2021-05-20T14:26:09.021385+0000 [duoauthproxy.lib.log#info] (('UAG DMZ IP', 20152), user1, 227): login attempt for username 'user1'
2021-05-20T14:26:09.021722+0000 [duoauthproxy.lib.log#info] Sending AD authentication request for 'user1' to 'AD Server IP'
2021-05-20T14:26:09.021973+0000 [duoauthproxy.modules.ad_client._ADAuthClientFactory#info] Starting factory <duoauthproxy.modules.ad_client._ADAuthClientFactory object at 0x7f795e27e670>
2021-05-20T14:26:09.419931+0000 [duoauthproxy.lib.log#info] LDAP Authentication Failed: 'invalidCredentials: 8009030C: LdapErr: DSID-0C090590, comment: AcceptSecurityContext error, data 52e, v2580\x00'
: In case of success :

2021-05-20T14:36:54.262302+0000 [duoauthproxy.lib.log#info] Sending request from UAG DMZ IP to radius_server_challenge
2021-05-20T14:36:54.263102+0000 [duoauthproxy.lib.log#info] Received new request id 33 from ('UAG DMZ IP', 22932)
2021-05-20T14:36:54.263550+0000 [duoauthproxy.lib.log#info] (('UAG DMZ IP', 22932), user1, 33): login attempt for username 'user1'
2021-05-20T14:36:54.263962+0000 [duoauthproxy.lib.log#info] Sending AD authentication request for 'user1' to 'AD Server IP'
2021-05-20T14:36:54.264272+0000 [duoauthproxy.modules.ad_client._ADAuthClientFactory#info] Starting factory <duoauthproxy.modules.ad_client._ADAuthClientFactory object at 0x7f795e2470a0>

2021-05-20T14:36:54.658055+0000 [duoauthproxy.lib.log#info] http POST to https://api-xxxxxxx.duosecurity.com:443/rest/v1/preauth
2021-05-20T14:36:54.666361+0000 [duoauthproxy.lib.http._DuoHTTPClientFactory#info] Starting factory <_DuoHTTPClientFactory: b'https://api-xxxxxxx.duosecurity.com:443/rest/v1/preauth'>
2021-05-20T14:36:54.666885+0000 [duoauthproxy.modules.ad_client._ADAuthClientFactory#info] Stopping factory <duoauthproxy.modules.ad_client._ADAuthClientFactory object at 0x7f795e2470a0>
2021-05-20T14:36:55.340666+0000 [duoauthproxy.lib.log#info] (('UAG DMZ IP', 22932), user1, 33): Duo preauth returned 'auth'
2021-05-20T14:36:55.341314+0000 [duoauthproxy.lib.log#info] (('UAG DMZ IP', 22932), user1, 33): Sending authentication challenge packet
2021-05-20T14:36:55.341909+0000 [duoauthproxy.lib.log#info] (('UAG DMZ IP', 22932), user1, 33): Returning response code 11: AccessChallenge
2021-05-20T14:36:55.342411+0000 [duoauthproxy.lib.log#info] (('UAG DMZ IP', 22932), user1, 33): Sending response
2021-05-20T14:36:55.342868+0000 [duoauthproxy.lib.http._DuoHTTPClientFactory#info] Stopping factory <_DuoHTTPClientFactory: b'https://api-xxxxxxx.duosecurity.com:443/rest/v1/preauth'>
2021-05-20T14:36:55.870747+0000 [duoauthproxy.lib.log#info] Returning list of configured directory syncs. ['XXXXXXXXXXXXXXXXXXX']
2021-05-20T14:37:05.531047+0000 [duoauthproxy.lib.log#info] Sending request from UAG DMZ IP to radius_server_challenge
2021-05-20T14:37:05.532099+0000 [duoauthproxy.lib.log#info] Received new request id 3 from ('UAG DMZ IP', 53589)
2021-05-20T14:37:05.532793+0000 [duoauthproxy.lib.log#info] (('UAG DMZ IP', 53589), user1, 3): Valid response to challenge issued at id 33
2021-05-20T14:37:05.533621+0000 [duoauthproxy.lib.log#info] http POST to https://api-xxxxxxx.duosecurity.com:443/rest/v1/auth
2021-05-20T14:37:05.542598+0000 [duoauthproxy.lib.http._DuoHTTPClientFactory#info] Starting factory <_DuoHTTPClientFactory: b'https://api-xxxxxxx.duosecurity.com:443/rest/v1/auth'>
2021-05-20T14:37:11.607397+0000 [duoauthproxy.lib.log#info] (('UAG DMZ IP', 53589), user1, 3): Duo authentication returned 'allow': 'Success. Logging you in...'
2021-05-20T14:37:11.608063+0000 [duoauthproxy.lib.log#info] (('UAG DMZ IP', 53589), user1, 3): Sending access accept packet
2021-05-20T14:37:11.608527+0000 [duoauthproxy.lib.log#info] (('UAG DMZ IP', 53589), user1, 3): Returning response code 2: AccessAccept
2021-05-20T14:37:11.609004+0000 [duoauthproxy.lib.log#info] (('UAG DMZ IP', 53589), user1, 3): Sending response
How to check the logs for troubleshooting duo issues

Logs are in /opt/duoauthproxy/log folder

Check authproxy.log for authentication issues

common errors

  • Duo authentication returned ‘deny’: ‘Incorrect passcode. Please try again.’
    Cause: Duo response code wrong or expired
  • LDAP Authentication Failed: ‘invalidCredentials: 8009030C: LdapErr: DSID-0C090590, comment: AcceptSecurityContext error, data 52e, v2580\x00’
    Cause: This can happen any of below
    1) User credentials are wrong
    2) Duo auth proxy unable to communicate AD server
    3) Check Service account and credentials used for connectivity from Duo auth proxy to AD
    4) Check the network connectivity between Duo auth proxy and AD
  • Primary credentials rejected – User Authentication Failed
    Cause: Same as above

Scroll to Top