Skip to content

User & Permission Management

Managing who can log in, what they can run as root, and which files they can touch is the foundation of a secure server. This guide covers accounts, groups, sudo, standard permissions, and ACLs.

Tested on

AlmaLinux 9 / RHEL 9. Debian/Ubuntu differences are noted inline.

Users and groups

Create a user

# Create a user with a home directory and bash as the login shell
sudo useradd --create-home --shell /bin/bash deepak

# Set the password interactively
sudo passwd deepak

useradd reads its defaults from /etc/default/useradd and /etc/login.defs. The new account's details live in /etc/passwd, and the hashed password in /etc/shadow.

Inspect an account

id deepak              # uid, gid, and group membership
getent passwd deepak   # the /etc/passwd entry

Modify a user

# Add the user to a supplementary group (the -a is critical — without it you
# REPLACE all supplementary groups instead of appending)
sudo usermod -aG wheel deepak

# Change the login shell
sudo usermod --shell /usr/sbin/nologin svcuser

# Lock / unlock an account
sudo usermod --lock deepak
sudo usermod --unlock deepak

The classic usermod -G mistake

usermod -G wheel deepak (without -a) removes the user from every other supplementary group. Always use -aG to append.

Delete a user

sudo userdel deepak          # keep the home directory
sudo userdel --remove deepak # also delete /home/deepak and mail spool

Groups

sudo groupadd developers       # create a group
sudo gpasswd -a deepak developers   # add a member
sudo gpasswd -d deepak developers   # remove a member
getent group developers        # list members

Granting root access with sudo

Editing the sudoers config directly is dangerous — a syntax error can lock you out of sudo entirely. Always use visudo, which validates before saving.

sudo visudo

On RHEL-family systems, members of the wheel group get full sudo by default. On Debian/Ubuntu, it's the sudo group.

# RHEL/AlmaLinux
sudo usermod -aG wheel deepak
# Debian/Ubuntu
sudo usermod -aG sudo deepak

Scoped sudo rules with drop-in files

Prefer small files under /etc/sudoers.d/ over editing the main file. Validate with visudo -c -f:

# Allow the 'deploy' user to restart only nginx, without a password
echo 'deploy ALL=(root) NOPASSWD: /usr/bin/systemctl restart nginx' \
  | sudo tee /etc/sudoers.d/deploy-nginx
sudo chmod 0440 /etc/sudoers.d/deploy-nginx
sudo visudo -c -f /etc/sudoers.d/deploy-nginx

NOPASSWD with broad commands

NOPASSWD: ALL or wildcards like /bin/* effectively hand out full root with no audit friction. Scope every rule to exact binaries and arguments.

File permissions

Every file has an owner, a group, and three permission triads — owner / group / other — each with read (r/4), write (w/2), execute (x/1).

ls -l deploy.sh
# -rwxr-x---. 1 deploy developers 482 Jun  7 10:14 deploy.sh
#  │└┬┘└┬┘└┬┘   └──┬─┘ └───┬────┘
#  │ │  │  │       │       └ group
#  │ │  │  │       └ owner
#  │ │  │  └ other: ---  (no access)
#  │ │  └ group: r-x  (read + execute)
#  │ └ owner: rwx  (read + write + execute)
#  └ file type: - regular, d directory, l symlink

Change ownership and mode

sudo chown deploy:developers deploy.sh   # owner:group
sudo chmod 750 deploy.sh                  # rwxr-x--- (numeric)
sudo chmod g+w,o-rwx deploy.sh            # symbolic
sudo chmod -R u+rwX,g+rX,o-rwx /srv/app   # X = execute only on dirs/already-exec
Mode Meaning Typical use
644 rw-r--r-- regular files
600 rw------- secrets, private keys
755 rwxr-xr-x directories, public scripts
750 rwxr-x--- group-restricted scripts
700 rwx------ private directories

Special bits

# setgid on a shared directory: new files inherit the directory's group
sudo chmod 2775 /srv/shared
# sticky bit: only the file owner can delete their files (like /tmp)
sudo chmod 1777 /srv/dropbox

Fine-grained access with ACLs

Standard permissions allow exactly one owner and one group. When you need "this directory, plus read access for one extra user," use POSIX ACLs.

# Grant a single user read+execute, without changing ownership
sudo setfacl -m u:auditor:rx /srv/app

# Grant a group read+write recursively, and set the default for new files
sudo setfacl -R -m g:developers:rwX /srv/app
sudo setfacl -R -d -m g:developers:rwX /srv/app

# View ACLs
getfacl /srv/app

A + at the end of the permission string in ls -l (e.g. drwxr-x---+) means an ACL is present.

Remove ACLs

sudo setfacl -b /srv/app   # strip all ACLs, back to standard perms

Verify your work

id deepak                       # confirm group membership
sudo -l -U deploy               # show what 'deploy' may run via sudo
namei -l /srv/app/config.yml    # walk the full permission path to a file

Summary

  • Use useradd/usermod -aG/userdel for accounts; never forget the -a.
  • Grant root via wheel (RHEL) or sudo (Debian), and edit sudoers only through visudo, scoping rules tightly in /etc/sudoers.d/.
  • Numeric modes (644, 750, 600) cover most files; reach for setgid/sticky bits on shared dirs.
  • Use ACLs when one owner + one group isn't enough.

Test yourself