Skip to main content

Linux Users, Groups, and Permissions

·1462 words·7 mins
Linux Learning Lab
Author
Linux Learning Lab
Writing about code, tools, and workflows.
linux-beginner - This article is part of a series.
Part 3: This Article

The Linux Security Model
#

Linux is a multi-user operating system. Every file, process, and resource is owned by a user and associated with a group. The permission system controls who can read, write, or execute each file.

This model is simple but effective:

  • Users — individual accounts (human or service)
  • Groups — collections of users that share access
  • Permissions — rules on each file defining what users/groups can do

Users
#

Types of users
#

TypeUID RangePurpose
Root0Superuser — unrestricted access
System/service1–999Run background services (nginx, postgres)
Regular users1000+Human accounts

Viewing user information
#

# Current user
whoami

# Current user's ID and groups
id

# Details about any user
id mike

# All users on the system
cat /etc/passwd

The /etc/passwd file format:

mike:x:1000:1000:Mike:/home/mike:/bin/bash
FieldMeaning
mikeUsername
xPassword stored in /etc/shadow
1000User ID (UID)
1000Primary group ID (GID)
MikeComment/full name
/home/mikeHome directory
/bin/bashLogin shell

Managing users
#

# Create a user
sudo useradd -m -s /bin/bash newuser

# Create with specific options
sudo useradd -m -s /bin/bash -G sudo,docker -c "Jane Smith" jane

# Set/change password
sudo passwd newuser

# Modify a user
sudo usermod -aG docker mike    # Add mike to docker group
sudo usermod -s /bin/zsh mike   # Change shell

# Delete a user
sudo userdel newuser            # Remove user, keep home directory
sudo userdel -r newuser         # Remove user and home directory

# Lock/unlock an account
sudo usermod -L jane            # Lock
sudo usermod -U jane            # Unlock

Key flags for useradd/usermod
#

FlagMeaning
-mCreate home directory
-sSet login shell
-GSupplementary groups
-aGAppend to groups (usermod only — without -a, it replaces groups)
-cComment (full name)
-dHome directory path
-eAccount expiration date

Groups
#

Groups let you grant access to multiple users without setting permissions individually.

Viewing groups
#

# Current user's groups
groups

# Groups for a specific user
groups mike

# All groups on the system
cat /etc/group

# Details about a group
getent group docker

Managing groups
#

# Create a group
sudo groupadd developers

# Add a user to a group
sudo usermod -aG developers mike

# Remove a user from a group
sudo gpasswd -d mike developers

# Delete a group
sudo groupdel developers

Important: After adding a user to a group, they need to log out and back in (or run newgrp groupname) for the change to take effect.

Primary vs supplementary groups
#

  • Primary group — assigned at user creation, used as the default group for new files
  • Supplementary groups — additional groups the user belongs to
# Check primary group
id -gn mike

# Check all groups
id -Gn mike

File Permissions
#

Every file has three permission sets:

-rwxr-xr-- 1 mike developers 4096 Jun 9 10:00 script.sh
 │││ │││ │││
 │││ │││ └── Others (everyone else)
 │││ └──── Group (developers)
 └────── Owner (mike)

Permission types
#

SymbolPermissionOn filesOn directories
rReadView contentsList contents
wWriteModify contentsCreate/delete files inside
xExecuteRun as programEnter (cd into) the directory
-NoneNo accessNo access

Reading permissions
#

-rwxr-xr--
PositionMeaning
-File type (- = file, d = directory, l = link)
rwxOwner can read, write, execute
r-xGroup can read and execute, not write
r--Others can only read

Changing Permissions with chmod
#

Symbolic mode
#

# Add execute for owner
chmod u+x script.sh

# Remove write for group and others
chmod go-w file.txt

# Set exact permissions
chmod u=rwx,g=rx,o=r script.sh

# Add read for everyone
chmod a+r file.txt
SymbolMeaning
uUser (owner)
gGroup
oOthers
aAll (user + group + others)
+Add permission
-Remove permission
=Set exact permission

Numeric (octal) mode
#

Each permission has a numeric value:

PermissionValue
Read (r)4
Write (w)2
Execute (x)1
None (-)0

Add the values for each set:

OctalPermissionsMeaning
7rwxFull access
6rw-Read and write
5r-xRead and execute
4r--Read only
0---No access
chmod 755 script.sh    # rwxr-xr-x (owner full, group/others read+execute)
chmod 644 file.txt     # rw-r--r-- (owner read/write, group/others read)
chmod 700 private/     # rwx------ (owner only)
chmod 600 secret.key   # rw------- (owner read/write only)

Common permission patterns
#

