This guide will walk you through the steps to set up two-factor authentication on your Cisco ASA for your AnyConnect VPN users, whose credentials are managed by Active Directory. Relax, it only sounds complicated because it is, but not as much as I assumed after not being able to find a single tutorial on this.
You can use phone calls, SMS, mobile apps or OAUTH tokens for authentication. I recommend the phone call method because it’s free to receive, you don’t have to send anything back and it works on all devices made in the last 20 years.
- Cisco ASA with ASDM
- AnyConnect connection profile set up and working
- Active Directory authenticating your users
- Microsoft Azure subscription or trial
Azure will be responsible for initiating phone calls and processing the responses. Go to the Azure management portal, scroll down to Active Directory, select the Multi-Factor Auth Providers tab and create a new provider.
Once done, click Manage. There click Downloads and download the Multi-Factor Authentication Server to the server that’ll handle VPN authentication.
Multi-Factor Authentication Server
This server will sync users from AD, talk to the Cisco ASA via RADIUS and handle any incoming authentication requests. I strongly suggest you to allocate a separate VM for this instead of installing it directly on one of your DCs (I installed it on the VM that also performs Office 365 dirsync). It really won’t consume a lot of resources unless you’re gonna authenticate like 20 users per minute. If you don’t have .NET 2.0 the installer will tell you to install it, so in that case, go to the Control Panel and turn on this feature. Please note that MFAS does not require Windows Server, you can run it on the client versions as well.
Once installed, the Multi-Factor Authentication Server starts automatically. Skip the wizard.
Now you need to activate the server. For this you gotta generate the Activation Credentials on the same page you downloaded the installer from.
Then it asks for the group name. Enter something sensible, then proceed. Then it’ll also ask if you want to enable replication, but you’re prolly fine without it, at least for now. Once the activation’s finished, a lot of new options appear on the interface.
Now it’s time to set up RADIUS, the protocol on which the ASA and the MFAS will talk to each other. The ASA will only use one authentication port and one accounting port so you can remove the default alternative ports. Then add a new RADIUS client, specify the IP address of the ASA, give it a name and generate a shared secret – the same secret you’ll use on the ASA so take note of it. Also check Require Multi-Factor Authentication user match. Once added, also check Enable RADIUS authentication.
Finally, switch to the Target tab and select Windows domain.
Now set up AD sync so that the MFAS periodically fetches user info from AD. Go to Directory Integration and select the Synchronization tab. Check Enable synchronization with Active Directory. You prolly want to increase the sync interval to something more sensible than 5 minutes.
Then add a new sync item. You can choose to target by either container or security group. You can also target by both by using container hierarchy combined with a user filter. Set the other options according to your needs, then click Add.
Now you try to navigate to a different option but MFAS tells you immediately that it’s started to sync users.
That’s good. Now go to Users. Your users will not be visible right away and there’s no option to refresh the list, so your best bet is to go back and forth between Users and another option, e.g. RADIUS until they finally arrive – shouldn’t take much more than a few minutes.
Once they’re finally there, verify that the users don’t have issues. It’s quite possible that your phone number country codes are messed up. MFAS can split the country code from the phone number but only if you put a space between them, e.g. +36 301234567, not +36301234567. Once the phone numbers are fine, you can test if Azure can actually call you. Select a user, then click Test…. Specify the credentials:
Then test it.
Within a few seconds you should receive a phone call from a Washington phone number, where the operator will tell you to press the number sign (#) key. Once you do that, the authentication succeeds.
So that works now. You need to fix one last thing on the MFAS. Go to Company Settings and make sure that When user is disabled is set to Fail Authentication.
Now the MFAS works just fine, it’s time to move on to the ASA.
ASA will receive the VPN auth requests from AnyConnect clients, then ask MFAS if the credentials are correct. If they are, MFAS will tell Azure to call the user’s phone, and once the user acknowledges the call, Azure will report it to MFAS, which in turn will tell ASA to let the user in. So now it’s time to create a new AAA server that talks to MFAS and then modify your current AnyConnect connection profile to use this new AAA server. For this I’ll use ASDM coz I’m a lazy bastard GUI fag but feel free to use the CLI.
Go to Configuration / Remote Access VPN / AAA/Local Users / AAA Server Groups and add a new server group. The defaults are pretty much perfect here, you only need to specify the name.
Now add a server to this group. The interesting parts are IP address, port settings and the secret key which is, again, the same as what you’ve specified on the MFAS RADIUS page. Also make sure to increase the timeout to something like 60 seconds, otherwise there won’t be enough time to verify you over the phone.
Once done, apply the changes and test the server. Select Authentication, specify your credentials and click OK.
Then Cisco initiates the 2FA.
Within a few seconds you should receive a call from Azure again. Press #, then ASA should tell you that the test was successful.
And that’s it! Now you can use this AAA group with your AnyConnect connection profile.
There’s one caveat though: the AnyConnect client has a default timeout of 12 seconds. This is definitely not enough for 2FA, but thanks to the invaluable help of BK Rogers it’s also easy to fix. You need to create an AnyConnect Client Profile and explicitly set the timeout (the others didn’t need to be changed for me, defaults were fine).
Now you also gotta specify the FQDN of your VPN gateway, otherwise it won’t work.
Of course, this isn’t enough still, now you also need to assign this profile to the appropriate group policy that’s being applied to your AnyConnect connection profile.
On top of that, the profile’s only downloaded upon the first successful connection so if your users can’t succeed a single time, they won’t get the increased timeout. Workaround? Push the XML file to their computers. The location for connection profiles:
%ProgramData%\Cisco\Cisco AnyConnect Secure Mobility Client\Profile
- OS X / Linux:
On the ASA you can use the Real-Time Log Viewer by using the user’s name as filter but that only shows what happens after the user has authenticated.
If the user can’t get that far, you need to check out the MFAS logs. They can be found under
c:\Program Files\Multi-Factor Authentication Server\Logs, the filenames should be self-explanatory.
If, for any reason, you can’t use the phone (or whatever you use as the 2nd auth option), you can set up one-time bypass on the Azure portal and then you’ll only be asked for your username and password. This has some serious implications though: this means that this 2FA is only as secure as your authentication to the Azure management portal. Be safe!