Ways to allow unprivileged services to access privileged ones.

As a Linux System Administrator, you may need some kind of process that you are running to access or interact with privileged processes. Using su to run such a process means the user must know the root password, which is not the best practice. For this exact purpose, many tools were created for achieving this and in this blog post I am going to cover them.
If you want to see one specifically, you can just use the toggle button.

sudo

sudo is by far the most widely-known utility that allows unprivileged users to start and/or interact with privileged processes and it has been around since the 90's.

On a surface level, sudo reads a configuration file which contains the rules that it should follow, those being permissions for users. All you need in order to use it is to have been granted access by the system administrator and you can start privileged services by authenticating with your own password, or you may not even need an authentication method based on how your user was configured in the /etc/sudoers file.

It seems like it is quite a lite tool, when in fact it isn't. It has many features that have been added over the years which led to sudo being more complicated than it is meant to be and open the potential for a lot of vulnerabilities. As it is the case with any kind of complicated software, it has security holes that allow privilege escalation (a recent example being CVE-2023-22809 which ended up being a public exploit).

As vulnerabilities arised, developers created forks of sudo that replicate it's most common functionalities.

sudo-rs

sudo-rs was created by Memory Safety (a.k.a Prossimo ISRG) is meant to be a replacement for the original sudo ; the difference being the fact that it was entirely re-written in Rust in order to avoid the memory security issues that the original has, due to it being written in C.

It also lacks the features that opened vulnerabilities in the original, while also including some safety precautions for common sudoers mistakes. The following list was taken from the project's GitHub repository:

« Exceptions to the above, with respect to your /etc/sudoers configuration:

  • use_pty is enabled by default, but can be disabled.
  • env_reset is ignored --- this is always enabled.
  • visiblepw is ignored --- this is always disabled.
  • verifypw is currently ignored; a password is always necessary for sudo -v.
  • mail_badpass, always_set_home, always_query_group_plugin and match_group_by_gid are not applicable to our implementation, but ignored for compatibility reasons.

Some other notable restrictions to be aware of:

  • Some functionality is not yet supported; in particular sudoedit and preventing shell escapes using NOEXEC and NOINTERCEPT.
  • Per-user, per-command, per-host Defaults sudoers entries for finer-grained control are not (yet) supported.
  • Sudo-rs always uses PAM for authentication at this time, your system must be set up for PAM. Sudo-rs will use the sudo service configuration. This also means that resource limits, umasks, etc have to be configured via PAM and not through the sudoers file.
  • sudo-rs will not include the sendmail support of original sudo.
  • The sudoers file must be valid UTF-8.
  • To prevent a common configuration mistake in the sudoers file, wildcards are not supported in argument positions for a command. E.g., %sudoers ALL = /sbin/fsck* will allow sudo fsck and sudo fsck_exfat as expected, but %sudoers ALL = /bin/rm *.txt will not allow an operator to run sudo rm README.txt, nor sudo rm -rf /home .txt, as with original sudo. »

With this in mind, Linux users have an alternative for sudo, but what about other UNIX or Unix-like distributions? What about BSD variants? This is where doas comes in the scene.

doas

doas is entirely different from sudo, the formula is similar while being something new under the hood. Created by the OpenBSD Project, it has the same exact role that sudo has: to execute commands as another user.

The story starts with Ted Unangst which had issues configuring a sudoers config file. Those issues are the motive behind doas. It is much more simple, safer and does just what it is supposed to do. The configuration file syntax is also much more simple compared to sudo.

For example:

In order to allow a user to run privileged services, in sudo you would have to do this: user ALL=(ALL:ALL) ALL.

Meanwhile, with doas it is much easier to configure and understand it's syntax: permit user as root .

doas was introduced in OpenBSD 5.8, effectively replacing sudo, but the package is still available in the repositories if a user wants it specifically and it has also been forked over to Linux.

And last, but not least, the newest kid on the block: uid0

uid0

uid0 is not yet part of a released version of systemd as of the writing of this article. It is meant to be released with version 256 and it is only available for Linux distributions that have systemd as their init system.

It stands out by it's authentication method (it uses polkit), the fact that it doesn't depend on SetUID/SetGID, being PAM-reliant and it forks the service, allocates a pseudo-tty for it to be completely isolated for security concerns. This is all we know so far.

In theory, it should be the safest option so far because it isolates the environment in which the process is running, avoiding the posibility of potentially running malicious programs which could lead to data leakage. It remains to be seen whether it will do it's intended purpose.