Unix account security: users, passwords, sudo and SSH keys

Updated November 2026

Most attacks on Unix systems go through an account: a guessed password, a stolen key or a forgotten user who left years ago. These steps make accounts much harder to abuse.

One account per person

Never share accounts. With shared logins you cannot tell who did what, and you cannot remove one person's access without changing everyone's password. Create a personal account for each user with useradd and give them only the groups they need.

sudo useradd -m -s /bin/bash -c "Maria Petrova" maria
sudo passwd maria
sudo chage -d 0 maria          # force a new password at first login

Use sudo instead of the root password

With sudo, administrators run privileged commands with their own password and every command is logged. Nobody needs to know the root password, which you can keep in a sealed envelope or a password safe for emergencies.

# Debian and Ubuntu use the "sudo" group, RHEL, Fedora and the BSDs use "wheel"
sudo usermod -aG sudo maria

# give a group limited rights in a separate file, always edited with visudo
sudo visudo -f /etc/sudoers.d/webteam
%webteam ALL=(root) /usr/bin/systemctl reload nginx, /usr/bin/journalctl -u nginx

Avoid NOPASSWD rules for people, and never allow editors, shells, less or find through sudo: each of them can start a root shell.

Check the account database

# only root may have user ID 0
awk -F: '$3 == 0 {print $1}' /etc/passwd

# accounts with empty password fields
sudo awk -F: '$2 == "" {print $1}' /etc/shadow

# human accounts (UID 1000 and up on Linux)
getent passwd | awk -F: '$3 >= 1000 && $3 < 60000 {print $1, $7}'

# when each user last logged in (lastlog2 replaces lastlog on newer distributions)
lastlog2 2>/dev/null || lastlog

# password ageing for one user
sudo chage -l maria

# check passwd and shadow for errors
sudo pwck -r

System accounts such as www-data or postgres should have the shell /usr/sbin/nologin and a locked password (! or * in /etc/shadow).

Password policy

Advice on passwords changed a lot in the last ten years. NIST Special Publication 800-63B, which many organisations follow, recommends:

On Linux these rules are set in PAM. Minimum length and dictionary checks come from pam_pwquality (/etc/security/pwquality.conf), lockout after failed attempts from pam_faillock (/etc/security/faillock.conf):

# /etc/security/pwquality.conf
minlen = 15
dictcheck = 1
usercheck = 1

# /etc/security/faillock.conf
deny = 5
unlock_time = 900

# show and reset failed attempts for a user
sudo faillock --user maria
sudo faillock --user maria --reset

On RHEL and Fedora enable faillock with sudo authselect enable-feature with-faillock. On Debian and Ubuntu there is no ready-made pam-auth-update profile for pam_faillock: add it to /etc/pam.d/common-auth and common-account by hand, following man pam_faillock. Editing PAM files is easy to get wrong, so keep a root session open while you test.

Multi-factor login

A second factor stops most password attacks. Options for Unix systems:

SSH keys

Keys are stronger than passwords, but they need care too.

# every authorised key on the system, with the account it opens
sudo find / -xdev -name authorized_keys -path '*/.ssh/*' -exec sh -c 'echo "== $1"; cat "$1"' _ {} \;

When someone leaves

Remove access on their last day, not when someone remembers.

sudo usermod -L -e 1 maria          # lock the password and expire the account
sudo rm /home/maria/.ssh/authorized_keys
sudo crontab -l -u maria            # check for scheduled jobs before deleting
sudo pkill -KILL -u maria           # end running sessions
# later, after handing over their files:
sudo userdel -r maria

Also remove them from sudoers files, VPN, the management network, shared password safes and any service accounts whose passwords they knew, and rotate those passwords.

Root's own environment