Featured image for What is an Operating System

How to Create Users and Manage Permissions in Linux: The Complete Guide

Linux user management forms the backbone of system security. Every file, process, and service runs under a specific user context. Proper user and permission management prevents unauthorized access, data breaches, and system compromises.

This guide teaches you how to:

  • Create and manage users efficiently
  • Configure file permissions correctly
  • Implement access control lists
  • Automate user provisioning
  • Troubleshoot permission issues

Table of Contents

Understanding Linux User Types and System Architecture

Types of Users in Linux

Linux systems contain four main user types:

  1. Root User (UID 0): Has complete system control. Can modify any file and execute any command.
  2. System Users (UID 1-999): Run system services and daemons. Cannot login interactively.
  3. Regular Users (UID 1000+): Human users who login and perform tasks.
  4. Service Accounts: Special-purpose accounts for running specific applications.

User Database Files

Linux stores user information in four critical files:

/etc/passwd Structure

Contains user account information. Each line represents one user with seven colon-separated fields:

username:x:1000:1000:Full Name:/home/username:/bin/bash

Fields breakdown:

  • Username: Login name
  • Password: ‘x’ indicates password stored in /etc/shadow
  • UID: User ID number
  • GID: Primary group ID
  • GECOS: User description or full name
  • Home directory: User’s home path
  • Shell: Default shell program

/etc/shadow Structure

Stores encrypted passwords and aging information. Only root can read this file:

username:$6$hash:19000:0:99999:7:::

/etc/group Structure

Defines system groups:

groupname:x:1000:user1,user2,user3

/etc/gshadow Structure

Contains encrypted group passwords (rarely used).

Creating and Managing Linux Users

Essential User Management Commands

Creating Users with useradd

The useradd command creates new user accounts:

# Basic user creation
sudo useradd john

# Create user with home directory
sudo useradd -m sarah

# Create user with specific UID
sudo useradd -u 2000 mike

# Create user with comment
sudo useradd -c "John Doe - DevOps" -m john

# Create user with specific shell
sudo useradd -s /bin/zsh -m alice

# Create user with multiple options
sudo useradd -m -d /custom/home/bob -s /bin/bash -c "Bob Smith" -u 2001 bob

useradd vs adduser

Key differences:

  • useradd: Low-level utility, requires manual configuration
  • adduser: Interactive Perl script (Debian/Ubuntu), user-friendly wrapper
# Using adduser (Debian/Ubuntu)
sudo adduser jane
# Prompts for password and user information

Modifying Users with usermod

# Change username
sudo usermod -l newname oldname

# Change home directory
sudo usermod -d /new/home/path username

# Add user to supplementary groups
sudo usermod -aG docker,sudo username

# Lock user account
sudo usermod -L username

# Unlock user account
sudo usermod -U username

# Change user shell
sudo usermod -s /bin/zsh username

# Set account expiration
sudo usermod -e 2024-12-31 username

Deleting Users with userdel

# Delete user (keeps home directory)
sudo userdel username

# Delete user and home directory
sudo userdel -r username

# Force deletion (even if user logged in)
sudo userdel -f username

Advanced User Creation Options

Create system users for services:

# Create system user (no home, no login)
sudo useradd -r -s /usr/sbin/nologin mysqluser

# Create user with specific primary group
sudo useradd -g developers -m developer1

# Create user with password
sudo useradd -m -p $(openssl passwd -6 password123) user1

# Create user with account expiration
sudo useradd -e 2024-06-30 contractor1

Batch User Creation

Create multiple users efficiently:

Using a Shell Script

#!/bin/bash
# batch_users.sh

users=("user1" "user2" "user3" "user4" "user5")

for user in "${users[@]}"; do
    sudo useradd -m -s /bin/bash "$user"
    echo "$user:TempPass123!" | sudo chpasswd
    sudo chage -d 0 "$user"  # Force password change on first login
    echo "Created user: $user"
done

Using newusers Command

Create a file users.txt:

john:password:1001:1001:John Doe:/home/john:/bin/bash
jane:password:1002:1002:Jane Smith:/home/jane:/bin/bash
bob:password:1003:1003:Bob Johnson:/home/bob:/bin/bash

