User Account Security - Least Privilege and Access Control

Resource Navigation: README | Password Management | SSH Security Hardening | Two-Factor Authentication


Summary

User account security is the foundation of system security - every breach starts with compromised credentials or excessive privileges. This comprehensive guide covers creating secure user accounts with minimum necessary permissions, implementing sudo access control with fine-grained rules, configuring PAM (Pluggable Authentication Modules) for password policies and account restrictions, setting up centralized authentication with LDAP/FreeIPA, implementing role-based access control (RBAC), auditing user activity, automated account provisioning and deprovisioning, session management, and compliance with security frameworks. Learn production patterns for multi-user systems, jump hosts, development environments, and enterprise infrastructure with complete audit trails and least-privilege enforcement.

The Golden Rule: Grant minimum permissions necessary for each user's role; review access regularly.


Learning Objectives

By the end of this guide, you will be able to:


Prerequisites

Before implementing user account security, you should have:


User Account Fundamentals

User Types

Root (UID 0):

System Users (UID 1-999):

Regular Users (UID 1000+):

Service Accounts (application-specific):

User Information Files

# /etc/passwd - User account information
# Format: username:x:UID:GID:comment:homedir:shell
root:x:0:0:root:/root:/bin/bash
alice:x:1000:1000:Alice Admin:/home/alice:/bin/bash
bob:x:1001:1001:Bob Developer:/home/bob:/bin/bash
nginx:x:33:33:www-data:/var/www:/usr/sbin/nologin

# /etc/shadow - Encrypted passwords and aging
# Format: username:password:lastchange:min:max:warn:inactive:expire
alice:$6$rounds=5000$...:19000:0:90:7:30:

# /etc/group - Group memberships
# Format: groupname:x:GID:members
sudo:x:27:alice,bob
docker:x:999:alice

# /etc/gshadow - Group passwords (rarely used)
sudo:*::alice,bob

Creating Secure User Accounts

Basic User Creation

# Create user
sudo useradd -m -s /bin/bash alice

# Set password
sudo passwd alice

# Create user with all options
sudo useradd \
    --create-home \
    --shell /bin/bash \
    --comment "Alice Admin - DevOps Team" \
    --expiredate 2026-12-31 \
    --groups sudo,docker \
    alice

# Set secure password
sudo passwd alice

User Creation Best Practices

#!/bin/bash
# create-user.sh - Secure user creation script

USERNAME="$1"
FULLNAME="$2"
EXPIRE_DATE="$3"  # Optional: YYYY-MM-DD

if [ -z "$USERNAME" ] || [ -z "$FULLNAME" ]; then
    echo "Usage: $0 <username> <fullname> [expire-date]"
    exit 1
fi

# Create user with secure defaults
sudo useradd \
    --create-home \
    --shell /bin/bash \
    --comment "$FULLNAME" \
    --groups users \
    ${EXPIRE_DATE:+--expiredate $EXPIRE_DATE} \
    "$USERNAME"

# Set password (force change on first login)
sudo passwd --expire "$USERNAME"

# Set strict home directory permissions
sudo chmod 750 "/home/$USERNAME"

# Create .ssh directory with proper permissions
sudo mkdir -p "/home/$USERNAME/.ssh"
sudo chmod 700 "/home/$USERNAME/.ssh"
sudo touch "/home/$USERNAME/.ssh/authorized_keys"
sudo chmod 600 "/home/$USERNAME/.ssh/authorized_keys"
sudo chown -R "$USERNAME:$USERNAME" "/home/$USERNAME/.ssh"

# Send welcome email (optional)
# echo "Welcome!" | mail -s "Account Created" "$USERNAME@example.com"

echo "User $USERNAME created successfully"
echo "Password must be changed on first login"
echo "SSH key can be added to: /home/$USERNAME/.ssh/authorized_keys"

Service Account Creation

# Create service account (no login)
sudo useradd \
    --system \
    --no-create-home \
    --shell /usr/sbin/nologin \
    --comment "MyApp Service Account" \
    myapp

# Create with home directory (for application data)
sudo useradd \
    --system \
    --create-home \
    --home-dir /var/lib/myapp \
    --shell /usr/sbin/nologin \
    --comment "MyApp Service" \
    myapp

