Accounts: passwd, shadow, groups
How Linux knows who you are.
A large office building does not really run on names. When you start, the security desk hands you a badge with a number baked into it, and from that moment every door you open, every entry in the log, every access rule is tied to that number. Your name is printed on the front so humans can read it. The machinery behind the doors only ever checks the number. Linux runs its accounts the same way.
That number is your UID (user ID, the plain integer the system uses to identify you), and every group has one too, its GID (group ID). When you try to read a file or start a program, the kernel (the core part of the operating system that talks straight to the hardware) compares your UID against the file's owner. It never looks at the word 'deploy' or 'alice'. The names are a convenience layer painted over the numbers so you do not have to memorize them.
One number is special. UID 0 is root, the superuser, the account that skips every permission check on the machine. root is the master key that opens every door in the building. This is worth burning in now: Linux treats you as all-powerful because your UID is 0, not because your name happens to be 'root'. Give any account UID 0 and it is root, no matter what you called it.
Where The Accounts Live: /etc/passwd
Every account on the machine is written down in one plain-text file, /etc/passwd. Treat it as the building's public staff directory: anyone can flip through it, because it holds no secrets, only the facts you need to look a person up. It is world-readable on purpose. Programs all over the system need to turn a UID back into a name, and they read this file to do it.
root:x:0:0:root:/root:/bin/bashdaemon:x:1:1:daemon:/usr/sbin:/usr/sbin/nologinwww-data:x:33:33:www-data:/var/www:/usr/sbin/nologinsshd:x:107:65534::/run/sshd:/usr/sbin/nologindeploy:x:1000:1000:Deploy User:/home/deploy:/bin/bash
Take the last line, split it on the colons, and you have read a whole account. Username (deploy). A lone 'x' where a password once sat. The UID (1000). The GID of the primary group (1000). A free-text comment field (its old name is GECOS, a historical label; these days it just holds the full name). The home directory (/home/deploy). And the login shell (/bin/bash), the program that starts when the person logs in. That 'x' is a signpost. Long ago the password hash lived right here in this world-readable file, so anyone could copy it and start guessing. Now the 'x' means the hash lives in /etc/shadow, look there instead.
Not every account belongs to a person. The programs that run your website, your database, and your SSH server (SSH, Secure Shell, the standard way to log into a machine over the network) each get their own account, so that if one is broken into the attacker lands as that limited user and not as root. A compromised web server should not be a compromised machine. Look at the daemon, www-data, and sshd lines above: their login shell is /usr/sbin/nologin, a tiny program whose only job is to refuse the login, print a short 'this account is currently not available', and exit. Those accounts can own files and run services, but nobody can open a shell as them. When you audit a box, a service account whose shell is /bin/bash instead of nologin is worth a hard second look. Someone may have quietly turned a dormant account into a way back in.
You do not have to read the raw file every time. getent (short for 'get entries') asks the system for one account record and hands it back in the same colon-separated format. It reads /etc/passwd, and on machines wired into a central company directory such as LDAP (Lightweight Directory Access Protocol, a network service that stores accounts in one shared place) it reads that too. Building the habit of getent over grepping the file means your commands keep working when the accounts move onto the network.
Where The Secrets Live: /etc/shadow
If /etc/passwd is the public directory, /etc/shadow is the locked filing cabinet in the manager's office. Same list of people, but this file holds the real password hashes and the rules for when passwords expire. A hash is the scrambled, one-way fingerprint of a password: you can check a guess against it, but you cannot run it backward to get the password out. Only root can open this file.
The permissions tell the story before you read a single byte. rw for root, r for the group named 'shadow', and nothing at all for everyone else. An ordinary user cannot even read it, so they cannot copy the hashes off and attack them at their leisure. Inside, each line splits on colons again: the username, then the hash, then a run of numbers that govern password aging. The day the password was last changed (counted in days since the 1st of January 1970), the fewest days before it may be changed again, the most days before it must be changed, and how many days of warning the user gets first.
The hash is self-describing. It opens with a marker between dollar signs that names the algorithm that made it. '$y$' is yescrypt, the modern default on Debian and Ubuntu. '$6$' is the older SHA-512 (Secure Hash Algorithm, 512-bit). '$1$' is MD5 (Message Digest 5), which is ancient and weak, and finding it on a running system is a small alarm bell. Two other values can appear where a hash belongs. A single '*' means the account never had a usable password, which is normal for service accounts. A '!' at the front means the account is locked.
Groups: Who Belongs To What
A group is a labeled keyring. Rather than granting access to twenty files one teammate at a time, you hang those permissions on a single ring called, say, 'developers', and hand people the ring. Every user has one primary group (the GID from their /etc/passwd line, which owns any new file they create) plus any number of extra supplementary groups that stack on more access.
Each line is the group name, an 'x' placeholder, the GID, and then a comma-separated list of members. (Your primary group does not list you here; that link lives in your /etc/passwd line, which is why deploy's own group looks empty.) Two of these carry real weight. Membership in 'sudo' (or 'wheel' on Red Hat-style systems) is what lets a user run commands as root through sudo (superuser do, the command that runs one command as root after checking you are allowed). And 'docker' looks harmless but is not: anyone in the docker group can start a container that mounts the entire host filesystem and hands them root over it. Being in the docker group is, in practice, being root. When you review who can administer a machine, do not stop at the sudo group. Read the docker group exactly the same way.
Creating, Locking, And Removing Accounts
Adding a person is a couple of commands. useradd is the low-level tool; adduser is the friendlier Debian and Ubuntu wrapper that asks a few questions and fills in sane defaults. Give every human their own named account from day one.
When someone leaves, you have two moves and the order matters. Locking is reversible and takes effect at once: it disables the password so they cannot log in, while keeping their files and their name in the logs for any later investigation. Deleting is permanent and burns that trail. Lock first, delete much later if ever. An account that still accepts a password is a standing open door, and forgotten accounts belonging to people who left months ago are one of the most common ways attackers stroll back in. chage (change age, which edits the expiry rules in /etc/shadow) can also expire an account outright.
There is one habit worth setting in concrete: one human, one account, and never a shared login. A shared 'admin' account the whole team uses, or several people logging in straight as root, quietly wrecks your ability to investigate anything later. When something breaks or gets breached, the logs say 'admin did it' and you cannot tell which of the eight people that was. Give every person their own named account, have them escalate with sudo (which records who ran which command as root), and disable both direct root login and generic shared logins. You cannot hold anyone accountable for an action you cannot trace to a name, and that traceability is the ground every other control stands on.
What To Check First On A Strange Machine
Put all of this together and you have a quick first pass on any Linux box you inherit or are told to secure. Three questions: who is secretly root, who has no password at all, and who can become root. Three short commands answer them, using awk (a small tool that splits each line into fields and prints the ones you ask for).
The first command prints the name of every account whose third field, the UID, is 0. A healthy system prints exactly one name, root. A second name there is a backdoor superuser and one of the oldest persistence tricks there is. The second command prints any account with an empty password field, which would let someone in with no password at all; it should print nothing, and here it does. The third shows precisely who holds admin rights. Run these against a box you were sure was clean and now and then you will still get a surprise.
So next time you land on an unfamiliar server, before you touch anything, run id to see who the box thinks you are, then read /etc/passwd and run getent group sudo to see who else is on the machine and which of them could take it over. Those three checks cost about ten seconds, and they are the whole difference between guessing about a box and actually knowing it.
Try this
Work through “What To Check First On A Strange Machine” yourself on a sandbox you can throw away, following the commands above in order. Then break one step deliberately and re-run, so you have seen the failure before it finds you.
Takeaway
The trap worth remembering here: a leaked /etc/shadow is a slow-motion breach. Check that on your own systems before you need to, because it is cheaper to find on a quiet afternoon than during an incident.