Import users:

sudo newusers users.txt

Linux Group Management Fundamentals

Creating and Managing Groups

Group Creation Commands

# Create a new group
sudo groupadd developers

# Create group with specific GID
sudo groupadd -g 2000 admins

# Create system group
sudo groupadd -r systemgroup

Modifying Groups

# Rename group
sudo groupmod -n newname oldname

# Change GID
sudo groupmod -g 2001 groupname

Deleting Groups

# Delete group
sudo groupdel groupname

Group Membership Management

Manage user group memberships:

# Add user to group
sudo usermod -aG groupname username

# Set user's primary group
sudo usermod -g groupname username

# Remove user from group (edit /etc/group manually or use gpasswd)
sudo gpasswd -d username groupname

# View user's groups
groups username

# View group members
getent group groupname

# Add multiple users to group
sudo gpasswd -M user1,user2,user3 groupname

Linux File Permissions: The Foundation

Understanding Permission Structure

Linux uses three permission types:

  • Read (r=4): View file contents or list directory
  • Write (w=2): Modify file or create/delete in directory
  • Execute (x=1): Run file or access directory

Permissions apply to three entities:

  • User (u): File owner
  • Group (g): Group owner
  • Others (o): Everyone else

Reading Permission Output

ls -la
-rwxr-xr-- 1 john developers 4096 Jan 15 10:30 script.sh

Breakdown:

  • First character: File type (- = regular file, d = directory, l = link)
  • Next 9 characters: Permissions (user, group, others)
  • Owner: john
  • Group: developers

Using chmod Command Effectively

Numeric Method

# Give owner full permissions, group read/execute, others nothing
chmod 750 file.sh

# Common permissions
chmod 755 script.sh    # rwxr-xr-x
chmod 644 document.txt  # rw-r--r--
chmod 600 private.key   # rw-------
chmod 777 public.tmp    # rwxrwxrwx (avoid this!)

# Recursive permission change
chmod -R 755 /var/www/html

Symbolic Method

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

# Remove write for group
chmod g-w file.txt

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

# Add read for all
chmod a+r document.txt

# Remove all permissions for others
chmod o-rwx sensitive.dat

# Multiple changes
chmod u+x,g+w,o-r file.txt

File Ownership with chown and chgrp

# Change file owner
sudo chown john file.txt

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

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

# Recursive ownership change
sudo chown -R www-data:www-data /var/www/html

# Copy ownership from another file
sudo chown --reference=template.txt target.txt

Advanced Linux Permissions and Special Bits

Special Permission Bits

SUID (Set User ID)

Executes file with owner’s privileges:

# Set SUID
chmod u+s /usr/local/bin/program
# or
chmod 4755 /usr/local/bin/program

# Find SUID files
find / -perm -4000 -type f 2>/dev/null

SGID (Set Group ID)

Files execute with group privileges. Directories inherit group ownership:

# Set SGID on directory
chmod g+s /shared/folder
# or
chmod 2775 /shared/folder

# Find SGID files
find / -perm -2000 -type f 2>/dev/null

Sticky Bit

Only file owner can delete files in directory:

# Set sticky bit
chmod +t /tmp
# or
chmod 1777 /tmp

# Verify sticky bit
ls -ld /tmp
# drwxrwxrwt 10 root root 4096 Jan 15 10:30 /tmp

Default Permissions with umask

The umask determines default permissions for new files:

# View current umask
umask

# Set umask (removes permissions)
umask 022  # Default: 755 for directories, 644 for files
umask 027  # Secure: 750 for directories, 640 for files

# Set permanently for user
echo "umask 027" >> ~/.bashrc

# Set system-wide
echo "umask 027" >> /etc/profile

Umask calculation:

  • Maximum permissions: 777 (directories), 666 (files)
  • Subtract umask value to get default permissions
  • Example: 666 – 022 = 644 for files

Access Control Lists (ACLs) in Linux

When and Why to Use ACLs

ACLs provide fine-grained permissions beyond traditional Unix permissions. Use ACLs when:

  • Multiple users need different access levels
  • Traditional permissions are too restrictive
  • Temporary access is required

