Chapter 07Lesson 03~50 minutes

sudo, su, Privilege Boundaries, and Least Privilege

Use sudo and su deliberately, design command-scoped privilege delegation, validate sudoers policy, and avoid common elevation hazards.

PrivilegesudoSecurity lab

Learning objectives

By the end of this lesson

  • Distinguish authentication, authorization, privilege elevation, and session switching.
  • Explain the operational differences among sudo command, sudo -u, sudo -i, and su -.
  • Inspect effective sudo policy with sudo -l.
  • Create a command-scoped rule under /etc/sudoers.d and validate it with visudo.
  • Recognize shell escapes, writable-command, wildcard, environment, and broad-group hazards.

1. Privilege boundaries are policy boundaries

Linux uses separate identities so ordinary work does not automatically have unrestricted authority. The root account has UID 0 and bypasses many discretionary checks, so moving into root context is not merely a convenience—it crosses a high-impact security boundary. A mature workflow elevates only for the operation that requires it, records who requested the action, and returns immediately to an unprivileged context.

Authentication

Prove an identity

A password, key, token, or other mechanism establishes who is requesting access.

Authorization

Decide what is allowed

Policy evaluates the requester, target identity, host, command, arguments, and context.

Execution

Run with target credentials

The approved command starts with controlled effective credentials and environment.

A sudo request crosses an explicit policy gate
flowchart TD
  U["Unprivileged user"] --> R["sudo request"]
  R --> A["Authenticate according to policy"]
  A --> P["Evaluate sudoers rules"]
  P -->|deny| D["Reject and log"]
  P -->|allow| E["Build controlled environment"]
  E --> T["Execute as target user"]
  T --> L["Record result and return"]

2. sudo and su solve different problems

CommandTypical intentOperational note
sudo commandRun one authorized command as rootPreferred when policy can be command-scoped
sudo -u svc commandRun as a non-root target userUseful for verifying service-account behavior
sudo -iStart a root login-style shellBroad context; use only when a sequence truly requires it
sudo -sStart a shell with elevated credentialsEnvironment differs from a login shell
su - userStart a login-style session as another userUsually authenticates according to PAM and local policy

su changes user context; it does not inherently provide fine-grained command policy or per-command attribution. sudo evaluates configured authorization and can log the invoking user. Neither tool makes an unsafe command safe.

# Inspect the current identity and available sudo policy
id
sudo --list

# Show a command that needs no root privilege
systemctl --user status 2>/dev/null || true

# Run one read-only command as root, if policy permits
sudo id

# Run a read-only identity check as another account
# Replace daemon only if it exists locally.
getent passwd daemon >/dev/null && sudo -u daemon id

3. Read sudoers as an authorization language

A sudoers specification identifies who may run what, on which hosts, as which target users and groups, with which tags. The apparent simplicity of a line can hide broad authority. A permitted editor, pager, interpreter, package manager, archive tool, or command with a shell escape may provide an indirect root shell.

Use visudo because it locks and validates the policy. Put local rules in a clearly named file under /etc/sudoers.d, make it root-owned and mode 0440, and validate the complete configuration before ending the current administrative session.

# Conceptual form only
who  where = (run-as-user:run-as-group) tags: command

# Example of a narrow command rule
%da-operators ALL=(root) /usr/local/sbin/da-host-summary
Exact command paths matter, but are not sufficient

The authorized executable and every file it reads, imports, executes, or writes must be protected from the delegated user. Arguments, wildcards, environment variables, and shell features can expand authority unexpectedly.

4. Design least-privilege elevation

01Define the operation

Describe the business task, required inputs, expected outputs, and failure behavior.

02Wrap complexity

Prefer a root-owned, non-writable helper with strict input validation over a long list of powerful generic commands.

03Constrain the target

Run as a dedicated service user rather than root when full UID 0 is unnecessary.

04Protect dependencies

Secure the helper, its configuration, PATH, libraries, working directories, and output destinations.

05Validate and test

Use visudo -c, sudo -l, negative tests, logs, and an emergency recovery path.

