LDAP Auth and FreeIPA 4.9.6
-
Re: LDAP Auth and FreeIPA 4.4.1
I wanted to make an update to this, as I just had a nightmare trying to get this working with a guide that's 99.9% accurate. What follows is in no way prescriptive, but is here to document my experience so that others may have an easier time.
Note 1: Start off with transport set to "Standard TCP" while debugging. It will allow packet captures to show you exactly what's going on.
Note 2: You need a matching group on pfsense and FreeIPA, either the existing admins group or a new one created for the purpose, e.g. fw_admins from the referenced guide. This group needs to be given appropriate permissions from within pfsense. I went with "WebCfg - All pages" which effectively gives full admin rights.Step 1 in the previous guide needs slight tweaking:
First of all, add FreeIPA's CA to pfsense. Copy the contents of /etc/ipa/ca.crt from FreeIPA. Then on pfsense, go to System->Cert. Manager->CAs and click "Add." Give it a name, choose "Import an existing Certificate Authority" then check "Add this Certificate Authority to the Operating System Trust Store." The point of this is to allow pfsense to accept FreeIPA's self-signed certificate when connecting over TLS later. Paste the certificate data and leave the private key and serial blank - the firewall doesn't need to own this cert, it just needs to trust it. Hit save.
Now that pfsense trusts FreeIPA, we need to do the reverse (disclaimer, I don't actually know that this next step is necessary, but it's included for completeness's sake).
#This command needs to be run on pfsense. openssl req -out myFW-csr.csr -new -newkey rsa:2048 -nodes -keyout myFW-private.pem
I did this from the pfsense CLI as per the referenced guide, however I suspect it would be better to use the cert manager in the Web UI.
Once complete, copy myFW-csr.csr to your FreeIPA server however you wish.
You can't use the "--add" option with a host principal anymore, so next you'll have to create the principal, such as "host/myfw.mydomain.com". I did this from the webUI, and the instructions for that are not in the scope of this documentation.
On the IPA server, run:
kinit admin ##remember, this is kerberos ipa cert-request ./myFW-csr.csr
It will prompt you for the principal you just created.
You then need to go back to pfsense's cert manager to the Certificates tab and click "Add/Sign." Again give it a name and select "Import an existing certificate." The certificate data is from the output of the cert-request command, and the private key is the myFW-private.pem file created earlier. The certificate type should already be set to X.509 (PEM). Hit save.
Now we get to the real goal. Under System->User Manager->Authentication Servers, click Add. The type should be set to LDAP. I named mine simply "FreeIPA."
Hostname or IP Address: e.g. ipa.mydomain.com
Port Value: Don't set this manually, but should be 389 for plain or 636 for secure
Transport: For debugging purposes, choose "Standard TCP." If everything is working, change this to "SSL/TLS Encrypted."
Peer Certificate Authority: The FreeIPA CA you imported earlier
Protocol Version: 3
Search Scope: Entire Subtree
Base DN: something like dc=mydomain,dc=com
Authentication containers: cn=users,cn=accounts,dc=mydomain,dc=com
Note: You may be able to select this by clicking the button, which is a good test that your above settings were correct. If not, check again after setting the bind DN and password in a few stepsExtended query: enabled
Query: memberOf=cn=fw_admins,cn=groups,cn=accounts,dc=mydomain,dc=com
Note: This caused me endless headaches. Pfsense combines whatever you put in this box like so: (&(member=uid={user DN})(&{query})). This means that if you wrap the contents of this box in parentheses, the search will fail. You need to be careful about formatting - when in doubt, do a packet capture to see what pfsense is sending as a query.Bind anonymous: uncheck this
Bind credentials: Different from the original guide - DN and password of the user that will perform queries. For example uid=admin,cn=users,cn=accounts,dc=mydomain,dc=com
User naming attribute: uid
Group naming attribute: cn
Group member attribute: member - this is different from the original guide
RFC 2307 Groups: Unchecked - different from original guide. If your users have "memberOf" attributes, this should not be checked.
Group object class: posixGroup
UTF Encode: unchecked
Username Alterations: unchecked
Allow unauthenticated bind: unchecked
Finally, hit save. You should now be able to login to pfsense as any user in the FreeIPA fw_admins group
Troubleshooting
Most importantly, see Note 1 above!
- Set your transport to Standard TCP
- Under Diagnostics->Packet Capture, run a capture on TCP packets to port 389 of your FreeIPA server
- Under Diagnostics->Authentication, choose your FreeIPA server and log in with a username and password
- Stop the packet capture, download it, and open it in wireshark.
- On the Diagnostics->Authorization page, you should see a message that the user was authenticated successfully, along with a list of groups as shown below
Here's roughly what you should see:
- Bind request from pfsense using the credentials supplied under "Bind Credentials"
- Bind response of "success" from FreeIPA
- Search request from pfsense with a base like "cn=users,cn=accounts,dc=mydomain,dc=com", filtering for uid={username you entered}
a. Note - using a program like LDAP Admin, check that this user is located at this spot in your tree. - Exactly one search Result Entry from FreeIPA showing the DN of that user.
a. Examine the value tree in wireshark until you find "PartialAttributeList item memberOf" near the bottom. These are all of the groups to which that member belongs. - Search Result Done success (1 result) from FreeIPA
- Another bind request from pfsense combining the DN from step 4 with the password you entered on the diagnostics page
- Bind result success from FreeIPA
- Unbind request from pfsense
Common errors (or rather, mistakes that I made and learned from):
- Everything works fine with "Standard TCP" selected but stops working with "SSL/TLS Encrypted" selected
Make sure your certificates have all been set up from the start of the guide, and that the CA you imported from FreeIPA is selected for your Authorization Server.
- The user was authenticated successfully, but no groups appear on the diagnostics screen
The issue is with your extended query. Examine the exact syntax of the query in your packet capture, and try to replicate it using ldapsearch on your FreeIPA CLI. That command will give you more specific errors, and will let you easily try out variations on filters without going through the slow process of editing your authentication server in pfsense. Once you find a filter that works, edit your extended query in pfsense such that the packet capture uses the same filter. Remember that pfsense merges your extended query with a filter of its own, so you can't just paste the entire filter into that box.
- Everything works on the diagnostics side, but I still can't log in
You need to give permissions from within pfsense. Whatever group you're using, for example "fw_admins" or just "admins" needs to be created under System->User Management->Groups and be given permissions. The "WebCfg - All pages" permission will give that group full access to the pfsense Web UI, for instance.
I hope this helps someone out there. I'm very much not an expert on pfsense, LDAP, SSL, or FreeIPA, so I probably can't answer any questions that aren't already covered by this post. This was a struggle of many hours over a few things that were almost correct but not quite - which often seems so much harder to fix than something that is completely wrong.
-
Last step, which is missing from OP: Under System->User Management->Settings, change the authentication server to the one you just created. I recommend testing everything using diagnostics first, however.
-
I'm going to add one more note here in case anyone ever finds this (but mainly for my own future reference). The query filter can check for multiple groups with an OR ("|") operator as long as the string is not wrapped in parentheses, because as mentioned in the OP pfsense is going to add its own parentheses and LDAP syntax doesn't like unnecessary levels of nested parens.
For example, I've modified my configuration to allow an additional user without admin privileges, and the filter now looks like this:
|(memberOf=cn=fw_admins,cn=groups,cn=accounts,dc=mydomain,dc=com)(memberOf=cn=fw_users,cn=groups,cn=accounts,dc=mydomain,dc=com)
This means that any LDAP user who belongs to EITHER the fw_admins group or the fw_users group may now log in. An important note is that both groups need to be defined in pfsense's group settings and have their specific permissions assigned their, such as which web configurator pages they can view.
-
@bdben
I recently upgraded from 2.4.4 to 2.6.0 and everything was fine, except for my LDAP config using Freeipa (Red Hat IDM actually).So I walked through this config and that got my LDAP authenticating for my VPN server, and I can authenticate on the webconfigurator, BUT, I get the error "No pages assigned to this user".
So I figured it was something wonky with the way the groups were returning now. I followed your diagnostics and did a packet capture. I am seeing the PartialAttributeList for memberof come back with ALL my groups in my FreeIPA LDAP. in the pcap. See this screenshot:
https://share.getcloudapp.com/GGuKp8glBut in the authentication diagnostics, it doesn't return any groups. See this screenshot:
https://share.getcloudapp.com/bLuBqrE4I have also tried using ldapsearch but I am not sure what to use to test the filtering? Here is what I was poking away with:
ldapsearch -D "uid=binduser,cn=users,cn=accounts,dc=shadowman,dc=dev" -W -b "dc=shadowman,dc=dev" -u "uid=ldixon"
And that does return an entry for
ldixon
and it brings back all the attributes I'd expect to see. As a sampling of what it returns :memberOf: cn=ssogroups,cn=groups,cn=accounts,dc=shadowman,dc=dev memberOf: cn=vcenter_admins,cn=groups,cn=accounts,dc=shadowman,dc=dev memberOf: cn=ipausers,cn=groups,cn=accounts,dc=shadowman,dc=dev memberOf: cn=editors,cn=groups,cn=accounts,dc=shadowman,dc=dev memberOf: cn=trust admins,cn=groups,cn=accounts,dc=shadowman,dc=dev memberOf: cn=service,cn=groups,cn=accounts,dc=shadowman,dc=dev memberOf: cn=tower_users,cn=groups,cn=accounts,dc=shadowman,dc=dev memberOf: cn=tower_admins,cn=groups,cn=accounts,dc=shadowman,dc=dev memberOf: cn=guacamoleusers,cn=groups,cn=accounts,dc=shadowman,dc=dev memberOf: cn=vpn_users,cn=groups,cn=accounts,dc=shadowman,dc=dev memberOf: cn=application,cn=groups,cn=accounts,dc=shadowman,dc=dev memberOf: cn=cloud,cn=groups,cn=accounts,dc=shadowman,dc=dev memberOf: cn=network,cn=groups,cn=accounts,dc=shadowman,dc=dev memberOf: cn=security,cn=groups,cn=accounts,dc=shadowman,dc=dev memberOf: cn=linux,cn=groups,cn=accounts,dc=shadowman,dc=dev memberOf: cn=windows,cn=groups,cn=accounts,dc=shadowman,dc=dev memberOf: cn=demondgroup,cn=groups,cn=accounts,dc=shadowman,dc=dev memberOf: cn=pfsense_admins,cn=groups,cn=accounts,dc=shadowman,dc=dev
This is what I have my extended query set to in pfsense:
memberOf=cn=pfsense_admins,cn=groups,cn=accounts,dc=shadowman,dc=dev
That group does exists in my pfsense settings as a remote group, and the names match exactly, and I have granted that group all of the webconfigurator pages for privileges.
I think my problem is that when I do the authentication diagnostics, for some reason pfsense doesn't seem to be parsing all the memberOf results correctly? Any ideas on what I can try?
-
@CubedRoot I have exactly the same behaviour in PFsense Plus 22.05. Did you find a solution yet?
-
I found my issue: the group membership attribute should be "memberOf" instead of member as posted by OP.