Check ACL Support

# Verify filesystem supports ACLs
mount | grep acl

# Install ACL tools
sudo apt-get install acl  # Debian/Ubuntu
sudo yum install acl       # RHEL/CentOS

Managing ACLs

Setting ACLs with setfacl

# Grant user specific permissions
setfacl -m u:john:rwx file.txt

# Grant group permissions
setfacl -m g:developers:rx file.txt

# Set default ACL on directory
setfacl -d -m u:alice:rwx /shared/folder

# Remove specific ACL entry
setfacl -x u:john file.txt

# Remove all ACLs
setfacl -b file.txt

# Copy ACLs from one file to another
getfacl file1.txt | setfacl --set-file=- file2.txt

Viewing ACLs with getfacl

# View ACLs
getfacl file.txt

# View ACLs recursively
getfacl -R /shared/folder

# Backup ACLs
getfacl -R /data > acl_backup.txt

# Restore ACLs
setfacl --restore=acl_backup.txt

ACL Examples

# Create shared project directory
sudo mkdir /projects/webapp
sudo chgrp developers /projects/webapp
sudo chmod 2770 /projects/webapp

# Set default ACLs for new files
setfacl -d -m u::rwx /projects/webapp
setfacl -d -m g::rwx /projects/webapp
setfacl -d -m o::--- /projects/webapp

# Grant specific user read access
setfacl -m u:auditor:rx /projects/webapp

# Grant temporary access
setfacl -m u:contractor:rwx /projects/webapp
# Later remove it
setfacl -x u:contractor /projects/webapp

Sudo Configuration and Privilege Escalation

Configuring sudo Access

Understanding /etc/sudoers

Always edit sudoers using visudo:

# Edit sudoers file
sudo visudo

# Check syntax without editing
sudo visudo -c

Basic sudoers Syntax

# User privilege specification
username ALL=(ALL:ALL) ALL

# Allow user to run specific commands
john ALL=(ALL) /usr/bin/systemctl, /usr/bin/journalctl

# Allow group
%admin ALL=(ALL) ALL

# No password required
alice ALL=(ALL) NOPASSWD: ALL

# Specific host and commands
bob workstation=(root) /sbin/shutdown, /sbin/reboot

Creating sudoers.d Entries

# Create dedicated file
sudo visudo -f /etc/sudoers.d/developers

# Content example:
# Allow developers group to manage services
%developers ALL=(ALL) NOPASSWD: /usr/bin/systemctl restart nginx
%developers ALL=(ALL) NOPASSWD: /usr/bin/systemctl reload nginx
%developers ALL=(ALL) NOPASSWD: /usr/bin/systemctl status nginx

Advanced sudo Techniques

Command Aliases

# Define command aliases in sudoers
Cmnd_Alias SERVICES = /usr/bin/systemctl start *, \
                      /usr/bin/systemctl stop *, \
                      /usr/bin/systemctl restart *

Cmnd_Alias NETWORKING = /sbin/ifconfig, /sbin/route, \
                        /bin/ping, /sbin/iptables

# Use aliases
%netadmins ALL=(ALL) NETWORKING
%sysadmins ALL=(ALL) SERVICES

User and Host Aliases

# User aliases
User_Alias ADMINS = john, jane, bob
User_Alias DBADMINS = alice, charlie

# Host aliases
Host_Alias WEBSERVERS = web01, web02, web03
Host_Alias DBSERVERS = db01, db02

# Combine aliases
ADMINS ALL=(ALL) ALL
DBADMINS DBSERVERS=(postgres) ALL

Logging sudo Commands

# Enable sudo logging in sudoers
Defaults logfile="/var/log/sudo.log"
Defaults log_input
Defaults log_output

# View sudo logs
sudo cat /var/log/sudo.log
sudo journalctl -u sudo

Password Policies and Security Hardening

Implementing Password Policies

Password Aging with chage

# View password aging information
sudo chage -l username

# Set password expiration
sudo chage -M 90 username  # Maximum 90 days

# Set minimum days between changes
sudo chage -m 7 username