OctalUse case
755Executable scripts, directories
644Regular files (configs, documents)
700Private directories
600Private files (SSH keys, secrets)
775Shared group directories
664Shared group files

Recursive permissions
#

# Apply to directory and all contents
chmod -R 755 /var/www/html/

# Set directories to 755 and files to 644 (common for web)
find /var/www -type d -exec chmod 755 {} \;
find /var/www -type f -exec chmod 644 {} \;

Changing Ownership with chown
#

# Change owner
sudo chown mike file.txt

# Change owner and group
sudo chown mike:developers file.txt

# Change group only
sudo chown :developers file.txt
# or
sudo chgrp developers file.txt

# Recursive
sudo chown -R mike:developers /var/www/project/

Special Permissions
#

setuid (SUID)
#

When set on an executable, it runs as the file owner, not the user who launched it:

# The passwd command has SUID — it runs as root so it can modify /etc/shadow
ls -l /usr/bin/passwd
# -rwsr-xr-x 1 root root ... /usr/bin/passwd

The s in the owner execute position indicates SUID.

chmod u+s program
chmod 4755 program

setgid (SGID)
#

On a file: runs as the file’s group. On a directory: new files inherit the directory’s group:

# Set SGID on a shared directory
chmod g+s /shared/projects/
chmod 2775 /shared/projects/

# Now any file created inside inherits the "projects" group

Sticky bit
#

On a directory: only the file owner (or root) can delete files, even if others have write permission:

# /tmp uses the sticky bit
ls -ld /tmp
# drwxrwxrwt ... /tmp

# Set sticky bit
chmod +t /shared/
chmod 1777 /shared/

The t in the others execute position indicates the sticky bit.

sudo — Running Commands as Root
#

Regular users can’t modify system files or manage services. sudo grants temporary elevated privileges.

# Run a single command as root
sudo apt update

# Open a root shell
sudo -i

# Run as a different user
sudo -u postgres psql

# Edit a file as root (use this instead of sudo vim)
sudoedit /etc/ssh/sshd_config

The sudoers file
#

/etc/sudoers controls who can use sudo. Always edit it with visudo — it validates syntax before saving:

sudo visudo

Common entries:

# User mike can run any command as root
mike ALL=(ALL) ALL

# Group developers can restart nginx without a password
%developers ALL=(ALL) NOPASSWD: /usr/bin/systemctl restart nginx

# User deploy can run specific commands only
deploy ALL=(ALL) NOPASSWD: /usr/bin/systemctl restart myapp, /usr/bin/journalctl -u myapp

sudo vs su
#

CommandAction
sudo commandRun one command as root
sudo -iStart a root login shell
su - usernameSwitch to another user (needs their password)
sudo su - usernameSwitch to another user (needs your sudo privilege)

umask — Default Permissions for New Files
#

The umask value determines what permissions are removed from new files:

# View current umask
umask
# 0022

# What this means:
# New files:       666 - 022 = 644 (rw-r--r--)
# New directories: 777 - 022 = 755 (rwxr-xr-x)
# Set a more restrictive umask
umask 077
# New files: 600, new directories: 700

Make it persistent by adding to ~/.bashrc.

Practical Examples
#

Set up a shared project directory
#

# Create group and directory
sudo groupadd webteam
sudo mkdir /var/www/project
sudo chown root:webteam /var/www/project
sudo chmod 2775 /var/www/project

# Add users to the group
sudo usermod -aG webteam mike
sudo usermod -aG webteam jane

The SGID bit (2) ensures new files inherit the webteam group.

Secure SSH keys
#

chmod 700 ~/.ssh
chmod 600 ~/.ssh/id_ed25519
chmod 644 ~/.ssh/id_ed25519.pub
chmod 600 ~/.ssh/config

Find files with incorrect permissions
#

# World-writable files (potential security issue)
find / -type f -perm -002 2>/dev/null

# SUID binaries (should be a short, known list)
find / -perm -4000 2>/dev/null

# Files not owned by any user
find / -nouser 2>/dev/null

Best Practices
#

  • Use groups to manage shared access instead of making files world-readable
  • Apply the principle of least privilege — give the minimum permissions needed
  • Never set 777 on anything — there’s always a better approach
  • Use sudo for individual commands rather than working in a root shell
  • Always use visudo to edit the sudoers file — a syntax error can lock you out
  • Set SGID on shared directories so group ownership is inherited automatically
  • Keep SSH keys at 600 — SSH refuses to use keys with loose permissions
  • Audit SUID binaries periodically — an unexpected SUID binary is a red flag
linux-beginner - This article is part of a series.
Part 3: This Article