Effective user and permission management forms the foundation of Linux security on CentOS Stream (aligned with RHEL 9/10). The goal is principle of least privilege — grant only the access needed, use groups for scalability, enforce strong authentication, and audit regularly.
1. Core Philosophy & Defaults in CentOS Stream
- Never log in or run services as root remotely — disable direct root SSH login.
- Use the wheel group for sudo privileges (traditional Red Hat convention).
- Prefer groups over individual permissions — easier to onboard/offboard users.
- SELinux remains enforcing — it adds mandatory access control; user/group changes must respect contexts.
- Password policies are weak by default — tighten them immediately.
2. Creating & Managing Users (Best Practices)
- Create standard users (never root-equivalent accounts): Use useradd with sane defaults: home directory, shell, group. Modern pattern:
- sudo useradd -m -s /bin/bash -c “Full Name” username
- Immediately set strong password: sudo passwd username
- Service accounts (for daemons like nginx, docker): Use system users (–system flag) with no login shell (–shell /usr/sbin/nologin) and no home directory. Example: sudo useradd -r -s /usr/sbin/nologin -c “Nginx user” nginx
- Lock & expire inactive accounts: sudo usermod -L username (lock) sudo chage -E 0 username (expire immediately) sudo chage -M 90 -W 14 username (password expires every 90 days, warn 14 days before)
3. Group Management – The Scalable Way
Groups simplify permission delegation.
Role-based groups (recommended):
- webadmins for Nginx/Apache users
- dbadmins for MariaDB/PostgreSQL
- devops for Ansible/automation accounts
- monitoring for Prometheus/Grafana agents
Create: sudo groupadd webadmins Add user: sudo usermod -aG webadmins username (always -a to append!)
Primary vs secondary groups: Primary group (from /etc/passwd) owns new files. Use secondary groups (-aG) for access without changing ownership.
Shared directories (common for teams): Set group ownership + setgid bit: sudo chown -R :webadmins /var/www/projects sudo chmod -R g+rwxs /var/www/projects New files inherit group automatically.
4. sudo Configuration – Secure & Granular
Always edit with visudo (syntax checking + safe editor).
- Default pattern (wheel group): Uncomment or ensure: %wheel ALL=(ALL) ALL or better (require password): %wheel ALL=(ALL) ALL
- Passwordless sudo for specific commands (automation scripts): In /etc/sudoers.d/ansible (create drop-in file): ansible ALL=(ALL) NOPASSWD: /usr/bin/ansible-pull, /usr/bin/systemctl restart nginx
- Command restrictions (high security): dbadmin ALL=(ALL) /usr/bin/mariadb, /usr/bin/mysqladmin No shell access, only DB tools.
- Logging & timeouts: Add to /etc/sudoers: Defaults logfile=”/var/log/sudo.log”Defaults timestamp_timeout=15 (minutes)
5. File & Directory Permissions – Practical Rules
- Umask 027 (group-writable, no world access) — set globally in /etc/profile or per-user .bash_profile.
- Common patterns:
- Config files: 640 (owner rw, group r)
- Scripts/executables: 750 or 755
- Secrets (keys, certs): 600, owned by service user
- Find risky permissions: Regularly scan: find / -perm -o+w -type f 2>/dev/null (world-writable files) find /etc -perm /6000 (SUID/SGID binaries)
6. Password & Account Policies (PAM)
Edit /etc/security/pwquality.conf:
- minlen = 14
- dcredit = -1 (require digit)
- ucredit = -1, lcredit = -1, ocredit = -1
In /etc/login.defs:
- PASS_MAX_DAYS 90
- PASS_MIN_DAYS 7
- PASS_WARN_AGE 14
Enable faillock (lock after failed attempts): Install if needed: sudo dnf install pam_faillock Configure in /etc/pam.d/password-auth and /etc/pam.d/system-auth.
7. Auditing & Monitoring Essentials
- auditd rules for privileged actions: Monitor sudo usage, user creation, group changes: -w /etc/sudoers -p wa -k identity-a always,exit -F path=/usr/sbin/useradd -F perm=x -k user_mgmt
- Lastlog & wtmp: last / lastlog to review logins. sudo journalctl -u sshd for brute-force attempts.
- Remove unused accounts: sudo userdel -r olduser (removes home dir) Audit periodically: awk -F: ‘$3 >= 1000 {print $1}’ /etc/passwd (normal users)
Quick Best-Practice Checklist (Production Server)
- Disable root SSH login (PermitRootLogin no in sshd_config)
- Create sudo user in wheel group on day 1
- Use role-based groups (not per-user perms)
- Enforce password complexity & expiration
- Use drop-in sudoers.d files for organization
- Set umask 027 globally
- Audit SUID/SGID binaries & world-writable files monthly
- Monitor sudo.log & audit logs
- Lock/disable inactive accounts after 30–90 days
- Test offboarding: delete user, verify no lingering processes/files
This approach scales from single servers to fleets managed by Ansible (use ansible.posix.authorized_key, user, group, lineinfile for sudoers). For enterprise environments, consider FreeIPA or SSSD + AD/LDAP integration for centralized control.