# Set warning days
sudo chage -W 14 username

# Force password change on next login
sudo chage -d 0 username

# Set account expiration date
sudo chage -E 2024-12-31 username

# Interactive mode
sudo chage username

PAM Password Quality

Install and configure password quality tools:

# Install password quality library
sudo apt-get install libpam-pwquality  # Debian/Ubuntu
sudo yum install pam_pwquality         # RHEL/CentOS

# Configure /etc/security/pwquality.conf
minlen = 12
dcredit = -1    # Require digit
ucredit = -1    # Require uppercase
lcredit = -1    # Require lowercase
ocredit = -1    # Require special character
minclass = 3    # Require 3 character classes

Account Lockout Policy

Configure PAM to lock accounts after failed attempts:

# Edit /etc/pam.d/common-auth (Debian/Ubuntu)
auth required pam_tally2.so deny=5 unlock_time=1800

# Reset failed login counter
sudo pam_tally2 --user=username --reset

Security Best Practices

Disable Unnecessary Accounts

# Lock system accounts
sudo passwd -l daemon
sudo passwd -l bin
sudo passwd -l sys

# Find accounts with no password
sudo awk -F: '($2 == "" || $2 == "!" || $2 == "*") {print $1}' /etc/shadow

# Find accounts with UID 0 (root privileges)
awk -F: '($3 == 0) {print $1}' /etc/passwd

Monitor User Activity

# Last login information
last
lastlog

# Currently logged in users
who
w

# User command history
sudo cat /home/username/.bash_history

# Failed login attempts
sudo grep "Failed password" /var/log/auth.log
sudo aureport -au  # If using auditd

User Environment and Profile Management

Shell Configuration Files

Understanding initialization file hierarchy:

  • /etc/profile: System-wide login shell settings
  • /etc/bash.bashrc: System-wide bash settings
  • ~/.profile: User login shell settings
  • ~/.bashrc: User bash-specific settings
  • ~/.bash_profile: User bash login settings

Setting Environment Variables

# System-wide environment variable
echo "export JAVA_HOME=/usr/lib/jvm/java-11" >> /etc/profile

# User-specific environment variable
echo "export PATH=$PATH:/home/user/bin" >> ~/.bashrc

# Temporary environment variable
export TEMP_VAR="value"

# View all environment variables
env
printenv

Custom User Environment

# Create default files for new users
sudo mkdir -p /etc/skel/.config
sudo cp custom_bashrc /etc/skel/.bashrc

# Set custom prompt
echo 'PS1="\u@\h:\w\$ "' >> ~/.bashrc

# Add aliases
cat >> ~/.bashrc << 'EOF'
alias ll='ls -la'
alias gs='git status'
alias dc='docker-compose'
EOF

# Apply changes
source ~/.bashrc

Resource Limits

Configure limits.conf

# Edit /etc/security/limits.conf
# Format: domain type item value

# User limits
john soft nproc 1000
john hard nproc 2000
john soft nofile 4096
john hard nofile 8192

# Group limits
@developers soft nproc 2000
@developers hard nproc 4000

# All users
* soft core 0
* hard core 0

Set User Quotas

# Install quota tools
sudo apt-get install quota

# Enable quotas on filesystem (edit /etc/fstab)
/dev/sda1 /home ext4 defaults,usrquota,grpquota 0 2

# Remount filesystem
sudo mount -o remount /home

# Create quota database
sudo quotacheck -cug /home

# Enable quotas
sudo quotaon /home

# Set user quota
sudo setquota -u username 100M 200M 0 0 /home

# View quota report
sudo repquota -a

Troubleshooting Common Permission Issues in Linux

Diagnostic Commands and Tools

Essential Diagnostic Commands

# Check file permissions and ownership
ls -la file.txt
stat file.txt

# Check user identity and groups
id
whoami
groups

# Check effective permissions
namei -l /path/to/file

# Test file access
test -r file.txt && echo "Readable" || echo "Not readable"
test -w file.txt && echo "Writable" || echo "Not writable"
test -x file.txt && echo "Executable" || echo "Not executable"

