AD Group Checking with RADIUS Attribute Mapping

PrivacyIDEA, the application itself, can only communicate via a HTTP REST API. To augment this “limitation” there are a number of plugins that convert from one protocol or API into PrivacyIDEA’s REST API.

So when you use httpie, you are communicating directly with PrivacyIDEA, bypassing the PrivacyIDEA-RADIUS plugin. When you attempt to authenticate through the Fortigate, it is communicating via RADIUS, which is picked up by the PrivacyIDEA-RADIUS plugin, converted to a REST request, and passed along to PrivacyIDEA.

A better, equivilent test is to use radclient from your PrivacyIDEA server.

echo "User-Name=user, User-Password=password" | radclient -sx 127.0.0.1 \
   auth secret_here

Note: For this to work, your freeradius clients.conf file will need to include an entry for itself, something like

client localhost {
    ipaddr = 127.0.0.1
    proto = *
    netmask = 32
    secret = secret_here
    nastype = other
}

Running radclient with -sx will cause it to run in debug mode and print out a summary. This should help with troubleshooting.

On the Fortigate side, the User Group you’ve created needs to match what PrivacyIDEA is passing back. If your rlm_perl.ini is configured to match CN=VPNgroupname,CN=Users,DC=somedomain,DC=com, then the user group in the Fortigate needs to be exactly that. If you are using a regex, which I would recommend, like regex = CN=(VPNgroupname).*, then you only need to enter VPNgroupname in the Fortigate User group. Regex would allow you to match on multiple groups and create multiple Fortigate user groups. Use the regex | which acts as an OR to the statement to match on multiple groups

regex = CN=(VPNGroup1|VPNGroup2|VPNGroup3).*

The above will pass VPNGroup1, VPNGroup2, or VPNGroup3 back to the Fortigate. An issue I ran into with the Fortigate, it will only take ONE value for Fortinet-Group-Name. So if a user is a member of VPNGroup1 and VPNGroup2, the Fortigate will only put the user in the last group it receives from the PrivacyIDEA-RADIUS plugin.

In addition to the user group, you also need a firewall policy to allow this authenticating traffic to flow through. The source needs to include the VPN subnet assigned to the portal as well as the user group.

Thanks!

I have radclient working and was using it to test, and from that I can see it’s working:

Sent Access-Request Id 69 from 0.0.0.0:39857 to 172.XX.YY.ZZ:1812 length 64
	User-Name = "test2"
	User-Password = "xxxxxOTP"
	Cleartext-Password = "xxxxxOTP"
Received Access-Accept Id 69 from 172.X.Y.Z:1812 to 0.0.0.0:0 length 48
	Reply-Message = "privacyIDEA access granted"
Packet summary:
	Accepted      : 1
	Rejected      : 0
	Lost          : 0
	Passed filter : 1
	Failed filter : 0

And since I’m testing I mapped the identical group name (pasted it in) which I used in Fortigate setup.
Info: rlm_perl: +++ Map: Fortinet-Group-Name → “VPN_groupname”

and from the above I can be pretty sure I the radius server sent all correctly. So, it’s an issue on the firewall then. hmm.

I use IPSec VPN, I created multiple tunnels using peerID and each tunnel is assigned to a different AD group through group objects with no local users, just remote server: RADIUS and Group Name: VPN_groupname, as I mapped to Fortinet-Group-Name.

Fortigate logs show in negotiate IPsec phase1 failure due to “XAUTH authentication failed”, and

Group N/A
XAUTH User test2
XAUTH Group N/A

If I take the group name out of the VPN user group with RADIUS, it works fine. I think I have to dig into Fortigate logs more to see what’s up there.

Thanks for the clarification on the REST vs radius. I read about the plugin “hijacking” radius traffic and converting it to the REST API, but forgot about what I’m getting through the /validate/check.

So, Fortigate then.

If its not in production, you can stop the freeradius service and then run freeradius in debug from CLI with freeradius -X, and get a lot more output, it should tell you what the value is that RADIUS is putting in the Fortinet-Group-Name attribute.

“hijacking” is a strong word…has negative connotations to it to me. It’s more like an interpreter, changing a request from one language to another.

1 Like

Resolved! It wasn’t actually sending the attribute. I misunderstood the “mapping” directive. I’m new to freeRADIUS, too, so having it in debug mode, and wireshark to check the conversation between the firewall and radius helped out. All working well now.

Yeah, in a security context “hijacking” is a wrong word. :slight_smile:

Thanks for your help @wwalker ! Much appreciated. :+1:

1 Like

@wwalker Btw, just an FYI, on Fortigate 7.2.x version it appears it will look through all the Fortinet-Group-Name values, and then pick the one that matches.

I tested with a user in two AD groups which are used with 2 VPN tunnels, and each is associated with only one group. It will look at both values returned and pick the one that matches for that tunnel and ignore the other. See the reply back from freeRADIUS to the Fortigate.
Untitled

In this case the user was logging in to the VPN tunnel assigned with the first Fortinet-Group-Name value, while the second one was ignored (it’s used in another tunnel).

So, regex = CN=(VPNGroup1|VPNGroup2|VPNGroup3).* will work if a user is a member of VPNGroup1 and VPNGroup2.

I’d need to go through Fortigate OS release notes to confirm they’ve added that functionality, but it’s working fine in my case. I am using IPSec tunnel, and not SSL so am not sure is there any differences between IPSec and SSL how it processes the reply (I expect not to, but…).

I hope it helps. :slight_smile: