Sunday, Jan 31, 2021
#security #unix #openbsd #tool

doas is a simple and easy to configure replacement for sudo. It’s built by the OpenBSD developers (same ones who make OpenSSH, OpenNTPD, and LibreSSL), so you can be quite confident in its security/simplicity standards. On a basic level, it allows for running a command as a different user. Typically, that means allowing an “unprivileged” user to run “privileged” commands such as installing packages or updating the web server. The configuration syntax is very simple and straightforward, making complicated setups easy to understand.

doas accomplishes about 95% of what sudo is used for with a fraction of the code and complexity. I quickly checked the lines of code in the current stable version of each program using David A. Wheeler’s sloccount. sudo is at version 1.9.5p2 and doas is at 6.8.1.

$ cd OpenDoas
$ sloccount .
SLOC	Directory	SLOC-by-Language (Sorted)
3479    OpenDoas        ansic=2423,sh=667,yacc=290,perl=99

Totals grouped by language (dominant language first):
ansic:         2423 (69.65%)
sh:             667 (19.17%)
yacc:           290 (8.34%)
perl:            99 (2.85%)
$ cd sudo-1.9.5p2
$ sloccount .
SLOC	Directory	SLOC-by-Language (Sorted)
47841   plugins         ansic=43243,yacc=2118,lex=1295,sh=843,python=342
28060   lib             ansic=28060
10339   src_top_dir     ansic=10339
8081    scripts         sh=7761,perl=320
5193    logsrvd         ansic=5193
3140    top_dir         sh=3140
3091    include         ansic=3091
245     doc             sed=229,sh=16
203     src_regress     ansic=203
32      etc             sh=32
0       examples        (none)
0       m4              (none)
0       po              (none)

Totals grouped by language (dominant language first):
ansic:        90129 (84.85%)
sh:           11792 (11.10%)
yacc:          2118 (1.99%)
lex:           1295 (1.22%)
python:         342 (0.32%)
perl:           320 (0.30%)
sed:            229 (0.22%)

In terms of C code, sudu is over 37 times larger than doas. I would argue it is not 37 times more useful to make up for the larger attack surface. The vast majority of extra code implements rarely used features, which are likely not as actively maintained. This might explain why sudo has around 58 CVEs since January 2019, including a fairly serious one a few days ago, in the same time the portable version of doas has had 3. None of which apply to the native version on OpenBSD.

One may argue sudo is audited more intensely due to its prevalence. It’s true that doas certainly doesn’t share the same popularity as sudo, but it comes default on OpenBSD and is very common on NetBSD, FreeBSD, and linux distros – including the tiny and extremely prevalent Alpine – which are at the heart of many major targets.

The other big source of issues with sudo comes from trying to configure it to do anything more complicated than allow the wheel group to run commands as root. Its manual is like 10,000 lines long and includes the following man sudoers | grep -C1 despair.

The sudoers file grammar will be described below in Extended Backus-Naur Form (EBNF). Don’t despair if you are unfamiliar with EBNF; it is fairly simple, and the definitions below are annotated.


Configuring doas is dead simple. The manual is under 200 lines and OpenBSD prides itself on well written, easy to understand manuals. In fact, documentation issues are considered critical since they’re just as likely to cause serious vulnerabilities and issues as technical problems.

The basic config to allow all members of the wheel group to run commands as root is this:

$ cat /etc/doas.conf
permit persist :wheel

persist is an option that allows elevated commands to be run multiple times in a session, only authenticating with a password on the first attempt.

permit/deny and an identity are the only required entries. An identity can be a group or a user - groups are prefixed with :. You may also add a command to limit the scope to a single command rather than all commands. Read man 5 doas.conf for more information.