cn=Directory Manager
All about Directory Server
All | Personal | Sun

20051211 Sunday December 11, 2005

Forget your roots

It's a very common security practice to run server processes as a non-root user with limited capabilities. Unfortunately, you often need certain capabilities that are normally available only to the root user, including the ability to bind to privileged ports and the ability to increase the number of available file descriptors that may be used by a single process.

The way that the Directory Server and other daemons commonly deal with this is to require that they are started by the root user so they can create the listen sockets and do any other root-required processing, but then they call setuid to drop to an unprivileged user. This is effective, and certainly much safer than running as root, but there are a couple of problems with it:
  • It requires that the user have root access in order to be able to start the server. This is possible when a system boots through startup scripts (or an SMF profile in Solaris 10), but if you need to start the server at a time other than system boot then you need to be root. There is a way to work around this problem using RBAC, but I'll describe a better alternative below (and it still doesn't solve the next issue).
  • If you want to do something in the server process that would require root access after the startup has completed and setuid is called (e.g., start listening on another privileged port), then that operation would fail.

The ideal solution to this problem would be to have some way of granting a normal user the ability to do things that are normally only allowed for the root user. Solaris 10 provides exactly this capability through process rights management, also called least privilege. Using this mechanism, you can grant a normal user the ability to do things like bind to privileged ports or increase the number of available file descriptors. In fact, you can even take away the ability to do things that a normal user is allowed to do, like see what processes others are running on the system. In the Solaris 10 GA release, there are 48 privileges that have been identified and can be granted to or removed from a user. For a description of all of these privileges, issue the command:
ppriv -lv

To see what privileges you currently have, issue the command:
ppriv $$

By default, when this command is run as a normal user, you will see that you have "basic" privilege set, which expands to the combination of file_link_any, proc_exec, proc_fork, proc_info, and proc_session (these are the capabilities that have historically been granted to unprivileged users -- you can get this list using "ppriv -l basic").

For the purposes of Directory Server, the most interesting privileges include:
  • net_privaddr -- Controls the ability to bind to privileged ports (i.e., port 1024 and below).
  • sys_resource -- Controls the ability to modify resource limits, including the number of available file descriptors.
  • dtrace_proc -- Controls the ability to use DTrace against processes that the user can control.
  • dtrace_user -- Controls the ability to use DTrace for things outside the kernel (i.e., "user space" code).
  • proc_info -- Controls the ability to see any processes on the system other than those that the user can control.
  • file_link_any -- Controls the ability to create hard links to files owed by anyone other than the current user.

When I'm configuring an account for use by the Directory Server, I will usually take away the proc_info and file_link_any privileges and grant the other four. You can do this with a regular user account, but as I mentioned yesterday, it's better to use a role. When you're creating the role, you can do this by adding the "-K" option and specifying a value for the defaultpriv property. For example:
roleadd -d /export/home/dirsrv -m -s /usr/bin/bash -K defaultpriv=basic,net_privaddr,sys_resource,dtrace_proc,dtrace_user,-proc_info,-file_link_any dirsrv

If the role already exists, then you can use rolemod with the same -K argument string to accomplish the same effect. And of course if you want to use a normal user account rather than a role, then you can do it with useradd and usermod rather than roleadd and rolemod.

Once this has been done, you should be able to start the server while logged into the system as that role or user, and you will see that the server can start and operate without requiring root access. Further, if the server attempts to do anything that might require those privileges once it's running, then it will be granted as well. With current versions of the server, this shouldn't be needed, but we do have improvements in the works that could benefit from this.

One additional point that I should make in this discussion is that process rights management has been integrated with the Service Management Facility (SMF), another new capability in Solaris 10 that is intended for use in starting or stopping the services configured for use on a system. If you do put the Directory Server under SMF control (which is possible, but outside the scope of this discussion), then you can grant or revoke privileges in the SMF manifest itself so that they would be available for use by the Directory Server but not by any other processes started by that user or role. Perhaps that's a good topic for a future post.

Posted by cn_equals_directory_manager ( Dec 11 2005, 02:35:59 PM CST ) Permalink


Archives
Language
Links
Referrers