Previous Entry Share Next Entry
Access your remote SUDO rules offline with SSSD
jhrozek
This blog post is intended as both advertisement and documentation for a nice feature of SSSD 1.8 and later - integration with the sudo utility. It is also a featured Fedora 17 Feature.

I assume most of the readers are familiar with sudo. If not, sudo is a utility that runs on most of flavors of Unix, including Linux, and allows the user to elevate his privileges and run a particular program, even a login shell, as another user. Most of the time, the "another user" would be root and sudo would be used to get root privileges without knowing the root password. To learn more about sudo, visit its homepage and read the documentation

The later sections of the article are also assuming that the reader is familiar with LDAP, in particular adding entries to a directory.

In a single-machine environment, such as a personal laptop, the easiest way to configure sudo is to edit the /etc/sudoers file, preferably using a tool that double-checks the syntax, such as visudo.

Obviously, in a big corporate environment, the administrator faces a problem - how to distribute the file to all the machines he administers? One possible solution is to use tools such as puppet and directly copy the /etc/sudoers file. The other solution, which I will be focusing on in the rest of this article, is to store the rules in a centralized database, in particular LDAP.

Sudo itself has built-in support for processing rules stored in LDAP. Because the data is centralized, the administrator does not have to worry about distributing anything. He just needs to enter the rules into the LDAP server and all the clients, provided they are correctly configured, will be able to use them. There is another problem, though. Now that the data is stored on a server accessible over the network, what happens when the network is down, either because the server is down or simply because the user uses a laptop that is disconnected from the network?

Our solution is to cache the data retrieved from the central server on the client machine. We have developed a new SSSD service that caches the sudo rules much like SSSD is able to cache information about users including their credentials. Instead of sudo contacting the LDAP server directly, sudo queries SSSD. In this scenario, the SSSD acts as kind of a proxy between sudo and the LDAP server - the sudo utility has no idea whether the results came from the server itself or the on-disk cache.

There are several benefits to this approach, the most notable being the offline support and better performance. In a little more detail:
  • offline support - the on-disk cache SSSD provides means that the sudo rules that were previously retrieved from the central server are available even if the client machine is not connected to the network or the server that contains the sudo rules is down.

  • better performance - each invocation of sudo translates into one or more requests to the LDAP server over the network which might be slow and combined with other client requests affect the performance and load of the server itself. Consider a simple scenario where a user that is allowed to run some commands as root would like to edit a configuration file for a random service without knowing where exactly the file is. He might want to run sudo ls several times, then sudo vim some-service.conf and finally sudo service some-service restart. When sudo is configured to use SSSD as the information source, only the first request contacts the server by default and the successive requests are served from the cache for a configurable period of time to improve performance and reduce load. Another performance improvement is that the SSSD only keeps a single connection to the LDAP server open at a time. In comparison, multiple sudo users with the native LDAP back end would trigger multiple LDAP connections.

  • unified configuration - instead of configuring the SSSD to perform account lookups and then configuring /etc/ldap.conf to perform sudo rules lookups, the user only configures one client piece - the SSSD. The SSSD also provides several advanced features that might not be available in other LDAP client packages, such as the support for server discovery using DNS SRV requests or advanced server fail over, which lets the admin define several servers that are tried in descending order of preference and then stick to the working server

  • back end abstraction - while most of this article talks about LDAP, it would in theory be possible to store sudoers in another form of database
Now that we know what we can accomplish with sudo and SSSD integrated, let's show a more practical example.

A hands-on example

In our model example, we are going to create two groups - readers and writers. Readers must be able to read and inspect all config files, writers must also be able to edit them. Our goal is to store the entries in LDAP so that they are centralized and access them using the SSSD to leverage caching and allow offline access. To simplify the matter, we are going to allow executing the commands on all hosts in the enterprise. A prerequisite to this example is a running LDAP server, such as OpenLDAP or 389 Directory Server. In the rest of this example I will be using the base DN of dc=example,dc=com.

I'm going to start by configuring sudo to use its native LDAP lookup capability. In the next section, we will be migrating the setup to SSSD.

The rules are referring two group stored in LDAP - I will skip adding the users and the groups, because this step might depend on the layout and schema your directory server uses. Depending on your directory server, you might also want to add the required SUDO schema. The Schema files for some of the most popular directory servers are part of the sudo distribution and are located in /usr/share/doc/sudo-$version/schema.* on my Fedora machine.

Below are the corresponding LDAP entries. Use a utility such as ldapadd to add them into your server. The first entry is simply a container the rules are stored in. The native sudo lookup mechanism uses a hardcoded container name ou=SUDOers. SSSD allows the user to configure a custom search base.

dn: ou=SUDOers,dc=example,dc=com
objectClass: top
objectClass: nsContainer
ou: SUDOers


The next two objects are the two rules themselves. The readers_rule is referencing a group called readers with its sudoUser attribute. The sudoCommand attribute contains the command that we are allowing to be run, which is the "less" pager in particular.

dn: cn=readers_rule,ou=SUDOers,dc=example,dc=com
objectClass: top
objectClass: sudoRole
cn: readers_rule
sudoUser: %readers
sudoHost: ALL
sudoCommand: /usr/bin/less


The second object is very similar, just the group name and the command name are different.

