Why (and how) I switched from sudo to doas, and why you should too

2021/06/10

What is doas?

doas is a userspace utility from the OpenBSD project. From the manpage:

doas — execute commands as another user

If you are familiar with using sudo to perform actions as another user, then doas is an alternative implementation of the same goal.

So, why should I switch to doas?

Point 1: Security

sudo is a massive, feature-packed (“bloated”) program. Take a look at the source lines of code (SLOC) for sudo:

λ › tokei
===============================================================================
 Language            Files        Lines         Code     Comments       Blanks
===============================================================================
 Autoconf              107        56586        51294         3162         2130
 C                     329       128324        95141        19607        13576
 C Header               87        14984         8603         4901         1480
 Happy                   2         2839         2600            0          239
 JSON                    7          236          236            0            0
 Pascal                  3         1020          964           10           46
 Perl                    2          418          285           80           53
 Protocol Buffers        1          135          121            0           14
 Python                 10          706          537           51          118
 Shell                  65        22217        16720         2964         2533
 Plain Text              1            1            0            1            0
===============================================================================
 Total                 614       227466       176501        30776        20189
===============================================================================

With such a massive codebase, there are many potential points of failure. Since sudo runs commands as different users, then these points of failures could lead to one of the most devastating exploits: privilege escalation.

This isn’t just theoretical either. Take a look at the CVE list for sudo, which includes such delicacies as CVE-2021-3156: an off-by-one error that can result in a heap-based buffer overflow, which allows privilege escalation to root. And don’t think this is some old problem now that sudo is “mature” — the previously mentioned CVE was from January, 2021. It’s not a matter of “if”, but a matter of “when” new vulnerabilities are discovered for sudo.

In contrast, take a look at the CVE list for doas, and the SLOC for doas:

λ › tokei
===============================================================================
 Language            Files        Lines         Code     Comments       Blanks
===============================================================================
 C                      17         2435         1648          490          297
 C Header                5          986          774          140           72
 Happy                   1          352          317            0           35
 Markdown                1           63            0           45           18
 Shell                   1          561          412           88           61
===============================================================================
 Total                  25         4397         3151          763          483
===============================================================================

doas has ~3k SLOC compared to sudo’s ~177k. That’s nearly two full orders of magnitude less. While SLOC is not necessarily indicative of a secure implementation, it is far easier to audit a codebase that is 50 times smaller. Just by default, doas will have a far smaller attack surface than sudo.

Point 2: Ease of configuration

Everybody who’s used sudo at some point has had to wrangle with the dreaded /etc/sudoers file. This file is so complex, most sudo packages will provide a utility visudo just to ensure that users do not create an improper config file and lock themselves out of their system.

Now that may have been a slight embellishment. But the /etc/sudoers file really is too convoluted for average Linux desktop usage (notice the emphasis on desktop usage: more on this later).

As an example, consider the standard example for allowing a user to run any command:

user ALL=(ALL) ALL

Why are there so many ALLs? What do they all mean? You can see how easy this would be to misremember. Now, consider the same configuration in doas:

permit user

That’s so much cleaner.

Why shouldn’t I switch to doas?

In short: you should not switch to doas if you actually need the advanced configuration and granularity of sudo. If you don’t know if you need the advanced features of sudo, then you do not need the advanced features of sudo.

If you are using desktop Linux as a single-user, or even as a multi-user in a family home, then you don’t need all the features of sudo. doas will serve you just as well, if not better.

If you are a sysadmin in charge of an enterprise Linux server deployment, with hundreds/thousands of users, with all sorts of granular sudo settings, then doas probably will not work for you.

Alright, I’m convinced. Tell me how to switch.

I can only speak for Arch Linux from this point forward. doas has been ported over to Arch Linux and is in the official repositories under community/opendoas.

Before going forward with the installation, I highly recommend that you open a terminal emulator and log in as root. In the unfortunate scenario that you lock yourself out of sudo and doas, you can save yourself by running commands in this root terminal.

Install opendoas as follows:

# pacman -S opendoas

On Arch Linux, opendoas is configured with /etc/doas.conf. To allow users of the group wheel to run any command, insert the following line into /etc/doas.conf:

permit :wheel

If you only wish to let a certain user user access all commands, then:

permit user

What about more advanced configurations?

It’s possible that you may want more advanced configurations, such as letting a user only run certain commands as root, or passwordless command access. Let us show an example that will hopefully cover all the necessary cases.

For example: let’s say that we want any member of the group powerful to run a certain command /usr/bin/cmd as user leader, passwordlessly. Then:

permit nopass :powerful as leader /usr/bin/cmd

It’s as easy as that. Very readable and human-friendly. More details can be found in the (very concise) doas configuration manpage: man 5 doas.conf.

doas is asking for my password every time! sudo never did this! I’m never coming back here again!

By default, doas will ask for your password every time you run a command. While this is good for security, it can make certain command chains (doas cmd1 && doas cmd2 && doas cmd3 [...]) tedious. To emulate sudo timeout behavior, add persist to your configuration like so:

permit persist :wheel

From the manpage:

persist  After the user successfully authenticates, do not ask for a password again for some time.

I want to completely remove sudo and only use doas

There are multiple ways to do this. Most people will recommend uninstalling sudo and aliasing alias sudo=doas in your shell’s rc. I don’t like this method, as it is contingent upon sourcing the shell’s rc in order to get sudo functionality. What about scripts and applications that do not source the rc, or reset the environment before running? Instead, we should make a symlink on the filesystem itself, /usr/bin/sudo -> /usr/bin/doas.

Luckily, there is a package in the AUR opendoas-sudo that does this for you, so you don’t have to manually mess with parts of the filesystem that could conflict with the package manager. I use this package myself, and have had no issues.

Final thoughts

If nothing else, you should take from this post that sudo is a very large, complicated mess of a program. And no program is infallible. Even if you don’t switch to doas today, keep it in the back of your mind as a less bloated alternative to sudo.