Course menu

Module 5: Users and VPNsLesson 5.2 (2 of 8 in this module)21 of 41 in the FortiGate Administration course

Remote LDAP and RADIUS servers

Connecting FortiGate to Active Directory over LDAP and to a RADIUS server, using their groups in policies, testing with diagnose test authserver, and the usual bind and group-matching faults.

Intermediate · 16 min read

Written for FortiOS 7.6 · FortiOS 7.4: not yet reviewed

Exam domain: NSE 4 (FortiOS 7.6) · Firewall policies and authentication

Before this: Users and firewall authentication

You'll learn to configure an LDAPS connection to Active Directory and a RADIUS server on a FortiGate, restrict user groups to specific remote groups, prove a login with diagnose test authserver, and work out from the result whether a fault is in the bind, the password, the group match or the network path.

A remote authentication server is a directory or AAA server that the FortiGate asks to check a user's credentials instead of storing the password itself. With LDAP, the FortiGate searches the directory (usually Active Directory) for the user, verifies the password and reads the user's group memberships. With RADIUS, it sends an Access-Request and the server answers Access-Accept or Access-Reject, optionally with a group name. A FortiGate user group then decides which of those remote users, or which remote groups, count as members.

Two hundred staff, one directory, one MFA server

Kestrel Logistics keeps its 200 user accounts in Active Directory on DC1 (10.0.1.5, domain corp.example.com). Finance staff must reach the finance server FIN-SRV (10.0.2.30) in the DMZ; everyone else must not. The network team already uses a Windows NPS server, NPS1 (10.0.1.7), as a RADIUS server with multi-factor authentication for its VPN, and wants the same server to decide who gets the NetOps access on FGT1. Creating 200 local users on FGT1 would mean a second set of passwords that nobody would keep up to date. Both servers already know the answer, so FGT1 should ask them.

The previous lesson showed where user groups fit into a policy. This one is about the server side: how the FortiGate talks to LDAP and RADIUS, how a remote group becomes a FortiGate group, and how to prove each step from the CLI.

Learn more: Users and Firewall Authentication

Active and passive: where these servers fit

FortiOS identifies users in two ways. Active authentication asks for credentials: the captive portal, an IPsec dial-up VPN with XAUTH or EAP, an explicit proxy login, an administrator login. LDAP and RADIUS servers answer those requests. Passive authentication learns who is on an IP address without asking, from Windows logons (FSSO) or from RADIUS accounting messages (RSSO). This lesson covers the servers used for active authentication; the same LDAP server object is reused by FSSO for group lookups, which is one more reason to get it right first.

What FGT1 does with a username and password

1. Service bind
FGT1 binds to DC1 as the service account fgt-ldap.
2. Search
It looks under the dn for an object whose sAMAccountName equals the typed name.
3. Password check
It binds again as the user's own DN with the typed password. Success means the password is right.
4. Groups
It reads the user's group memberships (memberOf by default).
5. Group match
FortiOS compares those groups with the user group's match list, then with the policy.
A regular-bind LDAP login, as FGT1 performs it for every active authentication.

The bind type controls the first two steps:

Bind typeWhat happensUse it when
Simple (CLI default)Binds as cnid=user,dn directly; no search below the dnAll users sit in one flat container
AnonymousSearches without credentialsThe directory allows anonymous search (AD normally doesn't)
RegularBinds with a service account, then searches the dn and its subtreesActive Directory, users spread across OUs

For Active Directory, regular is the practical choice. Users live in many OUs, and simple bind only finds those directly below the dn.

Building the LDAPS connection to DC1

Simplified illustration of the FortiOS 7.6 GUI · not a screenshot
FGT1User & Authentication › LDAP Servers

New LDAP Server

Name
KESTREL-AD
Server IP/Name
dc1.corp.example.comA name that appears in the server certificate, so the identity check can pass.
Server Port
636
Common Name Identifier
sAMAccountName
Distinguished Name
dc=corp,dc=example,dc=com
Bind Type
Simple Anonymous Regular
Username
fgt-ldap@corp.example.com
Password
••••••••
Secure Connection
On
Protocol
STARTTLS LDAPS
Certificate
KESTREL-ROOT-CAWithout a CA certificate selected, the server certificate is not validated.
Server identity check
On
config user ldap edit "KESTREL-AD" set server "dc1.corp.example.com" set cnid "sAMAccountName" set dn "dc=corp,dc=example,dc=com" set type regular set username "fgt-ldap@corp.example.com" set password <service-account-password> set secure ldaps set port 636 set ca-cert "KESTREL-ROOT-CA" set server-identity-check enable next end

The company's root CA certificate must first be imported (System › Certificates › Import › CA Certificate). The FortiGate must be able to resolve dc1.corp.example.com, so its DNS servers should include DC1.

SettingWhat it does here
cnidsAMAccountName lets users type alice; the attribute name is case sensitive
dnSearch from the domain root, so users in any OU are found
usernameUPN, DOMAIN\name or full DN formats are accepted
secure ldapsTLS from the first packet on port 636 (STARTTLS upgrades a port 389 connection instead)
ca-certAccept only a server certificate signed by this CA
server-identity-checkThe certificate's SAN (or CN, if there is no SAN) must match the server name or IP (default enable)

The bind account only needs to read users and groups. A standard domain user is enough in most AD environments; a Domain Admin account here is a gift to whoever later reads the FortiGate's configuration backup. In practice, LDAP logins that "suddenly stopped working" on a Monday are very often this account's password expiring, so give it a password policy of its own and a calendar reminder.

Users in nested groups

By default FortiOS reads only the groups a user is a direct member of. If FIN-Staff contains a group AP-Clerks and Bob is in AP-Clerks, Bob does not match a FortiGate group mapped to FIN-Staff. For Active Directory, set search-type recursive in the LDAP server entry follows the nesting. It costs extra searches, so enable it only if your AD design really nests groups.

Adding NPS1 as a RADIUS server

RADIUS (Remote Authentication Dial-In User Service, RFC 2865) works differently. FGT1 sends an Access-Request over UDP 1812 containing the username and the password, hidden with the shared secret. NPS1 checks its own policies (and here, the MFA step) and replies Access-Accept or Access-Reject. An Accept can carry attributes, such as the Fortinet-Group-Name vendor-specific attribute (VSA) that FortiOS uses for group matching.

config user radius edit "KESTREL-NPS" set server "10.0.1.7" set secret <shared-secret> set auth-type auto set nas-ip 10.0.1.1 next end

GUI: User & Authentication › RADIUS Servers. auth-type auto tries PAP, MSCHAPv2 and CHAP in that order; set a single method if the server only accepts one. nas-ip is optional: without it the FortiGate uses the address of the interface facing the server.

NPS1 must list FGT1 as a RADIUS client with the same shared secret and the source address it will see, here 10.0.1.1 (FGT1's port2). A request from an address the server doesn't know as a client is usually dropped without a reply, which on the FortiGate looks exactly like a server that is down.

The FortiGate waits five seconds by default for any remote server to answer (remoteauthtimeout under config system global, 1–300). An MFA push that the user approves on a phone usually takes longer, so RADIUS servers with push MFA normally need this raised, for example to 60.

FortiOS 7.6 · 7.4 not yet reviewed

Because of the Blast-RADIUS vulnerability (CVE-2024-3596), FortiOS 7.6 requires the Message-Authenticator attribute in RADIUS responses over UDP and TCP (require-message-authenticator, enabled by default). An unpatched RADIUS server that omits it will fail every login. Patch the server; disabling the check is a temporary workaround only. RADIUS over TLS (RadSec, set transport-protocol tls) is the stronger fix where the path is untrusted. This page has not yet been reviewed against FortiOS 7.4.

Turning remote groups into FortiGate groups

A FortiGate user group of type Firewall can hold local users, remote servers, or both. Adding a server without a group match is the trap: every valid account on that server becomes a member. For LDAP that means every enabled AD user. Add a match so only the intended directory group qualifies.

config user group edit "GRP-Finance" set member "KESTREL-AD" config match edit 1 set server-name "KESTREL-AD" set group-name "CN=FIN-Staff,OU=Groups,DC=corp,DC=example,DC=com" next end next edit "GRP-NetOps" set member "KESTREL-NPS" config match edit 1 set server-name "KESTREL-NPS" set group-name "NetOps" next end next end

GUI: User & Authentication › User Groups › Remote Groups › Add. For LDAP the GUI lets you browse the directory and pick the group; the stored name is its full DN. For RADIUS you type the value that NPS1 returns in Fortinet-Group-Name.

Group names are compared as text. For RADIUS, setting the group name to Any does not mean "any group": it matches a server that literally returns "Any". To go back to accepting every user on the server, delete the match entry. When a user tries to log in, local members are checked first, then the remote servers in the group.

config firewall policy edit 12 set name "Finance-to-FIN-SRV" set srcintf "port2" set dstintf "port3" set srcaddr "LAN-subnet" set dstaddr "FIN-SRV" set groups "GRP-Finance" set service "HTTPS" set action accept next end

Schedule, logging and profiles as in any other policy. The group decides who; the address still decides from where.

Proving a login from the CLI

Before touching a policy, test the server with a real test account. The first argument is the name of the FortiGate's server object, not the server's hostname:

Example output · based on Fortinet documentation; exact format varies by model and FortiOS version
FGT1 # diagnose test authserver ldap KESTREL-AD alice <password>
authenticate 'alice' against 'KESTREL-AD' succeeded!
Group membership(s) - CN=FIN-Staff,OU=Groups,DC=corp,DC=example,DC=com
                      CN=Domain Users,CN=Users,DC=corp,DC=example,DC=com
Illustrative output. "succeeded" proves the bind, the search and the password. The group list is what FortiOS will compare with the match list, so copy the DN from here rather than typing it.
Example output · based on Fortinet documentation; exact format varies by model and FortiOS version
FGT1 # diagnose test authserver radius KESTREL-NPS pap dana <password>
authenticate 'dana' against 'pap' succeeded, server=primary ...
Group membership(s) - NetOps
Illustrative output, trimmed. The method (pap, chap, mschap or mschap2) must be one NPS1 accepts. A "no response" failure points at the network path, the client entry on the server or the secret; a reject with a reply points at the user, the password or the server's policy.

The GUI has the same tests: Test Connectivity and Test User Credentials on the LDAP server page. For more detail, the authentication daemon fnbamd can print every step:

Debug output and passwords

The test command puts a password in the CLI history and the debug can print usernames and directory data. Use a dedicated test account, run the debug only while reproducing the problem, and stop it with diagnose debug disable and diagnose debug reset.

diagnose debug reset diagnose debug console timestamp enable diagnose debug application fnbamd -1 diagnose debug enable diagnose test authserver ldap KESTREL-AD alice <password> diagnose debug disable diagnose debug reset

Read it in order: connection and TLS to the server, the service bind, the search result, the user bind, then the groups and the match. The first step that fails is the fault.

To watch the result in production, open Dashboard › Assets & Identities and expand the Firewall Users widget. It lists each authenticated user, the IP address, the method and the groups, and lets you deauthenticate one user. The CLI equivalent is diagnose firewall auth list.

diagnose firewall auth clear logs everyone out

Without a filter it removes every authenticated user on the VDOM, and every portal user must log in again. Set diagnose firewall auth filter first, or deauthenticate the single user in the GUI.

Five ways LDAP and RADIUS logins fail

Every LDAP test fails, even for known-good accounts

The service bind is failing, so nothing after it runs. The fnbamd debug shows the bind rejected (in Active Directory, result 49 with data 52e means invalid credentials, data 532 an expired password).

Show the fix

Check the bind account: password, expiry, lockout and the username format. Re-enter the password in the LDAP server entry (it is stored encrypted, so a pasted show output can't be compared). Then rerun the test.

LDAPS fails after the domain controller's certificate was renewed

Plain LDAP to the same server works; LDAPS doesn't. Either the new certificate is signed by a different CA than the one selected, or it no longer contains the name (or IP address) in Server IP/Name.

Show the fix

Import the issuing root CA and select it, and point the server field at a name that appears in the certificate's SAN. Using an IP address works only if that IP address is in the certificate. Turning off the identity check makes the connection work but stops the FortiGate from knowing it is talking to the real DC.

The test succeeds, but the user is not in the group

The group DN in the match differs from what the test returns, or the user is in a nested group.

Show the fix

Compare the match's group-name with the "Group membership(s)" line, character for character. If the user's group is inside the matched one, enable search-type recursive or match the inner group too.

RADIUS: "no response" from a server that is clearly running

NPS1 doesn't answer FGT1. Common causes: FGT1 isn't a client on NPS1, the request leaves from a different interface (after a routing or SD-WAN change) so the source IP isn't the registered one, or a firewall in between blocks UDP 1812.

Show the fix

Sniff the exchange with diagnose sniffer packet any 'host 10.0.1.7 and port 1812' 4. Requests with no replies point at the server side: check the NPS event log for a discarded request from an unknown client. Fix the client entry or pin the source with source-ip (or nas-ip) on the RADIUS server object.

Anyone with an AD account reaches FIN-SRV

GRP-Finance contains the KESTREL-AD server with no match entries, so every valid directory account is a member. Nothing errors, which is why this one survives until an audit.

Show the fix

Add the FIN-Staff group match, then deauthenticate current users so they are checked again. Review every user group with show user group: a remote member with no config match block is the pattern to look for.

Designing remote authentication that survives a bad day

  • Give each server a backup: secondary-server for LDAP and RADIUS (a third RADIUS server is possible in the CLI), pointing at a second DC or NPS server.
  • Use LDAPS with a selected CA and the identity check enabled, or RadSec, whenever the traffic crosses a network you don't fully trust.
  • Match specific remote groups in every user group, and name FortiGate groups after what they allow (GRP-Finance), not after the server.
  • Keep a local emergency administrator; if both DCs are unreachable, remote logins fail with them.
  • Raise remoteauthtimeout only as far as MFA needs; a long timeout also makes a dead server feel slow.

Try it: connect a lab FortiGate to a test directory

In a lab with a Windows Server domain controller, create a bind account, a group LAB-Finance with one test user, and a nested group inside it with a second user. Configure an LDAPS server entry on the FortiGate, then run diagnose test authserver ldap for both users and note the group lists. Create a user group matching LAB-Finance and see which user the policy accepts; then enable search-type recursive and test again. Finally, change the server field to the DC's IP address and explain the LDAPS result.

The four checks, in order
  • Connection: can the FortiGate reach the server, and does TLS validate?
  • Credentials: does diagnose test authserver succeed for a test user?
  • Group: does the returned group list contain the matched group exactly?
  • Policy: does the group sit in the policy that actually matches the traffic?

Test yourself on LDAP and RADIUS

Predict · scenario 1

GRP-Staff has KESTREL-AD as a remote member and no group match. Who can authenticate as a member of GRP-Staff?

Predict · scenario 2

diagnose test authserver ldap KESTREL-AD bob <pw> succeeds and lists CN=AP-Clerks,... only. GRP-Finance matches CN=FIN-Staff, which contains AP-Clerks. What fixes Bob's access?

Predict · scenario 3

LDAPS to 10.0.1.5 fails with server-identity-check enabled. The DC certificate's SAN lists only dc1.corp.example.com. What is the cleanest fix?

Predict · scenario 4

diagnose test authserver radius KESTREL-NPS pap dana <pw> reports no response. A sniffer shows requests leaving port2 and nothing coming back. Where do you look next?

Predict · scenario 5

After a NPS update, every RADIUS login fails on FortiOS 7.6, while the server logs show Access-Accept being sent. Which setting is involved?

Further reading in Fortinet's documentation

Links open the named page in Fortinet's documentation (checked 12 October 2026). RouteLearn is an independent educational resource, not affiliated with or endorsed by Fortinet. Fortinet, FortiGate, FortiOS, FortiManager and FortiGuard are trademarks of Fortinet, Inc. Example output on this page is illustrative.

FAQ

Should a FortiGate use LDAP or RADIUS for Active Directory users?
Either works. LDAP talks to the domain controllers directly and returns every group the user is in, which makes group matching easy. RADIUS goes through a server such as Windows NPS or FortiAuthenticator, which can add multi-factor authentication and its own access rules but only returns the group names it is configured to send. Many companies use LDAPS for firewall and VPN groups and RADIUS where an MFA server is already in place.
Does the FortiGate copy the directory's users?
No. It queries the server each time a user authenticates and keeps only the result (user, IP address, groups) for the authentication timeout. A new employee added to the right AD group can log in at once, and a disabled account fails at the next login.
Why does the test command work but users still can't log in?
diagnose test authserver only proves the server connection and the credentials. The login can still fail at the user group (the remote group isn't matched), at the policy (the group isn't in the policy, or a policy above matches first) or at the client side (DNS before the portal). Check those in that order.