# Find files with specific permissions
find /path -perm 777 -type f
find /path -user username
find /path -group groupname

Common Problems and Solutions

Permission Denied Errors

Problem: Cannot access file despite being owner:

# Check for immutable attribute
lsattr file.txt

# Remove immutable attribute if set
sudo chattr -i file.txt

Problem: Cannot execute script:

# Add execute permission
chmod +x script.sh

# Check shebang line
head -1 script.sh

# Verify interpreter exists
which bash

Group Membership Not Working

Problem: Added to group but permissions not working:

# Logout and login, or use:
newgrp groupname

# Verify group membership
groups

# Check group ID
id -Gn

Web Server Permission Issues

# Standard web directory permissions
sudo chown -R www-data:www-data /var/www/html
sudo find /var/www/html -type d -exec chmod 755 {} \;
sudo find /var/www/html -type f -exec chmod 644 {} \;

# For upload directories
sudo chmod 775 /var/www/html/uploads
sudo chown www-data:developers /var/www/html/uploads

SSH Key Permissions

# Fix SSH directory permissions
chmod 700 ~/.ssh
chmod 600 ~/.ssh/id_rsa
chmod 600 ~/.ssh/authorized_keys
chmod 644 ~/.ssh/id_rsa.pub

Automation and Scripting User Management

Shell Scripts for User Management

Automated User Provisioning Script

#!/bin/bash
# provision_user.sh

create_user() {
    local username=$1
    local fullname=$2
    local groups=$3
    
    # Check if user exists
    if id "$username" &>/dev/null; then
        echo "User $username already exists"
        return 1
    fi
    
    # Create user
    sudo useradd -m -c "$fullname" -s /bin/bash "$username"
    
    # Set temporary password
    echo "$username:ChangeMe123!" | sudo chpasswd
    
    # Force password change on first login
    sudo chage -d 0 "$username"
    
    # Add to groups
    if [ -n "$groups" ]; then
        sudo usermod -aG "$groups" "$username"
    fi
    
    # Create SSH directory
    sudo -u "$username" mkdir -p /home/"$username"/.ssh
    sudo chmod 700 /home/"$username"/.ssh
    
    echo "User $username created successfully"
}

# Usage
create_user "john" "John Doe" "developers,docker"

Bulk Permission Change Script

#!/bin/bash
# fix_permissions.sh

fix_directory_permissions() {
    local dir=$1
    local dir_perms=${2:-755}
    local file_perms=${3:-644}
    
    echo "Fixing permissions in $dir"
    
    # Set directory permissions
    find "$dir" -type d -exec chmod "$dir_perms" {} \;
    
    # Set file permissions
    find "$dir" -type f -exec chmod "$file_perms" {} \;
    
    echo "Permissions fixed"
}

# Usage
fix_directory_permissions "/var/www/html" 755 644

User Audit Script

#!/bin/bash
# audit_users.sh

echo "User Audit Report - $(date)"
echo "================================"

# List users with UID >= 1000 (regular users)
echo -e "\nRegular Users:"
awk -F: '$3 >= 1000 {print $1 " (UID: " $3 ")"}' /etc/passwd

# Find users with no password expiry
echo -e "\nUsers with no password expiry:"
for user in $(awk -F: '$3 >= 1000 {print $1}' /etc/passwd); do
    chage -l "$user" | grep -q "Password expires.*never" && echo "$user"
done

# Find users with sudo access
echo -e "\nUsers with sudo access:"
grep -Po '^[^#]*\K^[^:]+' /etc/group | grep sudo

# Last login information
echo -e "\nLast login times:"
lastlog | grep -v "Never logged in"

Configuration Management Tools

Ansible User Management

# ansible_users.yml
---
- name: Manage Linux users
  hosts: all
  become: yes
  vars:
    users:
      - name: john
        groups: ['developers', 'docker']
        shell: /bin/bash
        password: "{{ 'password123' | password_hash('sha512') }}"
      - name: jane
        groups: ['admins']
        shell: /bin/zsh
        
  tasks:
    - name: Create users
      user:
        name: "{{ item.name }}"
        groups: "{{ item.groups }}"
        shell: "{{ item.shell }}"
        password: "{{ item.password }}"
        create_home: yes
        state: present
      loop: "{{ users }}"
      
    - name: Add SSH keys
      authorized_key:
        user: "{{ item.name }}"
        key: "{{ lookup('file', 'keys/{{ item.name }}.pub') }}"
        state: present
      loop: "{{ users }}"

