Given how well the rest of the Synology DSM ecosystem works, one would be forgiven for believing that connecting it to FreeIPA would be simple or easy. Sadly, it isn’t and almost none of it seems to be Synology’s fault. For ease of actually accomplishing anything I’ve simplified my usecase significantly: NFS file shares with proper permissions set/controlled/understood by LDAP. I’m punting on CIFS/SAMBA shares since I’m literally the only person in my house who uses Windows and that is on a dual boot with Arch Linux anyway. As with all of these projects we start with the research phase.

This article from 2018 formed the basis for my plan but did things a little differently than I wanted. The process of figuring this out was very iterative so I will try to reorganize the steps I took into something that makes more logical sense.

Getting FreeIPA to Understand NFSv4

The first hurdle is that FreeIPA still does not ship with the LDAP schema elements required to get this working. You can check yourself with this command borrowed from here:

ldapsearch -H ldap:// -D 'cn=Directory Manager' \
    -W -x -s base -b 'cn=schema' objectclasses | \
    grep -i nfs

If that doesn’t return results like NFSv4RemotePerson you will need to add that configuration from a University of Michigan project first. I wasn’t able to use the method described in the first blog post of placing the LDIF file in /etc/dirsrv/slapd/schema/99nfs.ldif on the FreeIPA server since that directory doesn’t exist for me so I went for a more direct method. Here’s the LDIF file used and the command to inject it. Note that the bind DN of cn=Directory Manager was used instead of the admin account created during FreeIPA setup.

# nfsv4-schema.ldif
dn: cn=schema
changetype: modify
add: attributeTypes
attributeTypes: ( NAME 'NFSv4Name'
    DESC 'NFS version 4 Name'
    EQUALITY caseIgnoreIA5Match
    SYNTAX )
attributeTypes: ( NAME 'GSSAuthName'
    DESC 'RPCSEC GSS authenticated user name'
    EQUALITY caseIgnoreIA5Match
    SYNTAX )
add: objectClasses
objectClasses: ( NAME 'NFSv4RemotePerson'
    DESC 'NFS version4 person from remote NFSv4 Domain'
    MUST ( uidNumber $ gidNumber $ NFSv4Name )
    MAY ( cn $ GSSAuthName $ description) )
objectClasses: ( NAME 'NFSv4RemoteGroup'
    DESC 'NFS version4 group from remote NFSv4 Domain'
    MUST ( gidNumber $ NFSv4Name )
    MAY ( cn $ memberUid $ description) )

ldapadd -H ldap:// -D 'cn=Directory Manager' -W -f nfsv4-schema.ldif

Once FreeIPA understands the fields we want, it’s time to attach that information to our user objects. Again I did this through direct LDAP manipulations since I didn’t want to bother with writing a full FreeIPA plugin till I knew the method worked. The example below assumes the IPA domain is but should be updated appropriately for your actual instance.

# nfsv4-users.ldif
dn: uid=example,cn=users,cn=accounts,dc=example,dc=com
changetype: modify
add: objectClass
objectClass: NFSv4RemotePerson
add: GSSAuthName
GSSAuthName: example@EXAMPLE.COM
add: NFSv4Name

ldapadd -H ldap:// -D 'cn=Directory Manager' -W -f nfsv4-users.ldif

Getting Access to the New FreeIPA Attributes

A major difference between FreeIPA 3.x and the 4.x version I have deployed is the security posture of the LDAP server. In 3.x the system was more like a blacklist where everything was viewable except for specific forbidden fields. In 4.x it’s a whitelist where most everything is hidden unless specifically permissioned. This means, before we can have our service account look at the NFSv4 attributes, we have to tell FreeIPA that it is ok.

I managed all of this through the FreeIPA web UI but I’m fairly certain it can also be accomplished through the ipa CLI utility. The first step is the create a permission which gives read, search, and compare access on the GSSAuthName and NFSv4Name attributes. This is done under the IPA Server tab by clicking on the Role Based Access Control dropdown and selecting Permissions. As noted in our framing blog post you’ll need to enter the name of the attributes twice when creating the permission to have them set up correctly.

The next step is to add our Permission to a Privilege in FreeIPA. This is done through the same set of screens, selecting the Privileges tab from the dropdown instead of Permissions. Once that’s done we can finally create the object that will eventually give our service account the access it needs. From the same set of screens select Roles and create a new role named File Server assigning it the Permission we just created. Remember this name for later because we’re going to need to use it to attach the Role to our service account.

Creating the Service Account

The only real guide to FreeIPA service accounts is from back in the 3.x days but seems to work just fine here. The only modification is to add the inetUser objectClass so that you have access to the memberOf attribute per the mailing list discussion here. The LDIF shown below should accomplish what we’re looking for.

# service-account.ldif
dn: uid=system,cn=sysaccounts,cn=etc,dc=example,dc=com
changetype: add
objectclass: account
objectclass: simplesecurityobject
objectclass: inetuser
uid: system
userPassword: secret123
passwordExpirationTime: 20380119031407Z
nsIdleTimeout: 0

ldapadd -H ldap:// -D 'cn=Directory Manager' -W -f service-account.ldif

Finally, we can link the role to the newly created service account with another LDIF. For the memberOf line fill in the name of whatever Role you created as the final cn element.

# service-account-add-role.ldif
dn: uid=system,cn=sysaccounts,cn=etc,dc=example,dc=com
changetype: modify
add: memberOf
memberOf: cn=File Server,cn=roles,cn=accounts,dc=example,dc=com

ldapadd -H ldap:// -D 'cn=Directory Manager' -W -f service-account-add-role.ldif

Connecting Synology NAS to LDAP

Now with everything in place we can connect the NAS to LDAP through the Synology DSM web UI. In the Control Panel set up the LDAP domain connection using the service account DN and password created earlier. When selecting Server Type be sure to select Custom and provide under the filter heading (&(objectClass=inetOrgPerson)(objectClass=posixAccount)) for passwd and objectClass=posixGroup for group. This will keep your user and group list restricted to just those accounts that are capable of owning files on the NFS server. This trick was cribbed from a post by antonis found here.

Once that’s done, go through any shared folders and reconfigure them to remove mapping or squashing of unknown user accounts. Update your folder permissions as needed for different users and groups, then you should be ready to go!