> For the complete documentation index, see [llms.txt](https://book.bsdcn.org/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://book.bsdcn.org/ask/flat/chapter-14-user-accounts-and-permissions/di-14.4-jie-quan-xian-ti-sheng-gong-ju.md).

# 14.4 Privilege Escalation Tools

sudo and doas define privilege rules through configuration files, enabling specific users to execute privileged operations without the root password, and provide operation logging.

> **Thought Question**
>
> > Even administrators should restrict their own privileges when privileged operations are not needed.
>
> What do you think are the disadvantages of this privilege restriction design?

![Privilege diagram](/files/FlKfN2oXhHhgzlFRKrtR)

## doas

doas is a command-line tool ported from OpenBSD that can serve as an alternative to sudo in Unix-like systems.

The author of doas is Ted Unangst, and it was first introduced with OpenBSD 5.8. Users can execute commands with elevated privileges (typically as root) through doas. Unlike sudo, doas emphasizes configuration simplicity and security, focusing on streamlined privilege delegation and avoiding complex configuration options.

When using it, `sudo` can be directly replaced with `doas`; the two are functionally equivalent in basic usage scenarios. doas supports the following options:

| Option               | Description                                                     |
| -------------------- | --------------------------------------------------------------- |
| `nopass`             | Execute without password                                        |
| `keepenv` / `setenv` | Environment variable control (inherit or set)                   |
| `args`               | Command argument restriction                                    |
| `nolog`              | Do not log                                                      |
| `persist`            | Password caching (only supported by Port **security/opendoas**) |

doas does not have sudo's plugin architecture and LDAP integration or other advanced features.

### Installing doas

* Install using pkg:

```sh
# pkg install doas
```

* Or install using Ports:

```sh
# cd /usr/ports/security/doas/
# make install clean
```

### Using doas for Shared Privilege Management

User `user2` only needs to create the file **/usr/local/etc/doas.conf** and write:

```ini
permit nopass user2 as root
```

This allows user `user2` to obtain `root` privileges via doas without entering a password. If password-free doas is not needed, simply remove `nopass`.

> **Warning**
>
> The `nopass` option, while convenient, poses a security risk: if the user account is compromised, the attacker can gain root privileges without any additional credentials. It is recommended to use `nopass` only in trusted single-user desktop environments; multi-user or server environments should require password authentication.

For wheel group users, write the following line:

```ini
permit nopass :wheel
```

After installing and configuring `doas`, privileged commands can be executed:

```sh
$ doas ee /etc/rc.conf
```

### doas Example Configuration File

The example configuration file is located at **/usr/local/etc/doas.conf.sample**.

Brief annotations are as follows:

```ini
# Sample file for doas
# Please see doas.conf manual page for information on setting
# up a doas.conf file.

# Permit members of the wheel group to perform actions as root.
permit :wheel # Allow wheel group members to doas

# Same without having to enter the password
permit nopass :wheel # Allow wheel group members to doas without password

# Permit user alice to run commands as a root user.
permit alice as root # Allow user alice to doas

# Permit user bob to run programs as root, maintaining
# environment variables. Useful for GUI applications.
permit keepenv bob as root  # Allow user bob to doas, inheriting user bob's environment variables; needed for GUI applications, but reduces security (see post-install information)

# Permit user cindy to run only the pkg package manager as root
# to perform package updates and upgrades.
permit cindy as root cmd pkg args update  # Only allow user cindy to execute pkg update
permit cindy as root cmd pkg args upgrade # Only allow user cindy to execute pkg upgrade

# Allow david to run id command as root without logging it
permit nolog david as root cmd id # Allow david to run the id command as root without logging
```

## sudo

The original authors of sudo are Bob Coggeshall and Cliff Spencer (original version, circa 1980), and the primary rewriter and maintainer is Todd C. Miller.

sudo's `sudoers` configuration syntax has a high degree of complexity, with the manual page exceeding 1000 lines, making it prone to configuration errors that can lead to security vulnerabilities; timestamp files are located in **/var/run/sudo/ts/**, and if the file system is full, they may not work properly; `sudo -i` may not fully load environment variables in some shell environments.

`sudo` allows administrators to configure stricter system command access and provides logging functionality.

### Installing sudo

* Install using pkg:

```sh
# pkg install sudo
```

* Or install using Ports:

```sh
# cd /usr/ports/security/sudo/
# make install clean
```

### Using sudo for Shared Administration

The sudo configuration file consists of several sections and supports deep customization.

#### Configuring Regular Users to Use sudo

Unconfigured regular users executing sudo will receive the error `xxx Is Not in the Sudoers File. This Incident Will Be Reported`.

A line needs to be added to the sudoers configuration file to resolve this issue. Edit the **/usr/local/etc/sudoers** file, find the line `root ALL=(ALL:ALL) ALL`, and add a line below it:

```ini
actual_regular_user ALL=(ALL:ALL) ALL
```

Then save and exit. The user "actual\_regular\_user" will be able to use sudo; when prompted for a password, enter that user's password, not the root user's password.

#### Granting Specific Users Permission to Execute Specific Commands

In the following example, web application operations staff user1 needs to start, stop, and restart the web application *webservice*. To grant this user the relevant permissions, add a new line at the end of the **/usr/local/etc/sudoers** file:

```ini
user1   ALL=(ALL)       /usr/sbin/service webservice *
```

Then user user1 can start *webservice* via the following command:

```sh
$ sudo /usr/sbin/service webservice start
```

The above configuration only authorizes a single user (user1) for the webservice service, but most organizations have a Web team responsible for related management. Only one line of configuration is needed to grant permissions to an entire group. The following steps will first create a web group, then add users to it, and ultimately enable all group members to have the ability to manage the service:

```sh
# pw groupadd -g 6001 -n webteam
```

Then use the pw command to add the required user user1 to the webteam group:

```sh
# pw groupmod -m user1 -n webteam
```

Finally, write the following line in the **/usr/local/etc/sudoers** file to allow all members of the webteam group to manage *webservice*:

```ini
%webteam   ALL=(ALL)       /usr/sbin/service webservice *
```

#### sudo Password-Free for Regular Users and Groups

Users authorized to use sudo only need to enter their own password to complete authentication. Compared to `su`, the advantage of sudo is that `su` requires entering the `root` password and grants full `root` privileges, while sudo allows fine-grained privilege control per user or group. To allow webteam group members to manage the service without a password, change to:

```ini
%webteam   ALL=(ALL)       NOPASSWD: /usr/sbin/service webservice *
```

Similarly, if you want user user1 to be password-free, change to:

```sh
user1   ALL=(ALL)       NOPASSWD:ALL
```

If you want users in the `wheel` group to also be password-free, then:

```sh
%wheel   ALL=(ALL)       NOPASSWD:ALL
```

The percent sign `%` indicates a group; without `%` it indicates a regular user.

## sudo-rs

sudo-rs is an implementation of sudo and su written in Rust, security-oriented with memory safety.

### Non-coexistence Installation with sudo

Before installing sudo-rs, sudo must be uninstalled first; the two cannot coexist under this approach.

* Install using pkg:

```sh
# pkg install sudo-rs
```

* Or install using Ports:

```sh
# cd /usr/ports/security/sudo-rs/
# make install clean
```

Provides `sudo`, `visudo`, and `sudoedit` commands.

`visudo` edits the sudoers file in a secure manner, similar to vipw(8). It locks the sudoers file to prevent simultaneous editing, performs basic validity checks, and checks for syntax errors before installation. If syntax errors are found, it displays the line number and prompts "What now?", where the user can choose `e` (re-edit), `x` (exit without saving), or `Q` (force save, risky). Editor selection is determined by the `SUDO_EDITOR`, `VISUAL`, and `EDITOR` environment variables, defaulting to **/usr/bin/vi**.

FreeBSD's `visudo` comes from the sudo package (not the base system) and shares the same upstream source code as the Linux version, with basic compatibility.

### Coexistence Installation with sudo

Both sudo and sudo-rs exist in the system simultaneously.

* Install using pkg:

```sh
# pkg install sudo-rs-coexist
```

* Or install via Ports:

```sh
# cd /usr/ports/security/sudo-rs/
# make -V FLAVORS # View available FLAVORS
default coexist
# make FLAVOR=coexist install clean # Install the coexistence version of sudo-rs
```

Provides `sudo-rs`, `visudo-rs`, and `sudoedit-rs` commands.

### sudo-rs Example Configuration File

The configuration file is located at: **/usr/local/etc/sudoers**.

```ini
## sudoers file.

##
## This file MUST be edited with the 'visudo' command as root.

## Failure to use 'visudo' may result in syntax or file permission errors
## that prevent sudo from running.

##
## See the sudoers man page for the details on how to write a sudoers file.

## Defaults specification

##
## Preserve editor environment variables for visudo.

## To preserve these for all commands, remove the "!visudo" qualifier.

Defaults!/usr/local/sbin/visudo env_keep += "SUDO_EDITOR EDITOR VISUAL"

##
## Use a hard-coded PATH instead of the user's to find commands.

## This also helps prevent poorly written scripts from running
## arbitrary commands under sudo.

Defaults secure_path="/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"

##
## Uncomment if needed to preserve environmental variables related to the
## FreeBSD pkg utility and fetch.

# Defaults     env_keep += "PKG_CACHEDIR PKG_DBDIR FTP_PASSIVE_MODE"

##
## Additionally uncomment if needed to preserve environmental variables
## related to portupgrade

# Defaults     env_keep += "PORTSDIR PORTS_INDEX PORTS_DBDIR PACKAGES PKGTOOLS_CONF"

##
## You may wish to keep some of the following environment variables
## when running commands via sudo.

##
## Locale settings

# Defaults env_keep += "LANG LANGUAGE LINGUAS LC_* _XKB_CHARSET"

##
## X11 resource path settings

# Defaults env_keep += "XAPPLRESDIR XFILESEARCHPATH XUSERFILESEARCHPATH"

##
## Desktop path settings

# Defaults env_keep += "QTDIR KDEDIR"

##
## Allow sudo-run commands to inherit the callers' ConsoleKit session

# Defaults env_keep += "XDG_SESSION_COOKIE"

##
## Uncomment to enable special input methods.  Care should be taken as
## this may allow users to subvert the command being run via sudo.

# Defaults env_keep += "XMODIFIERS GTK_IM_MODULE QT_IM_MODULE QT_IM_SWITCHER"

##
## Uncomment to disable "use_pty" when running commands as root.

## Commands run as non-root users will run in a pseudo-terminal,
## not the user's own terminal, to prevent command injection.

# Defaults>root !use_pty

##

##
## User privilege specification

##
root ALL=(ALL:ALL) ALL

## Uncomment to allow members of group wheel to execute any command

# %wheel ALL=(ALL:ALL) ALL

## Same thing without a password

# %wheel ALL=(ALL:ALL) NOPASSWD: ALL

## Uncomment to allow members of group sudo to execute any command

# %sudo ALL=(ALL:ALL) ALL

## Uncomment to allow any user to run sudo if they know the password
## of the user they are running the command as (root by default).

# Defaults targetpw  # Ask for the password of the target user

# ALL ALL=(ALL:ALL) ALL  # WARNING: only use this together with 'Defaults targetpw'

## Read drop-in files from /usr/local/etc/sudoers.d

@includedir sudoers.d
```

### Testing

```sh
$ sudo su
[sudo: authenticate] Password: # Input is not displayed here, no mask prompt
#
```

## Appendix: Privilege Escalation via mac\_do

References:

* K Rin. FreeBSD MAC Introduction\[EB/OL]. \[2026-03-26]. <https://sandb0x.tw/a/FreeBSD_MAC_%E7%B0%A1%E5%96%AE%E4%BB%8B%E7%B4%B9>. A brief Chinese introduction to the basic concepts and configuration of the FreeBSD Mandatory Access Control framework.
* FreeBSD Project. mac\_do(4)\[EB/OL]. \[2026-03-26]. <https://man.freebsd.org/cgi/man.cgi?query=mac_do&sektion=4>. MAC policy do module manual page.
* OpenBSD. doas -- execute commands as another user\[EB/OL]. \[2026-04-17]. <https://man.openbsd.org/doas.1>. doas privilege escalation tool manual page.

## Privilege Escalation Tool Configuration File Structure

The following is a summary of the configuration file paths for the privilege escalation tools introduced in this section:

```sh
/usr/local/etc/
├── doas.conf  # doas configuration file
├── doas.conf.sample  # doas example configuration file
├── sudoers  # sudo/sudo-rs main configuration file
└── sudoers.d/  # sudo additional configuration directory
    ├── username  # Username configuration file
    └── wheel  # wheel group configuration file
```

## Exercises

1. Review the source code of the `mac_do` module in FreeBSD, analyze its mechanism for implementing privilege escalation through Mandatory Access Control, and outline the fundamental differences in the privilege model compared to `sudo`/`doas`.
2. Review the source code implementation of the `doas` tool in FreeBSD Ports, analyze the design of its configuration parsing, rule matching, and environment variable handling, and evaluate its trade-off strategy between simplicity and security.
3. Modify the `keepenv` option in the `doas` configuration, record its impact on environment variable inheritance behavior, and analyze the security risks of different environment variables (such as `PATH`, `HOME`) in privilege escalation scenarios.


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://book.bsdcn.org/ask/flat/chapter-14-user-accounts-and-permissions/di-14.4-jie-quan-xian-ti-sheng-gong-ju.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
