From Password Spray to SAML: Securing Cisco FTD AnyConnect VPN with Entra ID
Written with the help of Claude AI
Why we did this
Random Active Directory lockouts turned out to be a large password spray against our Cisco AnyConnect VPN, and the fix was moving VPN authentication to SAML with Microsoft Entra ID.
The starting point was common: a Cisco Firepower 1100-series firewall running FTD, managed on-box, with AnyConnect users signing in with their Windows AD password. Users kept getting locked out for no obvious reason.
This post walks through what we found and every step it took to fix it, including the problems we hit along the way. It's written for small IT teams who run a similar setup and are seeing the same symptoms.
What you'll end up with:
- VPN sign-in through Entra ID, with MFA on every connection
- The firewall never sees or forwards AD passwords, so spray attempts can't lock AD accounts
- Optional single sign-on through the user's default browser
Starting environment: FTD 7.2.x managed by Firepower Device Manager (FDM), AnyConnect 4.10, hybrid AD synced to Entra ID, no Entra ID P1 licences, and endpoint security plus a DLP agent on domain laptops.
Step 1: Prove the VPN is the source
One command on the FTD settled it. Before touching anything, confirm where the failed logons come from.
> show aaa-serverIt doesn't depend on logging being set up, and it shows request, accept and reject counts per authentication server. Ours showed this for the AD server group:
Counter | Value |
|---|---|
Authentication requests | ~774,000 |
Accepts | ~400 |
Rejects | ~770,000 |
Nearly every attempt failed, and each failure counted as a bad password against an AD account. The LOCAL group also showed ~73,000 rejects and zero accepts. Those were attempts against the built-in default connection profiles, which authenticate against an empty local database and never reach AD.
Two surprises came out of this:
- We weren't using RADIUS at all. The server group was plain LDAP on port 389, pointing straight at a domain controller. Check your actual config rather than relying on documentation or memory.
- The syslog buffer was missing everything.
show logging | include 113005returned nothing despite hundreds of thousands of failures. Buffer logging was off or set below informational. If you need source IPs, enable the internal buffer at level 6 or send syslog to a server.
If the reject count is low, the VPN isn't your problem. Check event 4740 on the PDC emulator instead: the Caller Computer Name points to the real source, which could be an Exchange server, a stale credential on a phone, or a cloud sign-in through Pass-through Authentication.
Why adding MFA through NPS wouldn't have helped
The usual advice is the NPS extension for Entra MFA. That checks the AD password first and only then prompts for MFA. Every wrong guess still counts against AD, so accounts keep locking. MFA through NPS stops a guessed password from being used, but it doesn't stop the lockouts.
Also check the accepts. At this volume, a few weak passwords may have been guessed, so review active sessions with show vpn-sessiondb anyconnect for unfamiliar IPs or users before going further.
Step 2: Choose SAML, and check what manages your firewall
SAML with Entra ID was the only option that stopped the lockouts. With SAML, the firewall redirects the user to Microsoft's sign-in page and never handles the password. Entra checks it instead, and its Smart Lockout absorbs the spray. If Entra Connect uses Password Hash Sync, failed attempts never reach your domain controllers at all.
FDM or FMC?
We lost time following FMC instructions on a box managed by FDM. The two have different menus and different field names. A quick way to tell: FMC is a separate server or VM you log into, while FDM is the web UI served by the firewall itself. Most Firepower 1000-series boxes in small offices use FDM.
The FDM 7.2 certificate limitation
On FDM 7.2 and earlier, Cisco only supports Duo as a SAML identity provider. The IdP signing certificate must have Basic Constraints: CA:TRUE, and Entra's signing certificate doesn't. The symptom is the error "Failed to generate SAML AuthnRequest", and show saml metadata <profile-name> returns blank sections.
You have two ways out:
- Upgrade to FDM 7.3 or later, which adds a Skip CA Certificate Check option when uploading a trusted CA certificate. This is what we did.
- Stay on 7.2 and use Cisco's workaround: generate your own signing certificate with
CA:TRUE, upload it to Entra as a PFX, make it active, and upload it to FDM. You then have to renew that certificate yourself before it expires.
The upgrade was worth doing anyway: newer releases add RA VPN threat detection and fix several actively exploited VPN vulnerabilities.
Step 3: Upgrade FTD, and watch for expired certificates
We went from 7.2.5 directly to 7.6.6, which Cisco supports as a single upgrade. Check your hardware first: the Firepower 2100 series can't run 7.6 and tops out at the 7.4 train, while the 1000 series is fine.
Before you start
- Take an FDM backup under Device → Backup and Restore, and download it off the box.
- Download the upgrade package for your model from software.cisco.com, not the reimage package.
- Run the readiness check in Device → Updates → System Upgrade.
- Plan a maintenance window. A single box reboots, so internet access and the VPN go down for 45–90 minutes. Never power-cycle it mid-upgrade.
- Go to Objects → Certificates and look for any certificate with an expiry date in the past. The readiness check didn't catch the one that broke our upgrade.
The failure we hit
The upgrade ran to the final stage and then failed. To find out why, check the status and the upgrade logs:
> show upgrade status detail
> expert
$ sudo su
# ls -lt /ngfw/var/log/sf/
# grep -iE "error|fatal|fail" /ngfw/var/log/sf/<upgrade-folder>/main_upgrade_script.log | tail -n 40The log showed 800_post/100_ftd_onbox_data_import.sh failing with "The chosen certificate has already expired." The new version installed fine, but re-importing the FDM configuration hit an expired certificate that 7.2 had tolerated and 7.6 rejected.
The culprit was DefaultWebserverCertificate, the self-signed certificate for the FDM web UI, which had expired two years earlier. show crypto ca certificates didn't list it, because that command only shows certificates deployed to the data plane. FDM keeps its own certificate database, and the upgrade validates all of it.
The fix
- Run
upgrade cancelto roll back to the old version with your configuration intact. - Create a new certificate under Objects → Certificates → Add Internal Certificate → Self-Signed. You can't renew the system default.
- Select the new certificate under Device → System Settings → Management Access → Management Web Server. Your browser session drops and shows a certificate warning, which is expected.
- Check the other places a certificate can be selected (RA VPN device identity, identity policy, SSL decryption), then delete any expired custom certificates.
- Back up again and rerun the upgrade.
Step 4: Configure Entra ID
The gallery app does most of the work, and you can enforce MFA without an Entra ID P1 licence. In the examples below, the VPN address is vpn.example.com and the new connection profile is called VPN-SSO.
Create a new connection profile rather than converting the old one
The connection profile name is part of both SAML URLs, so pick it once and use it everywhere with the same capitalisation. A new profile also lets you test with one user while the old one keeps working.
Add and configure the app
- In the Entra admin center, go to Enterprise applications → New application and add Cisco Secure Firewall - Secure Client.
- Open Single sign-on and choose the SAML tile. If you don't see the SAML settings, you're probably in App registrations instead of Enterprise applications.
- Under Basic SAML Configuration, set:
- Identifier:
https://vpn.example.com/saml/sp/metadata/VPN-SSO - Reply URL:
https://vpn.example.com/+CSCOE+/saml/sp/acs?tgname=VPN-SSO - If your VPN runs on a non-standard port, include it in both, for example
vpn.example.com:4334.
- Identifier:
- Download Certificate (Base64), and copy the Login URL and Microsoft Entra Identifier.
- Under Properties, set Assignment required to Yes, then assign users under Users and groups.
Without Entra ID P1
Conditional Access needs P1, and so do a few other things you'd expect to use. Here's how we worked around each:
Need | P1 approach | What we did without P1 |
|---|---|---|
Require MFA | Conditional Access policy | Per-user MFA, enabled for each VPN user and every admin |
Assign users to the app | Assign a security group | Assign each user individually |
Lockout threshold | Custom Smart Lockout | Default Smart Lockout (10 failures) |
For per-user MFA, turn off Security Defaults first. Then go to Users → Per-user MFA, enable the users, and under Service settings untick remember MFA on trusted devices so every connection prompts. Have users register the Authenticator app at https://aka.ms/mfasetup before cutover.
If Entra Connect uses Pass-through Authentication instead of Password Hash Sync, failed cloud sign-ins still hit AD. Make sure your AD lockout threshold is above Entra's, or switch to Password Hash Sync.
P1 is worth budgeting for later. Location-based Conditional Access alone would have blocked most of this spray.
Step 5: Configure SAML in FDM
FDM needs three objects and one global setting, and the global setting is the one most guides miss.
1. Upload the Entra certificate
Go to Objects → Certificates → + → Add Trusted CA Certificate. Upload the Base64 certificate and tick Skip CA Certificate Check. The checkbox only appears when adding a new certificate, not when editing one. If it's missing after an upgrade, hard-refresh the browser, because it may be showing the old UI from cache.
2. Create the SAML server object
Go to Objects → Identity Sources → + → SAML Server:
- IDP Entity ID URL: the Microsoft Entra Identifier,
https://sts.windows.net/<tenant-id>/, including the trailing slash - Sign In URL and Sign Out URL: the Entra Login URL, ending in
/saml2 - Identity Provider Certificate: the certificate from step 1
- Request Signature: None
3. Set the FQDN and port
There is no Base URL field in FDM. FDM builds the SAML base URL from the RA VPN global settings, which live inside the connection profile wizard.
Edit any connection profile and click Next until the Global Settings page. There, Fully-qualified Domain Name for the Outside Interface becomes the base URL, and Port Configuration sets the VPN port.
We ran the VPN on 4433 because FDM management was using 443 on the outside interface. That port mismatch cost us an afternoon: the SAML login URL came out without :4433 and went nowhere. The cleanest fix is to take FDM management off the outside interface entirely under Device → System Settings → Management Access → Data Interfaces, which you should do anyway, and run the VPN on 443.
4. Create the connection profile
Create VPN-SSO with SAML as the primary identity source, using your SAML object. Use the same address pool and group policy as your existing profile. Give it a group URL, and turn off the option that lets users pick a connection profile at the login page.
5. Verify before testing
> system support diagnostic-cli
# show running-config webvpn | include base-url
# show saml metadata VPN-SSOThe metadata output gives you the exact SP entity ID and ACS URL the firewall uses. Copy them into Entra's Identifier and Reply URL. Matching Entra to the firewall's own output avoids typos in the port, capitalisation, or trailing slashes.
If something fails, run debug webvpn saml 255, retry from the client, and read the output. Run undebug all when you're done.
Step 6: Fix the client-side problems
Once the firewall and Entra matched, SAML worked from a phone and a personal PC but failed on domain laptops. Both problems were on the endpoint, not the firewall.
"Profile settings mandate a single local user"
This appeared after a successful MFA approval. The client profile's Windows Logon Enforcement was set to SingleLocalLogon, and the test PC had a second Windows session still signed in. Run query user, sign off the extra session, and connect again. Keep the setting: it stops a second user on the same PC from riding someone else's tunnel.
"Sent an invalid response", then "validation failed"
On domain laptops, the embedded browser showed a TLS error. Refreshing loaded the Microsoft sign-in page and MFA succeeded, but the client then reported validation failed. The firewall debug showed:
%FTD-3-716164: SAML response relay state missing data integrity hash.The firewall signs the RelayState it sends to Entra and expects that signature back. Refreshing after the TLS error started a sign-in without the firewall's RelayState, so the firewall rejected the result. The refresh was a symptom; the TLS error was the real problem.
Finding the TLS interception
Opening the Microsoft sign-in page in Edge on the laptop and checking the certificate showed the cause. The certificate chain led to a root named after the laptop's own hostname, ending in "endpoint cert", not to a Microsoft or DigiCert root.
That pattern means local software is intercepting HTTPS by re-signing it with its own root certificate. Things we learned while tracking it down:
- Pausing the antivirus didn't help, because it wasn't the antivirus. The interceptor was the DLP agent, which generates a signing certificate for each endpoint. ESET's own certificate, for comparison, is named "ESET SSL Filter CA".
- The certificate's NotBefore date was useless, because interception products often backdate it.
- Check another laptop. If every managed laptop has the same pattern, it's your own software. If only one does, treat that laptop as potentially compromised: it can read Microsoft sign-ins in cleartext.
The fix: exclusions in the interception tool
SAML doesn't tolerate a man-in-the-middle, so the exclusions are required. In the DLP console's protection exclusions (website exclusions), we added:
vpn.example.com, login.microsoftonline.com, *.microsoftonline.com, login.live.com, *.msauth.net, *.msftauth.netAfter the policy synced and the client restarted, the certificate chain went back to Microsoft's and the VPN connected normally. If your interceptor is an antivirus or a secure web gateway agent, the equivalent setting is usually called SSL/TLS filtering exclusions.
Step 7: Add single sign-on and upgrade the client
Switching the SAML login to the user's default browser gives SSO, so users who are already signed in to Microsoft don't type their password again.
Enable SSO
- In the
VPN-SSOconnection profile, change the SAML Login Experience from the embedded browser to Default OS Browser. - In the SAML server object, untick Request IDP re-authentication at login. While it's ticked, Entra has to ask for the password every time.
- Deploy, then test with a fresh connection.
You probably don't need the separate external-sso-*.pkg package. It was only required by early AnyConnect 4.10 builds; current clients include the support. It's a 10 KB download, so keep it on hand in case FDM asks for it.
With per-user MFA, expect no password prompt but still an Authenticator prompt. The Windows token only satisfies MFA if the user signed in with Windows Hello for Business. For a firm that just survived a spray, keeping that tap is a reasonable trade-off. Running dsregcmd /status tells you whether laptops are hybrid-joined (AzureAdJoined: YES, AzureAdPrt: YES), which gives the most reliable SSO.
Upgrade AnyConnect 4.10 to Secure Client 5.1
AnyConnect 4.x is end of life. From the Secure Client 5 downloads, take:
Package | Use |
|---|---|
Headend Deployment Package (Windows), | Upload to FDM; clients upgrade from it |
Pre-Deployment Package (Windows), | Install the core VPN MSI on one test laptop first |
Profile Editor (Windows) | Edit client profile XML |
Skip the ARM64 packages unless you have ARM laptops, and skip the API and transforms packages.
In FDM, the client package is uploaded on the Global Settings page of the connection profile wizard. FDM holds one package per operating system, so the upload button stays greyed out until you remove the old Windows package with its X. Remove and upload in the same session, then deploy.
Clients upgrade themselves on their next connection, without local admin rights. Afterwards, update any application exclusions in your security tools: the install path changes to Cisco Secure Client, and the UI process is now csc_ui.exe.
Step 8: Close the old attack path
SAML only ends the lockouts once nothing else on the firewall still sends passwords to AD.
- Delete the LDAP-backed connection profile after all users have moved. As long as it exists, attackers keep spraying AD through it.
- Keep the default profiles as sinkholes.
DefaultWEBVPNGroupandDefaultRAGroupshould authenticate against something that can never succeed, such as an empty local database. FDM 7.6.4 and later fixed a bug that prevented changing these in FDM. - Turn off connection profile selection on the login page, and don't use aliases. Users reach the SAML profile only through its group URL in the client profile.
- Watch the counters. Run
show aaa-serverover the next day. The LDAP reject count should stop climbing. If it keeps rising, something still points at the LDAP server. - Enable RA VPN threat detection. It's available from 7.4.2.1 and 7.6.0, and it shuns IP addresses that repeatedly fail authentication or probe the default profiles. Check with
show threat-detection serviceandshow shun.
Housekeeping
- Send syslog to an external server or SIEM, so the next incident has a record.
- Switch any remaining LDAP use to LDAPS. Plain LDAP on 389 sends passwords to the domain controller unencrypted.
- Keep FDM management off the internet.
- Put certificate expiry dates in a calendar: the VPN certificate, the Entra SAML signing certificate (three years by default), and the FDM web certificate.
Lessons learned
Most of our time went into problems that a short checklist would have caught up front.
Symptom | Cause | Fix |
|---|---|---|
Random AD lockouts | Password spray through VPN, LDAP auth straight to a DC | SAML with Entra ID; delete the LDAP profile |
"Failed to generate SAML AuthnRequest" | FDM 7.2 rejects Entra's non-CA signing certificate | Upgrade to 7.3+ and use Skip CA Check |
SAML login URL missing the port | FDM builds the base URL from the outside-interface FQDN | Run VPN on 443 or include the port in the FQDN |
Upgrade fails at | Expired | Replace it before upgrading |
"Single local user" error | Second Windows session signed in | Sign off the extra session |
TLS error, then relay state 716164 | DLP agent intercepting HTTPS | Exclude VPN and Microsoft sign-in domains |
Pre-flight checklist
show aaa-serverconfirms whether the VPN is the lockout source- Confirm whether FTD is managed by FDM or FMC, and which version
- No expired certificates under Objects → Certificates
- FDM backup downloaded off the box
- Users registered for MFA before cutover
- Certificate issuer for
login.microsoftonline.comchecked on a managed laptop - New connection profile tested with one user before moving everyone
- Old LDAP profile deleted after cutover
Comments
Post a Comment