# Set ownership for application directories
sudo mkdir -p /var/log/myapp /var/lib/myapp
sudo chown -R myapp:myapp /var/log/myapp /var/lib/myapp
sudo chmod 750 /var/log/myapp /var/lib/myapp

Sudo Configuration

Understanding Sudo

┌──────────────────────────────────────────┐
│            User: alice                    │
│         (Regular User)                    │
└──────────────┬───────────────────────────┘
               │
               │ sudo systemctl restart nginx
               ↓
    ┌────────────────────────┐
    │    Check /etc/sudoers   │
    │    Is alice allowed?    │
    └────────────┬───────────┘
                 │
           Yes   │
                 ↓
    ┌────────────────────────┐
    │   Prompt for password   │
    │   (alice's password)    │
    └────────────┬───────────┘
                 │
           Valid │
                 ↓
    ┌────────────────────────┐
    │   Execute as root:      │
    │   systemctl restart     │
    │   nginx                 │
    └────────────────────────┘

Basic Sudo Access

# Add user to sudo group (Debian/Ubuntu)
sudo usermod -aG sudo alice

# Add user to wheel group (RHEL/CentOS)
sudo usermod -aG wheel alice

# Verify groups
groups alice

# Test sudo access
su - alice
sudo whoami  # Should output: root

Sudoers File Configuration

# NEVER edit /etc/sudoers directly!
# Always use visudo (validates syntax)
sudo visudo

# Default sudoers configuration
# /etc/sudoers

# Allow sudo group members to run any command
%sudo   ALL=(ALL:ALL) ALL

# Allow wheel group (RHEL)
%wheel  ALL=(ALL:ALL) ALL

# Syntax: WHO WHERE=(AS_WHO) WHAT
# WHO: User or %group
# WHERE: Hosts (ALL = all hosts)
# AS_WHO: Run as user:group (ALL:ALL = any user/group)
# WHAT: Commands (ALL = any command)

Fine-Grained Sudo Rules

# /etc/sudoers.d/custom-rules
# (Create separate files in sudoers.d/)

# Allow alice to restart nginx without password
alice ALL=(ALL) NOPASSWD: /usr/bin/systemctl restart nginx

# Allow webadmin group to manage web services
%webadmin ALL=(ALL) NOPASSWD: /usr/bin/systemctl restart nginx, \
                               /usr/bin/systemctl reload nginx, \
                               /usr/bin/systemctl status nginx, \
                               /usr/bin/systemctl restart apache2

# Allow dbadmin to manage databases
%dbadmin ALL=(postgres) NOPASSWD: /usr/bin/psql, \
                                   /usr/bin/pg_dump

# Allow developers to read logs (no password)
%developers ALL=(ALL) NOPASSWD: /usr/bin/tail -f /var/log/myapp/*.log, \
                                /usr/bin/less /var/log/myapp/*.log, \
                                /usr/bin/grep * /var/log/myapp/*.log

# Restrict to specific hosts
alice webserver1,webserver2=(ALL) ALL

# Allow user to run commands as specific user
deployer ALL=(www-data) NOPASSWD: /usr/local/bin/deploy.sh

# Require password for dangerous commands
%operators ALL=(ALL) /usr/bin/systemctl restart *, \
                     /usr/bin/reboot

# Disable specific commands
alice ALL=(ALL) ALL, !/usr/bin/passwd root, !/usr/bin/su root

Sudo Aliases for Complex Rules

# /etc/sudoers.d/aliases

# Command aliases
Cmnd_Alias WEB_RESTART = /usr/bin/systemctl restart nginx, \
                         /usr/bin/systemctl reload nginx
Cmnd_Alias DB_ADMIN = /usr/bin/psql, /usr/bin/pg_dump, \
                      /usr/bin/pg_restore
Cmnd_Alias LOG_READ = /usr/bin/tail, /usr/bin/less, \
                      /usr/bin/grep, /usr/bin/cat

# User aliases
User_Alias WEBADMINS = alice, bob, charlie
User_Alias DBADMINS = dave, eve

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

# Use aliases in rules
WEBADMINS WEBSERVERS=(ALL) NOPASSWD: WEB_RESTART
DBADMINS DBSERVERS=(postgres) NOPASSWD: DB_ADMIN

Sudo Security Options

# /etc/sudoers

# Require password (default)
Defaults    authenticate

# Password timeout (minutes)
Defaults    timestamp_timeout=5

# Require password every time (no timeout)
Defaults    timestamp_timeout=0

# Log all sudo commands
Defaults    log_input, log_output
Defaults    logfile="/var/log/sudo.log"

# Send email on sudo use
Defaults    mail_always
Defaults    mailto="security@example.com"

# Restrict environment variables (security)
Defaults    env_reset
Defaults    env_keep="COLORS DISPLAY HOSTNAME HISTSIZE KDEDIR LS_COLORS"
Defaults    env_keep+="MAIL PS1 PS2 QTDIR USERNAME LANG LC_ADDRESS LC_CTYPE"

# Require sudo to preserve environment
Defaults    !setenv

# Lecture users on first sudo use
Defaults    lecture="always"

# Use custom insults on wrong password (fun but professional?)
Defaults    insults

# Require root password instead of user password
Defaults    rootpw

# SELinux support
Defaults    use_pty
Defaults    setype=unconfined_t

PAM (Pluggable Authentication Modules)

PAM Configuration Files

# PAM configuration directory
/etc/pam.d/

# Common PAM files:
/etc/pam.d/common-auth       # Authentication
/etc/pam.d/common-account    # Account validation
/etc/pam.d/common-password   # Password changing
/etc/pam.d/common-session    # Session setup
/etc/pam.d/sshd              # SSH authentication
/etc/pam.d/sudo              # Sudo authentication
/etc/pam.d/login             # Console login

# PAM module syntax:
# type  control  module  arguments

Password Quality Requirements

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

# Configure password requirements
sudo nano /etc/security/pwquality.conf

# /etc/security/pwquality.conf
# Minimum password length
minlen = 14

# Require at least one digit
dcredit = -1

# Require at least one uppercase
ucredit = -1

# Require at least one lowercase
lcredit = -1

# Require at least one special character
ocredit = -1

# Maximum consecutive repeated characters
maxrepeat = 3

# Maximum consecutive characters from same class
maxclassrepeat = 4

# Minimum different characters from old password
difok = 5

# Check against dictionary
dictcheck = 1

# Reject usernames in passwords
usercheck = 1

# Reject passwords containing username
gecoscheck = 1

# Enable in PAM
# /etc/pam.d/common-password
password  requisite  pam_pwquality.so retry=3

Password Aging

# Set password aging for new users
sudo nano /etc/login.defs

# /etc/login.defs
PASS_MAX_DAYS   90      # Password expires after 90 days
PASS_MIN_DAYS   7       # Can't change password for 7 days
PASS_WARN_AGE   14      # Warn 14 days before expiration

# Set for existing user
sudo chage alice
# Or with flags:
sudo chage -M 90 -m 7 -W 14 alice

# View password status
sudo chage -l alice

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

# Set account expiration
sudo chage -E 2026-12-31 alice

# Lock account after 30 days of inactivity
sudo chage -I 30 alice

Account Lockout (Failed Login Attempts)

# Configure account lockout
sudo nano /etc/pam.d/common-auth

# /etc/pam.d/common-auth
# Lock account after 5 failed attempts for 10 minutes
auth required pam_tally2.so deny=5 unlock_time=600 onerr=fail audit

# Or use faillock (newer)
auth required pam_faillock.so preauth silent audit deny=5 unlock_time=600
auth [default=die] pam_faillock.so authfail audit deny=5 unlock_time=600
auth sufficient pam_unix.so nullok try_first_pass
auth requisite pam_deny.so

# Account validation
account required pam_faillock.so

# View failed attempts
sudo faillock --user alice

# Unlock user manually
sudo faillock --user alice --reset

# View all locked accounts
sudo faillock

Time-Based Access Restrictions

# Restrict login times
sudo nano /etc/security/time.conf

# /etc/security/time.conf
# Format: services;ttys;users;times

# Allow alice login only during business hours
login;*;alice;Mo-Fr0800-1800

# Allow after-hours access for oncall group
login;*;%oncall;Al0000-2400

# Restrict SSH to specific hours
sshd;*;*;!Al1800-0800

# Enable in PAM
# /etc/pam.d/common-account
account  required  pam_time.so

Access Control Lists

# Configure user access restrictions
sudo nano /etc/security/access.conf

# /etc/security/access.conf
# Format: permission:users:origins

# Deny all except specific users from SSH
- : ALL EXCEPT alice bob : ALL

# Allow only from specific networks
+ : alice : 10.0.0.0/8 192.168.0.0/16
- : alice : ALL

# Allow root only from console
+ : root : LOCAL
- : root : ALL

# Deny specific user
- : baduser : ALL

# Enable in PAM
# /etc/pam.d/sshd
account  required  pam_access.so

Two-Factor Authentication (PAM)

# Install Google Authenticator PAM module
sudo apt install libpam-google-authenticator

# Configure for user
google-authenticator
# - Scan QR code with authenticator app
# - Save emergency codes
# - Answer configuration questions

# Enable in PAM
sudo nano /etc/pam.d/sshd

# /etc/pam.d/sshd (add at top)
auth required pam_google_authenticator.so

# Configure SSH to use PAM
sudo nano /etc/ssh/sshd_config

# /etc/ssh/sshd_config
ChallengeResponseAuthentication yes
UsePAM yes
AuthenticationMethods publickey,keyboard-interactive

# Restart SSH
sudo systemctl restart sshd

# See [SSH Security Hardening](ssh-security-hardening) for details

Centralized Authentication

LDAP Integration (Basic)

# Install LDAP client
sudo apt install libnss-ldap libpam-ldap ldap-utils

# Configure LDAP server connection
sudo nano /etc/ldap.conf

# /etc/ldap.conf
uri ldap://ldap.example.com
base dc=example,dc=com
ldap_version 3
binddn cn=readonly,dc=example,dc=com
bindpw readonly_password

# Configure NSS to use LDAP
sudo nano /etc/nsswitch.conf

# /etc/nsswitch.conf
passwd:         files ldap
group:          files ldap
shadow:         files ldap

# Configure PAM for LDAP
sudo pam-auth-update
# Enable "LDAP Authentication"

# Test LDAP connectivity
ldapsearch -x -H ldap://ldap.example.com -b "dc=example,dc=com"

# Create home directories automatically
sudo nano /etc/pam.d/common-session

# Add:
session required pam_mkhomedir.so skel=/etc/skel umask=0077

FreeIPA Integration

# Install FreeIPA client
sudo apt install freeipa-client

# Join FreeIPA domain
sudo ipa-client-install \
    --domain=example.com \
    --server=ipa.example.com \
    --realm=EXAMPLE.COM \
    --principal=admin \
    --password='IPA_ADMIN_PASSWORD' \
    --mkhomedir \
    --unattended

# Test FreeIPA authentication
kinit admin
klist

# List IPA users
ipa user-find

# Add sudo rules from FreeIPA
sudo ipa sudorule-show webadmins

# Automatic home directory creation enabled
# Sudo rules managed centrally in FreeIPA

Active Directory Integration

# Install required packages
sudo apt install realmd sssd sssd-tools adcli krb5-user

# Discover AD domain
sudo realm discover example.com

# Join AD domain
sudo realm join --user=Administrator example.com

# Configure home directories
sudo nano /etc/sssd/sssd.conf

# /etc/sssd/sssd.conf
[sssd]
domains = example.com
config_file_version = 2
services = nss, pam

[domain/example.com]
default_shell = /bin/bash
krb5_store_password_if_offline = True
cache_credentials = True
krb5_realm = EXAMPLE.COM
realmd_tags = manages-system joined-with-adcli
id_provider = ad
fallback_homedir = /home/%u@%d
ad_domain = example.com
use_fully_qualified_names = False
ldap_id_mapping = True
access_provider = ad

# Restart SSSD
sudo systemctl restart sssd

# Test AD authentication
id 'alice@example.com'
su - alice

# Configure sudo for AD groups
sudo visudo

%Domain\ Admins ALL=(ALL) ALL

Auditing and Monitoring

Audit User Activity (auditd)

# Install audit daemon
sudo apt install auditd audispd-plugins

# Configure audit rules
sudo nano /etc/audit/rules.d/user-activity.rules

# /etc/audit/rules.d/user-activity.rules

# Audit all commands executed by users
-a always,exit -F arch=b64 -S execve -k user_commands
-a always,exit -F arch=b32 -S execve -k user_commands

# Audit sudo usage
-a always,exit -F path=/usr/bin/sudo -F perm=x -k sudo_usage

# Audit user additions/removals
-w /usr/sbin/useradd -p x -k user_modification
-w /usr/sbin/userdel -p x -k user_modification
-w /usr/sbin/usermod -p x -k user_modification
-w /etc/passwd -p wa -k passwd_changes
-w /etc/shadow -p wa -k shadow_changes
-w /etc/group -p wa -k group_changes
-w /etc/gshadow -p wa -k gshadow_changes

# Audit SSH logins
-w /var/log/auth.log -p wa -k auth_log_changes

# Audit file access by specific user
-a always,exit -F arch=b64 -S open -S openat -F auid=1000 -k alice_file_access

# Make rules immutable (can't be changed without reboot)
-e 2

# Reload rules
sudo augenrules --load

# Restart auditd
sudo systemctl restart auditd

# Search audit logs
sudo ausearch -k user_commands --start recent
sudo ausearch -k sudo_usage -i

# Generate audit report
sudo aureport --summary
sudo aureport --auth --summary
sudo aureport --executable --summary

Session Recording (tlog)

# Install tlog for session recording
sudo apt install tlog

# Configure for specific users
sudo nano /etc/tlog/tlog-rec-session.conf

# Record all sessions for users in 'recorded' group
# Create group
sudo groupadd recorded
sudo usermod -aG recorded alice

# Configure PAM to use tlog
sudo nano /etc/pam.d/system-auth

# Add before pam_unix.so:
session required pam_exec.so seteuid /usr/bin/tlog-rec-session

# View recorded sessions
sudo journalctl -o verbose --output-fields=MESSAGE TLOG_REC

# Play back session
sudo tlog-play -r journal -M TLOG_REC=<session-id>

Monitoring Active Users

# Show logged-in users
w
who
users

# Show last logins
last
last alice
lastlog

# Show failed login attempts
lastb
sudo lastb

# Show current user sessions
loginctl list-sessions
loginctl show-session <session-id>

# Monitor in real-time
watch -n 5 'w'

# Monitoring script
#!/bin/bash
# monitor-users.sh

while true; do
    clear
    echo "=== Active Users ==="
    w
    echo
    echo "=== Recent Logins ==="
    last -n 10
    echo
    echo "=== Failed Logins ==="
    sudo lastb -n 5
    sleep 30
done

User Provisioning Automation

Ansible User Management

# users.yml - Ansible playbook for user management

---
- name: Manage users
  hosts: all
  become: yes
  
  vars:
    users:
      - name: alice
        fullname: "Alice Admin"
        groups: ["sudo", "docker"]
        ssh_key: "ssh-rsa AAAAB3NzaC1yc2E..."
        state: present
      
      - name: bob
        fullname: "Bob Developer"
        groups: ["docker"]
        ssh_key: "ssh-rsa AAAAB3NzaC1yc2E..."
        state: present
      
      - name: olduser
        state: absent  # Remove user
  
  tasks:
    - name: Manage user accounts
      user:
        name: "{{ item.name }}"
        comment: "{{ item.fullname | default('') }}"
        groups: "{{ item.groups | default([]) }}"
        append: yes
        create_home: yes
        shell: /bin/bash
        state: "{{ item.state }}"
      loop: "{{ users }}"
    
    - name: Set up SSH keys
      authorized_key:
        user: "{{ item.name }}"
        key: "{{ item.ssh_key }}"
        state: present
      loop: "{{ users }}"
      when: item.state == "present" and item.ssh_key is defined
    
    - name: Configure sudo access
      template:
        src: sudoers.j2
        dest: "/etc/sudoers.d/{{ item.name }}"
        mode: '0440'
        validate: 'visudo -cf %s'
      loop: "{{ users }}"
      when: "'sudo' in item.groups"

User Onboarding Script

#!/bin/bash
# onboard-user.sh - Complete user onboarding

set -e

USERNAME="$1"
FULLNAME="$2"
EMAIL="$3"
ROLE="$4"  # developer, sysadmin, readonly

if [ $# -ne 4 ]; then
    echo "Usage: $0 <username> <fullname> <email> <role>"
    echo "Roles: developer, sysadmin, readonly"
    exit 1
fi

echo "=== Onboarding User: $USERNAME ==="

# Create user
sudo useradd \
    --create-home \
    --shell /bin/bash \
    --comment "$FULLNAME - $EMAIL" \
    "$USERNAME"

# Set temporary password (expires immediately)
TEMP_PASS=$(openssl rand -base64 12)
echo "$USERNAME:$TEMP_PASS" | sudo chpasswd
sudo chage -d 0 "$USERNAME"

# Assign groups based on role
case "$ROLE" in
    sysadmin)
        sudo usermod -aG sudo,docker,adm "$USERNAME"
        ;;
    developer)
        sudo usermod -aG docker "$USERNAME"
        ;;
    readonly)
        sudo usermod -aG adm "$USERNAME"
        ;;
    *)
        echo "Unknown role: $ROLE"
        exit 1
        ;;
esac

# Create SSH directory
sudo mkdir -p "/home/$USERNAME/.ssh"
sudo chmod 700 "/home/$USERNAME/.ssh"
sudo touch "/home/$USERNAME/.ssh/authorized_keys"
sudo chmod 600 "/home/$USERNAME/.ssh/authorized_keys"
sudo chown -R "$USERNAME:$USERNAME" "/home/$USERNAME/.ssh"

# Create sudo rules
if [ "$ROLE" == "sysadmin" ]; then
    echo "$USERNAME ALL=(ALL) ALL" | sudo tee "/etc/sudoers.d/$USERNAME"
    sudo chmod 440 "/etc/sudoers.d/$USERNAME"
fi

# Send welcome email
cat <<EOF | mail -s "Welcome to the Team!" "$EMAIL"
Hello $FULLNAME,

Your account has been created:
Username: $USERNAME
Temporary Password: $TEMP_PASS

You'll be required to change your password on first login.

Please add your SSH public key to: ~/.ssh/authorized_keys

Documentation: https://docs.example.com/onboarding

Regards,
IT Team
EOF

echo "=== User $USERNAME created successfully ==="
echo "Temporary password: $TEMP_PASS"
echo "Password expires on first login"
echo "Role: $ROLE"

User Offboarding Script

#!/bin/bash
# offboard-user.sh - Complete user offboarding

set -e

USERNAME="$1"

if [ -z "$USERNAME" ]; then
    echo "Usage: $0 <username>"
    exit 1
fi

echo "=== Offboarding User: $USERNAME ==="

# Lock account immediately
sudo usermod -L "$USERNAME"
echo "✓ Account locked"

# Expire account
sudo chage -E 0 "$USERNAME"
echo "✓ Account expired"

# Kill all user processes
sudo pkill -KILL -u "$USERNAME" || true
echo "✓ Processes terminated"

# Backup home directory
BACKUP_DIR="/backup/offboarded-users"
sudo mkdir -p "$BACKUP_DIR"
sudo tar -czf "$BACKUP_DIR/$USERNAME-$(date +%Y%m%d).tar.gz" "/home/$USERNAME"
echo "✓ Home directory backed up"

# Remove from all groups except primary
USER_GROUPS=$(groups "$USERNAME" | cut -d: -f2)
for group in $USER_GROUPS; do
    if [ "$group" != "$USERNAME" ]; then
        sudo gpasswd -d "$USERNAME" "$group" || true
    fi
done
echo "✓ Removed from supplementary groups"

# Remove sudo access
sudo rm -f "/etc/sudoers.d/$USERNAME"
echo "✓ Sudo access removed"

# Archive SSH keys
sudo cp "/home/$USERNAME/.ssh/authorized_keys" "$BACKUP_DIR/$USERNAME-ssh-keys-$(date +%Y%m%d).txt" || true
echo "✓ SSH keys archived"

# Remove from LDAP/FreeIPA (if applicable)
# ipa user-disable "$USERNAME"

# Log offboarding
logger "User $USERNAME offboarded on $(date) by $(whoami)"

echo "=== User $USERNAME offboarded successfully ==="
echo "Backup location: $BACKUP_DIR/$USERNAME-$(date +%Y%m%d).tar.gz"
echo ""
echo "To completely remove user:"
echo "  sudo userdel -r $USERNAME"

Role-Based Access Control (RBAC)

Define Roles

# /etc/security/roles.conf - Document roles

# Roles:
# 1. System Administrator (sysadmin)
#    - Full sudo access
#    - All servers
#    - Groups: sudo, docker, adm

# 2. Developer (developer)
#    - Limited sudo (restart services)
#    - Dev/staging servers only
#    - Groups: docker, developers

# 3. Database Administrator (dbadmin)
#    - Database servers only
#    - Run as postgres user
#    - Groups: dbadmin

# 4. Read-Only Auditor (auditor)
#    - View logs and configs
#    - No write access
#    - Groups: adm

# 5. Application Deployer (deployer)
#    - Deploy applications
#    - Restart app services
#    - Groups: deployers

Implement RBAC with Sudo

# /etc/sudoers.d/rbac-rules

# System Administrators (full access)
%sudo ALL=(ALL:ALL) ALL

# Developers (restart services, view logs)
Cmnd_Alias DEV_COMMANDS = /usr/bin/systemctl restart myapp, \
                          /usr/bin/systemctl status *, \
                          /usr/bin/docker ps, \
                          /usr/bin/docker logs *
%developers ALL=(ALL) NOPASSWD: DEV_COMMANDS

# Database Administrators
Cmnd_Alias DB_COMMANDS = /usr/bin/psql, /usr/bin/pg_dump, \
                         /usr/bin/systemctl restart postgresql
%dbadmin ALL=(postgres) NOPASSWD: DB_COMMANDS

# Auditors (read-only)
Cmnd_Alias AUDIT_COMMANDS = /usr/bin/tail -f /var/log/*, \
                            /usr/bin/less /var/log/*, \
                            /usr/bin/cat /etc/*
%auditor ALL=(ALL) NOPASSWD: AUDIT_COMMANDS

# Deployers
Cmnd_Alias DEPLOY_COMMANDS = /usr/local/bin/deploy.sh, \
                             /usr/bin/systemctl restart myapp
%deployers ALL=(www-data) NOPASSWD: DEPLOY_COMMANDS

RBAC with File Permissions

# Create role-based directories

# Developers can read/write app code
sudo mkdir -p /var/www/myapp
sudo chown -R :developers /var/www/myapp
sudo chmod -R 775 /var/www/myapp
sudo chmod g+s /var/www/myapp  # Set SGID

# DBAs can access database backups
sudo mkdir -p /backup/databases
sudo chown -R :dbadmin /backup/databases
sudo chmod 770 /backup/databases
sudo chmod g+s /backup/databases

# Auditors can read logs
sudo chown -R root:adm /var/log/myapp
sudo chmod -R 640 /var/log/myapp

Security Best Practices

User Account Security Checklist

☑ Root login disabled (SSH and console)
☑ Regular users use sudo for admin tasks
☑ Sudo configured with least privilege
☑ All sudo commands logged
☑ Strong password policy enforced (PAM)
☑ Password aging configured (90 days max)
☑ Account lockout after failed attempts
☑ Two-factor authentication enabled
☑ Service accounts have no login shell
☑ Unnecessary user accounts removed
☑ User home directories have strict permissions (700/750)
☑ SSH keys managed securely
☑ Centralized authentication (LDAP/FreeIPA) if multi-server
☑ Regular access reviews (quarterly)
☑ Audit logging enabled (auditd)
☑ Failed login attempts monitored
☑ Automated provisioning/deprovisioning
☑ Emergency access procedures documented
☑ Role-based access control implemented
☑ Principle of least privilege enforced

What's Next?

After implementing user account security:

Authentication:

Network Security:

Advanced Security:


Additional Resources

Official Documentation

Tutorials & Guides

Tools


Change Log

Choose Theme

Your selection is saved locally.

Neural Cacophony
Aperture v2
Flux v1
Mosaic Chaos
Nexus v1
Nexus Zest
Prism v2
Synapse