Avoid casual NOPASSWD use. It may be appropriate for tightly constrained automation, but it removes an interactive authentication checkpoint and increases the impact of a compromised account or unattended session.

5. Hands-on lab: delegate one read-only operation

Run this only on a disposable lab VM. The lab creates a group, installs a root-owned helper that accepts no arguments, delegates exactly that helper, validates the rule, and then removes the configuration.

lab_group=da-operators
helper=/usr/local/sbin/da-host-summary
rule=/etc/sudoers.d/da-host-summary

# Create the delegation group and add the current user.
# A new login session is normally needed for membership to take effect.
sudo groupadd --force "$lab_group"
sudo usermod --append --groups "$lab_group" "$USER"

# Install a root-owned helper. It refuses all arguments.
tmp=$(mktemp)
cat > "$tmp" <<'SCRIPT'
#!/usr/bin/env bash
set -euo pipefail
if (($# != 0)); then
  printf 'This command accepts no arguments.\n' >&2
  exit 64
fi
printf 'host=%s\n' "$(hostname)"
printf 'kernel=%s\n' "$(uname -r)"
printf 'uptime_seconds='
cut -d. -f1 /proc/uptime
SCRIPT
sudo install -o root -g root -m 0755 "$tmp" "$helper"
rm -f "$tmp"

# Create and validate the sudoers fragment.
printf '%%%s ALL=(root) %s\n' "$lab_group" "$helper" | sudo tee "$rule" >/dev/null
sudo chmod 0440 "$rule"
sudo visudo -cf "$rule"
sudo visudo -c

# Start a new login before this test if the group was newly added.
sudo --list
sudo "$helper"

# Negative test: arguments must be rejected by the helper.
if sudo "$helper" unexpected; then
  printf 'Negative test unexpectedly succeeded.\n' >&2
  exit 1
fi

# Cleanup after testing.
sudo rm -f "$rule" "$helper"
sudo gpasswd --delete "$USER" "$lab_group" 2>/dev/null || true
sudo groupdel "$lab_group" 2>/dev/null || true
sudo visudo -c

Verification checklist

6. Privilege-delegation hazards

Delegating a shell-capable program

Editors, pagers, interpreters, debuggers, and many maintenance tools can execute commands or load arbitrary code.

Authorizing writable scripts

If the caller can alter the script or a sourced file, the caller effectively controls what root executes.

Broad wildcards and arguments

Filesystem expansion, option injection, and unexpected argument combinations can exceed the intended resource scope.

Granting a generic administrative group

Membership in broad sudo-capable groups is often equivalent to full root and should be reviewed as such.

Leaving a root shell open

Long-lived elevated shells weaken attribution and make accidental commands much more destructive.

7. Knowledge check

Question 1. Why is a narrow root-owned helper often safer than delegating several generic tools?

Question 2. What does sudo -u appuser command accomplish?

Question 3. Why should the complete sudoers configuration be validated before closing an existing admin session?

8. Summary

Privilege elevation is an authorization workflow, not a shortcut. Prefer one command over a root shell, a dedicated target identity over UID 0, a protected purpose-built helper over generic powerful tools, and validated, logged policy over informal administrative groups. The goal is the smallest auditable authority that completes the task.

Next lesson

Password Policies, PAM, and Account Locking

The next lesson examines the authentication stack, password-aging controls, account-state checks, and the risks of changing PAM policy.

9. Further reading

  • sudo(8), sudoers(5), visudo(8), and sudo.conf(5).
  • su(1) and your distribution's PAM configuration.
  • Sudo project's security guidance on command matching, wildcards, environment, and logging.
  • Organizational privileged-access management and break-glass procedures.

Keep the academy open

Support free, practical DevOps education.

Every lesson is designed to remain readable in a browser, downloadable from GitHub, and usable without a paid learning platform. Contributions help expand and maintain the curriculum.

Ethereum / ERC-20
0x716c4Ab160C4B66F31a28AE2448BfF68fc3a2ef0 Send only Ethereum/ERC-20 compatible assets to this address.