Best Practices and Enterprise Considerations

Security Guidelines

Principle of Least Privilege

  • Grant minimum permissions required for tasks
  • Use groups for role-based access
  • Regular permission audits
  • Document permission changes
# Example least privilege setup
# Create role-based groups
sudo groupadd web-developers
sudo groupadd database-admins
sudo groupadd deployment-users

# Assign specific permissions
sudo setfacl -R -m g:web-developers:rwx /var/www/dev
sudo setfacl -R -m g:database-admins:r-x /var/lib/mysql
sudo setfacl -R -m g:deployment-users:r-x /opt/applications

Regular User Audits

# Schedule regular audits with cron
# Add to root's crontab
0 2 * * 1 /usr/local/bin/audit_users.sh > /var/log/user_audit.log 2>&1

# Check for inactive users
lastlog -b 90  # Users inactive for 90+ days

# Review sudo usage
sudo grep sudo /var/log/auth.log | tail -50

Compliance and Auditing

Audit Configuration with auditd

# Install auditd
sudo apt-get install auditd

# Monitor user/group changes
sudo auditctl -w /etc/passwd -p wa -k passwd_changes
sudo auditctl -w /etc/shadow -p wa -k shadow_changes
sudo auditctl -w /etc/group -p wa -k group_changes

# Monitor sudo commands
sudo auditctl -w /usr/bin/sudo -p x -k sudo_commands

# View audit logs
sudo aureport -au  # Authentication report
sudo aureport -m   # Modifications report
sudo ausearch -k passwd_changes  # Search specific events

Quick Reference and Cheat Sheet

Essential Commands Quick Reference

Task Command
Create user sudo useradd -m username
Delete user sudo userdel -r username
Change password sudo passwd username
Add to group sudo usermod -aG groupname username
Create group sudo groupadd groupname
Change permissions chmod 755 filename
Change ownership sudo chown user:group filename
Set ACL setfacl -m u:username:rwx filename
View permissions ls -la filename
Check user info id username

Common Permission Combinations

Numeric Symbolic Use Case
755 rwxr-xr-x Executable files, directories
644 rw-r–r– Regular files
600 rw——- Private files
700 rwx—— Private directories
775 rwxrwxr-x Shared directories
664 rw-rw-r– Shared files

Troubleshooting Flowchart

  1. Permission Denied?
    • Check file ownership: ls -la
    • Check user groups: groups
    • Check ACLs: getfacl filename
    • Check parent directory permissions
  2. Cannot Execute?
    • Check execute bit: ls -la
    • Verify shebang: head -1 script
    • Check interpreter: which interpreter
  3. Group Permissions Not Working?
    • Verify group membership: id username
    • Re-login or use: newgrp groupname
    • Check primary vs supplementary groups

Conclusion and Next Steps

This guide covered essential Linux user management and permission concepts. You learned how to:

  • Create and manage users and groups effectively
  • Configure file permissions and ownership
  • Implement ACLs for fine-grained access control
  • Set up sudo access and privilege escalation
  • Automate user provisioning with scripts
  • Troubleshoot common permission issues

Next Steps for Learning

  1. Practice in a lab environment: Set up a virtual machine to test commands safely
  2. Implement automation: Create scripts for your common tasks
  3. Study advanced topics:
    • SELinux/AppArmor for mandatory access control
    • LDAP/Active Directory integration
    • Kerberos authentication
    • PAM module configuration
  4. Security certifications: Consider Linux+ or RHCSA certification

Remember: Always test permission changes in a development environment before applying them to production systems. Document all changes and maintain regular backups.

If you have MikroTik network equipment, feel free to check our list of MikroTik guides.

Similar Posts

Leave a Reply

Your email address will not be published. Required fields are marked *