Adding Duo 2FA to Microsoft ADFS

KB ID 0001656

Problem

I did a Duo run through a few weeks ago, and to be honest their documentation is usually pretty good. I was spinning this up as a PoC for a client so I thought I’d put my take on the procedure here.

ADFS Duo Pre-Requisites

I already have a Duo Authentication Proxy server setup and my users are enrolled, you will need to set this up first. See the following article;

Duo: ADSync and Enroll Users via SMS

Log into the the Duo Admin Portal > Applications > Protect an Application > Search for and select Microsoft ADFS > Protect This Application.

 Copy the Integration Key, Secret Key and the API hostname to notepad.

Download the Duo AD FA MFA Adapter on your ‘first‘ ADFS server. Enter the information you copied to Notepad, (above). Tick ‘Bypass Duo Authentication when offline’, and because my users are logging on with their Office 365 UPNs, I’m also ticking ‘Use UPN username format’ (SEE USERNAME NORMALISATION NOTE BELOW.)

Note: I only have one ADFS server, if you have an ADFS Server farm you will need to install each one with the SAME shared session key, you can generate one of these yourself in PowerShell with the following commands;

[box]

$bytes = new-object "System.Byte[]" 30
(new-object System.Security.Cryptography.RNGCryptoServiceProvider).GetBytes($bytes)
[Convert]::ToBase64String($bytes)

[/box]

I only have one, so I’ll simply ‘Generate new session key‘ > Finish the install wizard.

Note: If one has already been deployed, and you don’t know the key, go to the ADFS server on which it’s working, and look in the following registry key.

[box]

HKEY_LOCAL_MACHINE\SOFTWARE\Duo Security\DuoAdfs\AKey

[/box]

USERNAME NORMALISATION: Because I’m logging users on with UPNs (first-name.last-name.domain-name.com) Back in the Duo Portal under protected applications Microsoft ADFS > Set username normalisation to ‘None” > Scroll down and save the change.

Server 2019 Only: I’m deploying on Server 2019 so I also need to execute the following Powershell command, you will need to enter YOUR API Hostname (you copied above).

[box]

Set-AdfsResponseHeaders -SetHeaderName "Content-Security-Policy" -SetHeaderValue "default-src 'self' 'unsafe-inline' 'unsafe-eval'; img-src 'self'; frame-src api-xxxxxxxx.duosecurity.com"

[/box]

Launch the ADFS Management Console > Authentication Methods > Additional Authentication Methods > Edit.

Tick ‘Duo Authentication for AD FS {version}’ > Apply > OK.

Relying Party Trust > Here I have my Office 365 trust, yours may be for something else! Edit Access Control Policy.

Click ‘Use Access Control Policy’ > The one I want is ‘Permit Everyone and Require MFA for Specific Group‘. This way I can select who gets 2FA challenged, and I can migrate users slowly into this group once I know they are enrolled, (also I use the same group to Sync the users to Duo to make things simple). Change the <parameter> and locate you domain security group.

Now when the users connect to ADFS, after they logon, they are challenged to provide 2FA authentication.

like so;

Related Articles, References, Credits, or External Links

NA

Publishing Remote Desktop Services With Web Application Gateway

KB ID 0001143 

Problem

Getting this article to completion has been a bit of a journey! This is the final post that will stitch together all the others I’ve posted over the last couple of weeks, that will enable you to publish your RemoteApps with  ‘Remote Desktop Web Access’, and have that service presented securely from your DMZ. I’ll be using Active Directory Federation Services, (you don’t have to, but it’s more secure than simply using ‘pass-though’ security).

Solution

Prerequisites

Topology: Simply getting your ‘ducks in a row’ will take a lot longer than actually deploying the service. Here is the topology that I’m going to deploy;

Firewall Rules: You will see I’ve labelled all the Certificate/CRL rules as optional, this is because you would only need them if you were using self signed certificates. In this example that’s what I am doing, this means that all my remote clients need the root certificate installing on them, so for production I suggest you purchase a publicly signed wildcard certificate for simplicity.

