Intro
Decide whether to use Wildcard user on FAZ/FMG/FGT or only specific users.
RADIUS Configuration – Windows NPS
Install Network Policy Role (NPS)
Open NPS management console
Integrate NPS with local Active Directory
Create in NPS console RADIUS clients signifying each network device (FGT, FAZ, FMG)
Create Connection Request Policy for each client
Create Network Policy for each RADIUS client matching on AD Groups membership for end users
Create a RADIUS user to represent the RADIUS server
Create a user group to include this RADIUS user
Create (here) a wildcard admin account and assign RADIUS-containing user group
Fortigate
FortiAnalyzer
FortiManager
Fortigate
FortiManager
Fortianalyzer
Fortianalyzer with overriding not only accprofile but ADOM of the user as well
FAZ Debug (dia deb app auth -1)
Specific (not wildcard) user with access profile assigned on Fortinet device
Specific (not wildcard) user with access profile assigned by FGT AND Group Matching on Fortigate side
Intro
Removing locally stored passwords from the Fortinet devices is a good step in securing the admin access. While you have to keep at least one local admin-level user for disaster recovery scenarios, the day-to-day changes are best being done by admins authenticated remotely via LDAP/TACACS+/LDAP. In this post I wll show how to do it in FGT/FAZ/FMG against RADIUS server. The RADIUS server will be Windows Server 2019 NPS.
Decide whether to use Wildcard user on FAZ/FMG/FGT or only specific users.
Fortinet created a special setting in the administrator users config – Wildcard user authentication, which in GUI is usually called Match all users on remote server.
When you choose the Wildcard user it means Fortinet device is NOT aware of any usernames at all, all users and their passwords are stored on the remote RADIUS server. And if the RADIUS server authenticates any user successfully, FGT/FAZ/FMG will be happy as well and will assign the access profile set for the Wildcard User, or the one sent by RADIUS.
The advantage of the Wildcard User is that we do not need to manage users on the device – disabling/removing/adding – all is being done on RADIUS server. The disadvantage is that if RADIUS server admin makes a mistake and does not restrict what users can authenticate against this FGT/FMG/FA device, ANY valid user on RADIUS server may potentially log in as admin-level user.
The alternative is to use/create specific admin-level users of type RADIUS, that will still check password and autheticate against RADIUS.
When there are multiple Wildcard Users configured on the same Fortinet device – the first in the table from top to the bottom match wins. If there are both – specific/individual and Wildcard users present – the specific users always match first, and only after that the Wildcard is tried.
Additionally, we have to decide whether to enable profile override – when this option is enabled, the profile sent for a user from the RADIUS server overrides the profile set at the Fortinet device. This way we can assign different access profiles to different users, which is desirable.
RADIUS Configuration – Windows NPS
The intial RADIUS configs done on the NPS are the same for all Fortinet devices: Fortigate, FortiManager, and FortiAnalyzer.
Install Network Policy Role (NPS)
Open NPS management console
Integrate NPS with local Active Directory
if it is a 1st configuration of NPS, make sure to integrate it with Active Directory (if NPS is installed on DC).
Create in NPS console RADIUS clients signifying each network device (FGT, FAZ, FMG)
Next, we create RADIUS clients for each Fortinet device that needs to authenticate against this NPS using their IPs and setting shared secret.
Fortigate (10.100.104.13):
FAZ (10.100.104.17):
FMG (10.100.104.252):
Create Connection Request Policy for each client
Next, is the Connection Policy. I will be matching on RADIUS Client IPs (i.e. the same IPs I used in RADIUS client creation above) as condition:
FGT
After that just click on Next, as Group membership for users on AD we will specify in Network Policy in the next step, not in the Connection Request Policy.
We create the same Connection Request Policies for FMG and FAZ, and they differ only by RADIUS Client IP.
Create Network Policy for each RADIUS client matching on AD Groups membership for end users
In this AD topology, I created 4 AD users adminad1,…admiad4, then created a new AD Group named AllFGTAdmins and added all 4 users to it. We will next match RADIUS Network Policy on this AD Group, i.e. only members of this AD group will be able to authenticate according to NPS Network Policy. This way we prevent the mistake of allowing ANY valid AD user to authenticate against our Fortinet devices. In later examples of assigning Access Profiles from RADIUS, I will add new Groups and make them more granular.
Here I set as condition in the Network Policy matching on the AD group membership and select just AllFGTAdmins group:
Windows 2019 only – there is a bug in this version of Windows that even though it has default Allow rule for incoming RADIUS requests enabled, the Windows Firewall still blocks incoming RADIUS requests from all. The workaround is either to disable Windows Firewall on Server 2019, or create a Custom Inbound Rule for the same ports UDP 1812 (RADIUS) and 1813 (ACCOUNTING). In the screenshot below I created a custom Inbound Rule:
Message Authenticator problem – starting with FortiOS 7.2.10, 7.4.5 and 7.6.1 Fortinet hardened their RADIUS handling in the Fortigates to mitigate Blast RADIUS vulnerability (CVE-2024-3596). What was optional (Message-Authenticator attribute) in the RADIUS communication, Fortinet made obligatory, but Server 2019 NPS does NOT have it enabled by default and thus any RADIUS authentication attempt will be dropped by the Fortigate.
Running dia deb app fnbamd -1, dia deb en will show the following error:
_rad_chk_resp_authenticator-The Message Authenticator validation is mandatory now
_rad_chk_resp_authenticator-No Message Authenticator
nbamd_rad_validate_pkt-Invalid digest
rad_rxtx-Error validating radius rsp
And if we do packet capture on the Fortigate, we will see that Fortigate does include this Message Authenticator RADIUS attribute, but the response from NPS does not, and as a result – Fortigate drops successfully authenticated user connection.
To fix this, enable the following option in NPS Console:
If your Server 2019 is not regularly updated, enabling this option will be not enough – you have to have security patches from Microsoft installed as well, see https://support.microsoft.com/en-us/topic/july-9-2024-kb5040430-os-build-17763-6054-0bb10c24-db8c-47eb-8fa9-9ebc06afa4e7
Fortigate configuration
Create a RADIUS user to represent the RADIUS server
edit “RAD1”
set server “10.100.104.184”
set secret ENC xl1PiA
set auth-type ms_chap_v2 // Optional – just make sure the same config on NPS
next
end
Create a user group to include this RADIUS user
edit “RAdminGroup”
set member “RAD1”
next
end
Create (here) a wildcard admin account and assign RADIUS-containing user group
edit “RAdmins”
set remote-auth enable
set accprofile “super_admin”
set vdom “root”
set password FLDm,bnK>JHDF // To use if RADIUS server is down
set wildcard enable
set remote-group “RAdminGroup”
next
end
Wildcard User with dummy accprofile assigned on Fortinet device with override enabled to get actual profile name from the RADIUS
We use Vendor Specifc Attirbute (VSA) of 12356 for the Fortinet as vendor, and the attribute 6 Fortinet-Access-Profile which is a string to list accprofile existing on the Fortinet device (you cannot create accprofile on RADIUS, just send its name). See in the References link to all VSA attributes of Fortinet.
Fortigate
To allow the Access Profile to be overriden, we enable this option on admin user (option exists for regular admin users as well as Wildcard users). Also, as a best practice, we create an empty access profile and assign it to this Wildcard user instead of the “super_admin” I assigned above:
edit “noaccess”
next
end
edit “RAdmins”
set remote-auth enable
set accprofile “noaccess”
set vdom “root”
set wildcard enable
set remote-group “RAdminGroup”
set accprofile-override enable <– ENABLE OVERRIDE
next
end
User Group containing the RADIUS object:
edit “RAdminGroup”
set member “RAD1”
next
end
Now let’s set VSA 6 on NPS to the accprofile name of super_admin:
And trying successfully to log in with user adminad4 I get the correct super_admin profile from the RADIUS server sent VSA Attribute 6:
[912] __rad_rxtx-
[1286] fnbamd_rad_process-Result from radius svr ‘RAD1’ is 0, req 11553634668545
[545] fnbamd_rad_get_vsas-FORTINET attr, type 6, val super_admin
Debug (dia deb fnbamd -1)
Before doing any debug we have to understand what messages RADIUS exchanges, what they mean and such as debug lists numeric codes only.
Most popular RADIUS request/response messages/codes as per RFC:
Code
Description
1
Access-Request, sent by RADIUS client to the server to authenticate a user.
2
Access-Accept, response from RADIUS server when authenticaiton is successful.
3
Access-Reject, response from RADIUS server when auth has failed.
4
Accounting-Request, request from client to server to start Accounting.
5
Accounting-Response, response to ACK the accounting request
11
Access-Challenge, sent by server to request additional info – usually MFA.
40
Disconnect-Request, sent by the RADIUS server to the client in order to terminate a user session, more relevant to switches/WiFi and IEEE 802.1X.
41
Disconnect-Response, ACK by the RADIUS client to the server.
43
Change-of-Authorization Request (CoA), sent by RADIUS to the client, and contain information for dynamically changing session authorizations.
44
CoA-Response.
Debug output of successful login with user adminad1 with Wildcard admin user:
opt=00014001 prot=9 svc=6
[333] __compose_group_list_from_req-Group ‘RAdminGroup’, type 1 <– FOUND USER
GROUP WITH RADIUS
[508] create_auth_session-Session created for req id 10020305883137
Next FGT is counting all other remote servers configured (none in this case) until reaches RAD1 RADIUS server
10.100.104.184 using MS-CHAP2 (configured, not default) and authenticates against it:
[425] __fnbamd_cfg_get_tac_plus_list_by_admin-
[606] fnbamd_cfg_get_tac_plus_list-Total tac+ servers to try: 0
[840] fnbamd_cfg_get_ldap_list-
[613] __fnbamd_cfg_get_ldap_list_by_admin-
[856] fnbamd_cfg_get_ldap_list-Total LDAP servers to try: 0
[416] ldap_start-Didn’t find ldap servers
[316] radius_start-eap_local=0
[896] fnbamd_cfg_get_radius_list-
[675] __fnbamd_cfg_get_radius_list_by_admin-
[456] fnbamd_rad_get-vfid=0, name=’RAD1′
[805] __rad_auth_ctx_insert-Loaded RADIUS server ‘RAD1’
[663] __add_admin_rad_svr-Loaded RADIUS server ‘RAD1’ for admin user ‘RAdmins’
[818] __rad_auth_ctx_insert_all_usergroup-
[918] fnbamd_cfg_get_radius_list-Total rad servers to try: 1
[1025] fnbamd_cfg_radius_clear_reachability-Clearing RAD
server reachability RAD1:10.100.104.184
[936] fnbamd_rad_get_auth_server-
[1172] fnbamd_rad_auth_ctx_init-User ha_relay? 0.
[295] fnbamd_radius_get_next_auth_prot-Next auth prot MS-CHAPv2
[1107] __auth_ctx_svr_push-Added addr 10.100.104.184:1812 from rad ‘RAD1’
[930] __fnbamd_rad_get_next_addr-Next available address
of rad ‘RAD1’: 10.100.104.184:1812.
[1125] __auth_ctx_start-Connection starts RAD1:10.100.104.184,
addr 10.100.104.184:1812 proto: UDP
[280] __rad_udp_open-Opened radius socket 10, sa_family 2
[945] __rad_conn_start-Socket 10 is created for rad ‘RAD1’.
[807] __rad_add_job_timer-
[439] fnbamd_cfg_get_pop3_list-
[417] __fnbamd_cfg_get_pop3_list_by_group-
[422] __fnbamd_cfg_get_pop3_list_by_group-Group ‘RAdminGroup’
[449] fnbamd_cfg_get_pop3_list-Total pop3 servers to try: 0
[434] start_remote_auth-Total 1 server(s) to try
[1900] handle_req-r=4
[828] __rad_rxtx-fd 10, state 1(Auth)
[830] __rad_rxtx-Stop rad conn timer.
[837] __rad_rxtx-
[605] fnbamd_rad_make_access_request-
Composes Access-Request (code 1) message to the RADIUS server, using default
(not set to custom) source IP, UDP , to the default port 1812:
[588] __create_access_request-Created RADIUS Access-Request. Len: 215.
[1171] fnbamd_socket_update_interface-vfid is 0, intf mode is 0, intf name is ,
server address is 10.100.104.184:1812, source address is null,
protocol number is 17, oif id is 0
[353] __rad_udp_send-oif=0, intf_sel.mode=0, intf_sel.name=
[868] __rad_rxtx-Sent radius req to server ‘RAD1’: fd=10,
IP=10.100.104.184(10.100.104.184:1812) code=1 id=3 len=215
[877] __rad_rxtx-Start rad conn timer.
[828] __rad_rxtx-fd 10, state 1(Auth)
[830] __rad_rxtx-Stop rad conn timer.
[880] __rad_rxtx-
[431] __rad_udp_recv-Recved 268 bytes. Buf sz 8192
Adds attribute Message Autenticator:
[1148] __rad_chk_resp_authenticator-ret=0
RADIUS server response is success: code 2 (ACCESS-ACCEPT):
[912] __rad_rxtx-
Next is the FNBAMD daemon final result (see table below for values, 0 = success)
[868] fnbamd_radius_parse_mschapv2_attr-Decoding TYPE_MS_MPPE_Recv_Key
[791] __radius_decode_mppe_key-Key len after decode 16
[879] fnbamd_radius_parse_mschapv2_attr-Decoding TYPE_MS_MPPE_Send_Key
[791] __radius_decode_mppe_key-Key len after decode 16
[1485] fnbamd_rad_process-Challenged: 0, FTK_Challenge: 0, CHG_PWD: 0,
Invaid_Digest: 0, State_Len: 0
[627] fnbam_user_auth_group_match-req id: 10020305883137, server: RAD1,
local auth: 0, dn match: 0
[206] find_matched_usr_grps-Passed group matching
[909] update_auth_token_session-config does not require 2fa
[239] fnbamd_comm_send_result-Sending result 0 (nid 0) for req 10020305883137, len=2641
[600] destroy_auth_session-delete session 10020305883137
[1347] fnbamd_rads_destroy-
[516] fnbamd_rad_auth_ctx_free-Freeing ‘RAD1’ ctx
FNBAMD authentication daemon response codes in the debug:
Code
Description
0
Success
1
Deny
2
Challenged (password renewal or token is needed)
3
unknown
4
Pending
5
Error
6
Framed IP Conflict
7
Token code is required
8
Need another token due to the previous one is out of sync
9
Response Buffer is too small
10
Authentication time out
11
Max Concurrent authentication sessions are reached
12
Token code is already used.
Debug of failed authentication
Here I am using the user adminad5 which exists in AD, and password is correct BUT he is not part of the FGTAllAdmins
AD group on the RADIUS server. And therefore, will not match the Network Policy of the RADIUS NPS on Server 2019 and thus NPS will reject it.
Intial process is the same as the above example of successful authentication, up to getting aresponse from the RADIUS:
opt=00014001 prot=9 svc=6
[333] __compose_group_list_from_req-Group ‘RAdminGroup’, type 1
[508] create_auth_session-Session created for req id 10269421789186
[590] fnbamd_cfg_get_tac_plus_list-
[425] __fnbamd_cfg_get_tac_plus_list_by_admin-
[606] fnbamd_cfg_get_tac_plus_list-Total tac+ servers to try: 0
[840] fnbamd_cfg_get_ldap_list-
[613] __fnbamd_cfg_get_ldap_list_by_admin-
[856] fnbamd_cfg_get_ldap_list-Total LDAP servers to try: 0
[416] ldap_start-Didn’t find ldap servers
[316] radius_start-eap_local=0
[896] fnbamd_cfg_get_radius_list-
[675] __fnbamd_cfg_get_radius_list_by_admin-
[456] fnbamd_rad_get-vfid=0, name=’RAD1′
[805] __rad_auth_ctx_insert-Loaded RADIUS server ‘RAD1’
[663] __add_admin_rad_svr-Loaded RADIUS server ‘RAD1’ for admin user ‘RAdmins’
[818] __rad_auth_ctx_insert_all_usergroup-
[918] fnbamd_cfg_get_radius_list-Total rad servers to try: 1
[936] fnbamd_rad_get_auth_server-
[1172] fnbamd_rad_auth_ctx_init-User ha_relay? 0.
[295] fnbamd_radius_get_next_auth_prot-Next auth prot MS-CHAPv2
[1107] __auth_ctx_svr_push-Added addr 10.100.104.184:1812 from rad ‘RAD1’
[930] __fnbamd_rad_get_next_addr-Next available address of
rad ‘RAD1’: 10.100.104.184:1812.
[1125] __auth_ctx_start-Connection starts RAD1:10.100.104.184,
addr 10.100.104.184:1812 proto: UDP
[280] __rad_udp_open-Opened radius socket 10, sa_family 2
[945] __rad_conn_start-Socket 10 is created for rad ‘RAD1’.
[807] __rad_add_job_timer-
[439] fnbamd_cfg_get_pop3_list-
[417] __fnbamd_cfg_get_pop3_list_by_group-
[422] __fnbamd_cfg_get_pop3_list_by_group-Group ‘RAdminGroup’
[449] fnbamd_cfg_get_pop3_list-Total pop3 servers to try: 0
[434] start_remote_auth-Total 1 server(s) to try
[1900] handle_req-r=4
[828] __rad_rxtx-fd 10, state 1(Auth)
[830] __rad_rxtx-Stop rad conn timer.
[837] __rad_rxtx-
[605] fnbamd_rad_make_access_request-
[328] __create_access_request-Compose RADIUS request
[588] __create_access_request-Created RADIUS Access-Request. Len: 215.
[1171] fnbamd_socket_update_interface-vfid is 0, intf mode is 0, intf name is ,
server address is 10.100.104.184:1812, source address is null,
protocol number is 17, oif id is 0
[353] __rad_udp_send-oif=0, intf_sel.mode=0, intf_sel.name=
[868] __rad_rxtx-Sent radius req to server ‘RAD1’: fd=10,
IP=10.100.104.184(10.100.104.184:1812) code=1 id=5 len=215
[877] __rad_rxtx-Start rad conn timer.
[828] __rad_rxtx-fd 10, state 1(Auth)
[830] __rad_rxtx-Stop rad conn timer.
[880] __rad_rxtx-
[431] __rad_udp_recv-Recved 60 bytes. Buf sz 8192
[1125] __rad_chk_resp_authenticator-The Message Authenticator validation is mandatory now
[1148] __rad_chk_resp_authenticator-ret=0
What differs is the RADIUS server response – here it is 3 (ACCESS-REJECT), also FNBAMD daemon final result is
1 (DENY):
[624] fnbamd_rad_extract_chap_error-CHAP err: E=649 R=0 V=3
[1028] __rad_error-Ret 1, st = 1.
[295] fnbamd_radius_get_next_auth_prot-Next auth prot ??
[1077] __rad_error-
[306] __rad_udp_close-closed.
[964] __rad_conn_stop-Stop rad conn timer.
[1286] fnbamd_rad_process-Result from radius svr ‘RAD1’ is 1, req 10269421789186
FortiAnalyzer
Create RADIUS user to set parameters for communication with the RADIUS server:
edit “RAD-184”
set server “10.100.104.184”
set secret ENC NTEwNjAxNDMzN
set auth-type mschap2
next
end
Create a Wildcard admin-level user, set profile to built-in profile w/o actual permissions, set ADOM to “all”, to be later overridden by the RADIUS server response (as a best practice option you could create a new ADOM w/o any devices in it and use this ADOM as default log-in ADOM):
edit “RAwildcard”
set profileid “No_Permission_User”<– BUILT-IN PROFILE
set adom-access all
set user_type radius
set radius_server “RAD-184”
config meta-data
edit “Contact Email”
next
edit “Contact Phone”
next
end
set wildcard enable
set ext-auth-accprofile-override enable
set ext-auth-adom-override enable
next
end
FortiManager
The config in FMG is pretty much identical to the FAZ, so I will only show this example.
Create RADIUS server
edit “RAD1”
set server “10.100.104.184”
set secret ENC MTUxMTg4NTA
set auth-type mschap2
next
end
Or in GUI System Settings → Remote Authentication:
Create Wildcard user
edit “RAWildcard”
set profileid “No_Permission_User”
set adom-access all
set policy-package “all_policy_packages”
set policy-block “all_policy_blocks”
set user_type radius
set radius_server “RAD1”
config meta-data
edit “Contact Email”
next
edit “Contact Phone”
next
end
set wildcard enable
set ext-auth-accprofile-override enable
set ext-auth-adom-override enable
next
end
And the same drill – create NPS Policy on RADIUS server to send FMG at least VSA Attribute 6 – name of the access profile, and possibly VSA Attribute 3 – ADOM name.
Debug on FMG dia deb app auth 8
send request: type=mschap2 id=35
got reply: code=accept(2) id=35
Message-Authenticator: len=16
Ftnt-Profile: Super_User
Ftnt-Adom: root
0-7: len=4
0-6: len=4
0-25: len=44
311-17: len=34
311-16: len=34
311-26: pS=EB01A13608E95CC4F996F80FD2CE58D3665C1DAB
311-10: pARGO
success
success
Additional logs on authentication failure can be found in System Settings → Event Logs, but they are not very detailed.
Here is example of successful and failed logins:
Wildcard user with accprofile override enabled and 2 user groups on NPS, one to assign super_admin profile, 2nd – readonly profile
As the decision what accprofile to assign to a user based on user’s group membership in AD is done totally on the NPS side, all configs are being done on NPS side. The Fortinet device side uses the regular Wildcard user with accprofile override enabled.
Fortigate
NPS configs. Here I create 2 Network Policies – FGT-readonly and FGT-superadmin. The 1st will assign any user in the AD Group FGTreadonly the accprofile (via VSA Attribute) “readonly” located on the Fortigate already. Users in the AD group FGTsuperadmin, after authentication will get profile “super_admin”. To the FGTreadonly group I added only adminad5 user, and to the FGTsuperadmin AD Group adminad4, adminad3 etc.
NPS, FGT-readonly policy:
NPS, FGT-superadmin policy:
FortiManager
For this and the next example I will only show Fortianalyzer configs as in both cases the configuration is the same for both FAZ & FMG.
Fortianalyzer
The NPS side is the same as for FGT – create 2 new Network Policies with Conditions of RADIUS Client IP (FAZ) and user group membership, sending for each policy different accprofile name via VSA Attribute 6 – “readonly” and “Super_User” (there is no “super_admin” profile in FAZ unless you create a custom one with that name).
readonly Network Policy of NPS for FAZ:
super_user Network Policy of NPS:
Fortianalyzer with overriding not only accprofile but ADOM of the user as well
Fortinet have additional helpful VSA Attribute – 3 Fortinet-Vdom-Name which when sent from RADIUS can be used by Fortigate/FAZ/FMG/etc to override the default VDOM/ADOM the user can access.
NPS: For this I created a new AD Group “FAZ-syslogadom” that contains only adminad8 user. I create then new Network Policy to match FAZ IP and this AD Group. And finally, I set not only VSA Attribute 6 – accprofile, but also VSA Attribute 3 – ADOM name to “Syslog” to be sent by RADIUS server.
As I want to assign this user write/read full rights BUT to the specific ADOM he has been assigned to, I have to create a new accprofile where “ADOM” settings is “Read only”, so this user cannot change to a different ADOM after log in. If I were to assign it the built-in “Super_User” profile, this would allow the user to change to another ADOM freely.
Here is the accprofile I created:
And on CLI:
edit “ADOMSuper_User”
set system-setting read-write
set adom-switch read
set device-manager read-write
set device-op read-write
set device-wan-link-load-balance read-write
set device-ap read-write
set device-fortiswitch read-write
set device-fortiextender read-write
set adom-lock read-write
set device-policy-package-lock read-write
set extension-access read-write
set log-viewer read-write
set fabric-viewer read-write
set report-viewer read-write
set event-management read-write
set update-incidents read-write
set triage-events read-write
set run-report read-write
set execute-playbook read-write
set script-access read-write
set fgt-gui-proxy disable
set ips-lock none
next
end
FAZ Debug (dia deb app auth -1)
Case 1: Debug of successful authentication with the user adminad7 getting “readonly” profile with access to all ADOMs:
FAZ-AWS # dia deb enab
FAZ-AWS #
s9: auth request: user=adminad7 from=GUI(10.100.104.13)
s9: wildcard admin: RAwildcard
s9: start radius: RAD-184
s9:RAD-184: connect to server 0: 10.100.104.184 ip=10.100.104.184 port=1812
s9:RAD-184: send request: type=mschap2 id=6
s9:RAD-184: got reply: code=accept(2) id=6
s9:RAD-184: 0-80: jZ9:RAD-184: ftnt-profile: readonly
s9:RAD-184: 0-7: len=4
s9:RAD-184: 0-6: len=4
s9:RAD-184: 0-25: len=44
s9:RAD-184: 311-17: len=34
s9:RAD-184: 311-16: len=34
s9:RAD-184: 311-26: 7S=55F620A3763E7D99149FFBCC96AEDF195E6C862E
s9:RAD-184: 311-10: 7ARGO
s9:RAD-184: success
s9: profile from server: readonly
s9: wildcard admin matched: RAwildcard
s9: profile-override: readonly
s9: no adom from server, use adoms in admin setting
s9: auth result: success
Case 2: Here I mis-spelled access profile name “super_user” instead of “Super_User” and got an error that such profile does not exist on FAZ and user log in was rejected:
s11: wildcard admin: RAwildcard
s11: start radius: RAD-184
s11:RAD-184: connect to server 0: 10.100.104.184 ip=10.100.104.184 port=1812
s11:RAD-184: send request: type=mschap2 id=8
s11:RAD-184: got reply: code=accept(2) id=8
s11:RAD-184: 0-80: len=16
s11:RAD-184: ftnt-profile: super_user
s11:RAD-184: 0-7: len=4
s11:RAD-184: 0-6: len=4
s11:RAD-184: 0-25: len=44
s11:RAD-184: 311-17: len=34
s11:RAD-184: 311-16: len=34
s11:RAD-184: 311-26: 689AEA94593EF06B7659C41254F31B68A85D628
s11:RAD-184: 311-10: O
s11:RAD-184: success
s11: profile from server: super_user (invalid)
s11: wildcard admin matched: RAwildcard
s11: no valid profile from server
s11: auth result: denied
Case 3: Debug of successful log in of adminad8 getting accprofile ADOMSuper_User and being forced to the ADOM “Syslog”:
s15: wildcard admin: RAwildcard
s15: start radius: RAD-184
s15:RAD-184: connect to server 0: 10.100.104.184 ip=10.100.104.184 port=1812
s15:RAD-184: send request: type=mschap2 id=12
s15:RAD-184: got reply: code=accept(2) id=12
s15:RAD-184: 0-80: len=16
s15:RAD-184: ftnt-adom: Syslog
s15:RAD-184: ftnt-profile: ADOMSuper_User
s15:RAD-184: 0-7: len=4
s15:RAD-184: 0-6: len=4
s15:RAD-184: 0-25: len=44
s15:RAD-184: 311-17: len=34
s15:RAD-184: 311-16: len=34
s15:RAD-184: 311-26: 12AC271969CF7E420358CD1B621D7022BAA5352
s15:RAD-184: 311-10: O
s15:RAD-184: success
s15: profile from server: ADOMSuper_User
s15: wildcard admin matched: RAwildcard
s15: profile-override: ADOMSuper_User
s15: adom-override: Syslog
s15: auth result: success
Specific (not wildcard) user with access profile assigned on Fortinet device
When creating individual users on Fortinet device it is logical to assign them the needed access profile as well.
I create a new Network Policy on Server 2019 here to all ALL Domain Users to be able to authenticate to simplify the case (the Group matching on NPS would work as well).
And I disabled the NPS policy matching on AllFGTAdmins group in AD (moving it down would still leave it active and match on it).
Next, I remove the Wildcard admin account on Fortigate to prevent the case of ANY Domain User connecting as admin (the new user would NOT use this Wildcard anyway, but for security sake). The alternative would be to create NPS Policy for a specific AD Group of which this user is member of:
del RAdmins
And create a new admin user adminad5 to be authenticated against NPS:
edit “adminad5”
set remote-auth enable
set accprofile “super_admin”
set vdom “root”
set remote-group “RAdminGroup”
set password ENC SH2cnkEXtY
next
end
Verifying on CLI:
authenticate ‘adminad5’ against ‘mschap2’ succeeded, server=primary
assigned_rad_session_id=9771184754689 session_timeout=0 secs idle_timeout=0 secs!
Specific (not wildcard) user with access profile assigned by FGT AND Group Matching on Fortigate side
RADIUS has no notion of Groups on Fortinet device, but we do have an option to use VSA Fortinet-specific Attribute Fortinet-Group-Name code 1 as a String – we just set in Network Policy of NPS for matching conditions to send some custom string (doesn’t have to match the user’s Group in AD) which Fortigate will match to the string we configure in Fortigate as well. If the string in FGT matches the string the RADIUS sends when a user successfully autheticated, Fortigate will allow it as well. When using this feature with VPN Groups on Fortigate, it makes sense to match the existing groups exactly.
Config on the NPS side steps:
Configure “group” matching on the Fortigate, remember – it is just string against string matching, also it is case-sensitive:
edit “RAdminGroup”
set member “RAD1”
config match
edit 1
set server-name “RAD1”
set group-name “FGTADMINS”
next
end
next
end
Debug (excerpts only, as much of it is the same as above):
User adminad5 matches RADIUS User Group on the FGT:
[333] __compose_group_list_from_req-Group ‘RAdminGroup’, type 1
[456] fnbamd_rad_get-vfid=0, name=’RAD1′
[805] __rad_auth_ctx_insert-Loaded RADIUS server ‘RAD1’
[663] __add_admin_rad_svr-Loaded RADIUS server ‘RAD1’ for admin user ‘adminad5’
RADIUS response (success):
[1148] __rad_chk_resp_authenticator-ret=0
[1216] fnbamd_rad_validate_pkt-RADIUS resp code 2
AFTER successfully authenticating the user adminad5 by RADIUS, next step is to match on the string sent as VSA Attribute – these actions are independent, RADIUS may send SUCCESS but then FGT will fail user if the VSA Attribute doesn’t match:
[502] fnbamd_rad_get_vsas-FORTINET attr, type 1, val FGTADMINS
[868] fnbamd_radius_parse_mschapv2_attr-Decoding TYPE_MS_MPPE_Recv_Key
[791] __radius_decode_mppe_key-Key len after decode 16
[879] fnbamd_radius_parse_mschapv2_attr-Decoding TYPE_MS_MPPE_Send_Key
[791] __radius_decode_mppe_key-Key len after decode 16
[1485] fnbamd_rad_process-Challenged: 0, FTK_Challenge: 0, CHG_PWD: 0, Invaid_Digest: 0, State_Len: 0
[627] fnbam_user_auth_group_match-req id: 10265108312068, server: RAD1, local auth: 0, dn match: 0
[581] __group_match-Check if RAD1 is a group member
[587] __group_match-Group ‘RAdminGroup’ passed group matching
[590] __group_match-Add matched group ‘RAdminGroup'(3)
Example of failed login on group-name string mismatch. Below is debug of when I intentionally put group-name on FGT in lower case, while it is upper case on RADIUS:
set member “RAD1”
config match
edit 1
set server-name “RAD1”
set group-name “fgtadmins”
next
end
next
end
Pay attention to the RADIUS response code – 2 (success), but in the 2nd step of matching the string, FGT fails the user:
[912] __rad_rxtx-
[1286] fnbamd_rad_process-Result from radius svr ‘RAD1’ is 0, req 10265108312067
[502] fnbamd_rad_get_vsas-FORTINET attr, type 1, val FGTADMINS
[868] fnbamd_radius_parse_mschapv2_attr-Decoding TYPE_MS_MPPE_Recv_Key
[791] __radius_decode_mppe_key-Key len after decode 16
[879] fnbamd_radius_parse_mschapv2_attr-Decoding TYPE_MS_MPPE_Send_Key
[791] __radius_decode_mppe_key-Key len after decode 16
[1485] fnbamd_rad_process-Challenged: 0, FTK_Challenge: 0, CHG_PWD:
0, Invaid_Digest: 0, State_Len: 0
[627] fnbam_user_auth_group_match-req id: 10265108312067, server: RAD1,
local auth: 0, dn match: 0
[581] __group_match-Check if RAD1 is a group member
[209] find_matched_usr_grps-Failed group matching
Fortianalyzer
FAZ also has the option of matching on Group Name sent from RADIUS. It is useful when using wildcard users and authenticating against the same NPS server – we cannot in such case allow any Domain Users as matching condition in NPS Policy, as this would allow any AD users that do not exist on FAZ but do exist in AD to authenticate.
Task: create RADIUS-authenticated user adminad9 on FAZ, when it connects assign it profile ADOMSuper_User and limit his access to the FGT-only ADOM.
So for this, I create user adminad9 on both FAZ and AD. I create a new AD Group FGT-only-adom which will have as a member just user adminad9. And then create NPS Policy matching user on AD Group FGT-only-adom and sending with the response also Fortinet VSA Attribute 1 Group-Name to be additional match on the FAZ side.
User adminad9 on the FAZ:
Using the same RADIUS server:
edit “RAD-184”
set server “10.100.104.184”
set secret ENC MTY2NTg3Nj
set auth-type mschap2
next
end
The user with the matching condition of string “FGT-only”:
config system admin user
edit “adminad9”
set profileid “ADOMSuper_User”
set adom-access specify
set adom “FGT-only” (1)
set dev-group “FGT-Perimeter-firewalls” (2)
set user_type radius
set radius_server “RAD-184”
config meta-data
edit “Contact Email”
next
edit “Contact Phone”
next
end
set ext-auth-group-match “FGT-only” (3)
set use-global-theme disable
set user-theme autumn (4)
next
end
Limit to this ADOM only
(Opt) Inside the ADOM, limit access to this device group only
Match on this string sent as VSA Attribute “Group-Name”, fail if no match
(Opt) Set the GUI Theme for this user
NPS Policy:
After log in, the user cannot change ADOM, and has Autumn as the theme:
Debug
s16: found admin: adminad9
s16: start radius: RAD-184
s16:RAD-184: connect to server 0: 10.100.104.184 ip=10.100.104.184 port=1812
s16:RAD-184: send request: type=mschap2 id=13
s16:RAD-184: got reply: code=accept(2) id=13
s16:RAD-184: 0-80: len=16
s16:RAD-184: ftnt-group: FGT-only <– GROUP-NAME SENT FROM RADIUS
s16:RAD-184: 0-7: len=4
s16:RAD-184: 0-6: len=4
s16:RAD-184: 0-25: len=44
s16:RAD-184: 311-17: len=34
s16:RAD-184: 311-16: len=34
s16:RAD-184: 311-26: GS=9ACFB7F404F0530F90AE097C95C0A69B119B250D
s16:RAD-184: 311-10: GARGO
s16:RAD-184: success
s16: auth result: success
References
I also write cheat sheets/scripts/guides to help in daily work, so make sure to check out my Github at https://github.com/yuriskinfo and https://www.linkedin.com/in/yurislobodyanyuk/