dn: cn=writers_rule,ou=SUDOers,dc=example,dc=com
objectClass: top
objectClass: sudoRole
cn: writers_rule
sudoUser: %writers
sudoHost: ALL
sudoCommand: /usr/bin/vim


The next step is to configure sudo to fetch user data from LDAP. This example assumes that you are already using the SSSD to retreive user and group data and will be only using the built in sudoers LDAP support to fetch sudo rules. First, you need to specify the LDAP server and sudoers search base in the /etc/ldap.conf config file:

uri ldap://ldap.example.com
sudoers_base ou=SUDOers,dc=example,dc=com


See the sudoers.ldap(5) manual page for more options.

With the rule database populated, we can configure sudo to start using them now. Sudo uses the configuration file /etc/nsswitch.conf to specify the data sources, in particular it uses the "sudoers" line. That said, the glibc does not provide a sudoers map, such as it does for passwd or netgroups. If the directive is not specified, it defaults to "files", that is, only read sudo rules from the /etc/sudoers file.
And then configure the sudo utility itself to connect to LDAP for sudoers information:

sudoers: files ldap

Now simply log in as user who belongs to either readers or writers group - you can type id or groups to check group memberships for a user. And that's it, you should be able to list the commands the user is allowed to run with sudo -l and also execute them.
This setup obviously does the job but comes at the costs mentioned in the previous part of the article - every sudo command queries the LDAP server which might be slow. Also, if the network is unreachable for any reason, you're out of luck, which might be an important factor if the administrator is trying to fix network problems and his sudo data are stored in an LDAP server.

How to migrate to SSSD

This section will show you how to set up the SSSD as a proxy for storing sudoers. A prerequisite is a sudo binary with sss plugin support (sudo-1.8.1p2 or later). As of this writing, only the Fedora version of sudo contains the plugin, although the support should land in the sudo upstream soon.


In case you are already using the SSSD for user and group lookups, the configuration will be extremely easy:

  1. Create a new [sudo] section in the /etc/sssd/sssd.conf config file. You can leave it empty or fine-tune it with sudo specific configuration options. See man sssd.conf for a (currently quite short) list of available options:

    [sudo]
  2. In the [sssd] section of the /etc/sssd/sssd.conf file, extend the services directive to also include sudo. If services originally included nss, pam which is the default, it would look like this:

    services = nss,pam,sudo

  3. If your sudo rules are stored outside the ldap_search_base, you also need to set the ldap_sudo_search_base parameter to point to the LDAP subtree that contains the sudo rules.

    ldap_sudo_search_base = ou=SUDOers,dc=example,dc=com

  4. The last step is to tell sudo to contact the SSSD for sudoers rules list. This is done in the /etc/nsswitch.conf config file:

    sudoers: files sss

    Whether to leave files in or not depends on your local configuration, but it might be prudent to retain the same order as the passwd and group NSS databases.

  5. Restart the SSSD.

    service sssd restart

Sudo will now fetch data via the SSSD. You should be able to see increased performance, especially when multiple sudo commands are used. Sudo will also be able to answer requests from the central directory even if network was unreachable or the LDAP server was down.

The SSSD only stores the rules that were explicitly requested using the sudo utility. If you need to download all the rules, for example to protect against the situation where the network is down but you need to act as a user who never used sudo before, you can also use the "periodical download" feature. See the ldap_sudo_refresh_enabled and ldap_sudo_refresh_timeout options of sssd-ldap(5) manual page to learn more about this feature.

Conclusion

This article showed the benefits of using the sudo service of SSSD to fetch sudoers rules on behalf of sudo. There is not much more configuration right now - which is a good thing, because the sudo/SSSD integration should just run well out of the box.

That said, we are still targeting several improvements, mainly in the field of multi domain support.

Please also note that the feature is quite fresh, so there might be bugs here and there. We would very much appreciate bug reports, RFEs or general comments.
Tags: , ,

Well done. When I was testing the SUDO WebUI for FreeIPA, I realized just how painful it was to deal with the client side configuration. SSSD was the path forward then, and I am glad to see we've arrived!

Thank you. The support for the FreeIPA native schema is not implemented yet, though. We chose to support the more generic LDAP schema, which is exposed using the compat plugin on a FreeIPA server first, and add the native FreeIPA schema in upstream SSSD 1.10.

My IPA server has the compat plugin enabled, but I cannot get sudo to work via sssd (sssd-1.8.3-11.fc17). Seems to work fine via ldap, but I am at a loss as to how to conifgure it to work with sssd. Any ideas?

Do you have any bind user enabled for accessing the rules? One of the reasons sssd might not work is that the current version only uses unauthenticated binds to the IPA server, while IPA protects the sudo rules with ACIs even in the compat tree by default.

So to access the rules on the IPA, you'd have to either set sssd to use password bind mounts or change the ACIs for the compat tree.

Native IPA support is on the roadmap for 1.10.

i have same problem, but im using centos6 and rhel6, where i can got sudo rpm with sss backend enabled.


It's going to be part of RHEL6.4.

Alternatively, for testing purposes, you can rebuild the sudo and sssd packages from F-18.

I just followed your guide, and it... just works !
Thanks for the nice step by step explanation.

PS My server is openldap 2.4 (a fedora 15 minimalist installation).

You are viewing jhrozek