DNS Requirements: For your internal domain and the DMZ it’s simple enough but your external clients will need to be able to resolve your public URL (and the URL of your CRL is used).

Certificate Services (Optional): If you want to deploy self signed wildcard certificates you will  need a PKI environment and a published CRL. See the following article;

Windows Certificate Services – Setting up a CRL

Once setup you will need to generate a self signed wildcard certificate. See the following article;

Certificate Services – Create a ‘Wildcard Certificate’

Active Directory Directory Services: You need to have your ADFS farm deployed and ready to add your relying trust to. See the following article;

Deploy Active Directory Federation Services

Web Application Proxy: The Role needs installing ready to have the publishing rule added for Remote Desktop Web Access. See the following article;

Deploying Windows ‘Web Application Proxy’

MAKE SURE: You have ran Windows updates on the WAP server, there are a number of bugs that have been fixed, ensure you have at least KB2975719, and in addition you need to have KB2983037 Hotfix installed.

Step 1: Add A Relying Trust To Active Directory Federation Services For Web Application Proxy

On your ADFS Server > Administrative Tools > AD FS Management > AD FS > Trust Relationships > Relying Party Trusts > Add Relying Party Trust.

Next.

Enter data about relying party trust manually > Next.

Give the trust a name > Next.

AD FS Profile  > Next.

Next.

Next.

As an identifier, add in the UEL to access Remote Desktop Web Access > Next.

I do not want to configure multi-factor authentication settings for this relying  party trust at this time > Next.

Permit all users to use this relying party > Next.

Next.

Untick “Open Edit Claim Rules dialog  for this relying party trust when the wizard closes’ > Close.

You should see your relying part trust listed, take note of its name.

Step 2: Configure Web Application Proxy To Publish Remote Desktop Web Access

On the WAP Server > Administrative Tools > Remote Access Management > Select the Server > Publish.

Next.

Select ‘Active Directory Federation Services (AD FS) > Next.

Note: As mentioned above, you can choose ‘pass-through’, then author authentication is done on the internal RD Web Access server (which is less secure).

Select the relying trust you created above > Next. (If it’s not there check https is open, and you can resolve the AD FS service name) > Next.

Give the publishing rule a name, and enter the URL the service will be published on, (this is usually the same inside and outside but does not have to be) >  Select your wildcard certificate > Next.

Publish.

Close

In PowerShell execute the following command;

[box]

Get-WebApplicationProxyApplication -Name “SmoggyNinja Remote Desktop Web Access” | Set-WebApplicationProxyApplication -DisableHttp

[/box]

Then the following command;

[box]

Get-WebApplicationProxyApplication -Name “SmoggyNinja Remote Desktop Web Access” | Set-WebApplicationProxyApplication -DisableTranslateUrlInRequestHeaders:$true
[/box]

Note: You only actually need this command if you’re  using different URLs but let’s stick with a script that works.

Step 3: Additional Works.

On the Remote Desktop Session Host Server run the following commands;

[box]

Import-Module Remote Desktop

Set-RDSessionCollectionConfiguration -CollectionName SN-RDS-COLLECTION -CustomRdpProperty “pre-authentication server address:s:https://remote.smoggyninja.com`nrequire pre-authentication:i:1″

[/box]

Related Articles, References, Credits, or External Links

NA

Active Directory Federation Services – Certificate Error ‘CNG Key’

KB ID 0001129

Problem

When installing the Active Directory Federation Services Role, you need to supply a certificate. I was running this up using a self signed wildcard certificate when this happened;

The certificate with the specified thumbprint {thumbprint} has a Cryptographic Next Generation (CNG) private key. The certificates with the CNG private key are not supported. Use a certificate based on a key pair generated by a legacy Cryptographic Service Provider.

Solution

I was generating a wildcard certificate using this method. By default it uses the CNG Key, you need to specify  Legacy Key instead, (I’ve updated the post mentioned above to point out where that’s done).

Related Articles, References, Credits, or External Links

NA