Series: Linux Mastery Road to Cloud
Domain: 2 of 12
Level: Round 2 depth
Format: Command explanation + real-world scenarios
I am currently going through a structured Linux mastery curriculum across 12 domains as part of my career transition into cloud and DevOps engineering. Instead of repeating simulation rounds, I tested my understanding domain by domain — explaining commands in plain language, identifying what each flag does, and connecting concepts to real production scenarios.
This post covers Domain 2: Users, Groups & Access Control.
Command 1 — Creating a user
useradd -m -s /bin/bash -G sudo,www-data -c "Limon Admin" limon
What each part does:
useradd— low-level binary to create a new user account-m— creates the home directory at/home/limon-s /bin/bash— assigns bash as the login shell-G sudo,www-data— adds the user to supplementary groups sudo and www-data-c "Limon Admin"— adds a comment/description for the accountlimon— the username being created
What gets written to /etc/passwd:
limon:x:1014:1014:Limon Admin:/home/limon:/bin/bash
useradd vs adduser:
useradd is the lower level binary — it does exactly what you tell it and nothing more. adduser is a higher level wrapper script (on Debian/Ubuntu) that calls useradd underneath, sets sensible defaults, and prompts for additional details interactively. Use useradd when you know exactly what the account needs. Use adduser for quick interactive setup.
Command 2 — Shadow and group file entries
When the user is created, two other files get updated:
/etc/shadow entry:
limon:!:20512:0:99999:7:::
Fields in order: username : password : lastchange : min : max : warn : inactive : expire : reserved
The ! means no password has been set yet — the account is locked for password authentication.
/etc/group entries:
sudo:x:27:limon
www-data:x:33:limon
Format: groupname : password : gid : members
The x in the password field means the group password is stored in /etc/gshadow — not /etc/shadow. These are two separate files:
/etc/shadow— stores user passwords/etc/gshadow— stores group passwords
This is a common confusion point worth remembering.
Command 3 — Locking an account
passwd -l limon
usermod -L limon
Both commands add a ! prefix to the password hash in /etc/shadow, effectively locking password-based login. They do the same thing mechanically — there is no real difference between them.
The critical thing both commands do NOT do:
Neither prevents SSH key-based login. If the user has a public key in ~/.ssh/authorized_keys, they can still log in after the account is locked.
To fully block all access including SSH keys:
# Change shell to nologin
usermod -s /sbin/nologin limon
# Or expire the account immediately
usermod -e 1 limon
This is a real operational trap — locking an account with passwd -l and thinking the user is fully blocked, while they walk back in through their SSH key.
Command 4 — Group management
groupadd developers
usermod -aG developers limon
newgrp developers
Step by step:
groupadd developers — creates a new group entry in /etc/group. Since no GID is specified, the system assigns the next available ID automatically.
usermod -aG developers limon — modifies limon’s account to add the developers group as a supplementary group.
The -a flag trap:
Running usermod -G developers limon without -a removes limon from all existing supplementary groups and replaces them with only developers. The -a flag means append — add to existing groups without removing anything. Always use -aG together.
newgrp developers — group changes normally require the user to log out and back in for the session to recognize them. newgrp spawns a new shell with the updated group membership immediately, without requiring a full logout. Note: it only affects the current terminal session. Other open sessions are unaffected.
Command 5 — Password aging policy
chage -l limon
chage -M 90 -m 7 -W 14 limon
chage -l limon — lists the current password aging information for the user: last change date, expiry, inactive period, warning days.
chage -M 90 -m 7 -W 14 limon — sets the password policy:
-M 90— password expires after a maximum of 90 days-m 7— user must wait at least 7 days after a password change before changing again-W 14— user receives a warning 14 days before the password expires
The /etc/shadow file is updated with these values.
Real-world scenario:
This is used in environments where compliance is required — PCI-DSS, HIPAA, or corporate security policies that mandate password rotation. Any company handling payment data, medical records, or regulated information will enforce maximum password age as part of a security audit requirement. These settings would typically be applied as part of a user provisioning script so every new account inherits the policy automatically.
Command 6 — Checking user identity
id limon
Example output:
uid=1000(limon) gid=1000(limon) groups=1000(limon),4(adm),24(cdrom),27(sudo),30(dip)
uid— the user’s unique IDgid— the primary group IDgroups— all groups the user belongs to, starting with the primary group
Primary group vs supplementary groups — why it matters:
When a user creates a file, the file’s group owner is set to the user’s primary group — not any of their supplementary groups.
Real-world problem this causes:
Say limon is in both the limon and www-data groups. He creates a file in /var/www/html. The file gets limon:limon ownership by default — not limon:www-data. Other www-data members like nginx cannot read it.
Two fixes:
# Temporarily switch active group before creating the file
newgrp www-data
# Or set the setgid bit on the directory so all files inherit the directory's group
chmod g+s /var/www/html
The setgid + sticky bit combination is standard practice for shared team directories:
g+s— new files automatically inherit the directory’s group+t(sticky bit) — users can only delete their own files, not each other’s
Command 7 — Safe sudoers editing
visudo
Why visudo exists instead of editing /etc/sudoers directly:
Two reasons:
- Syntax checking —
/etc/sudoersis the most critical file on the system. A syntax error can make sudo completely non-functional and lock you out of administrative access.visudovalidates syntax before saving. - File locking —
visudolocks the file while it is open for editing. If two administrators try to edit sudoers simultaneously with plainnano, the second save overwrites the first.visudoprevents concurrent edits entirely.
The difference between these two entries:
limon ALL=(ALL:ALL) ALL
limon ALL=(ALL:ALL) NOPASSWD: ALL
The first grants limon full sudo access but requires password authentication every time sudo is used — a gatekeeper.
The second grants the same full access but removes the password requirement entirely.
Why NOPASSWD: ALL is dangerous in production:
If limon’s account is compromised, an attacker has immediate root access with zero friction. No password prompt, no delay, no alert.
A more controlled real-world approach — passwordless but restricted to one specific command:
limon ALL=(ALL:ALL) NOPASSWD: /bin/systemctl restart nginx
This is the principle of least privilege: grant exactly what the user needs and nothing more.
Command 8 — Transferring file ownership
find /home -user limon -exec chown bob:developers {} \;
What it does:
Searches the entire /home directory for every file owned by limon and changes ownership to user bob with group developers.
Real-world scenario — offboarding:
When an employee leaves and a new person takes over their work, files are not always neatly organized in one place. The departing user may have created files in shared project directories, backup folders, or other locations across /home. This command transfers ownership of all of them in one operation regardless of where they are.
The \; at the end means find executes chown once per file found. Using + instead collects all files first and passes them to a single chown call — more efficient when dealing with large numbers of files.
Domain 2 verdict
Every concept tested correctly. The one area of initial uncertainty was the /etc/gshadow vs /etc/shadow distinction for group passwords — a common confusion point and an exam target worth remembering.
Key takeaways from this domain:
- Locking an account with
passwd -lorusermod -Ldoes not block SSH key login - Always use
-aGtogether withusermod— never-Galone visudoprotects against syntax errors AND concurrent edits- Primary group determines file ownership at creation time
NOPASSWD: ALLin sudoers is a security audit failure in production
This is part of an ongoing series documenting my Linux to Cloud career transition. Each post covers one of 12 structured domains tested at Round 2 depth. My home lab runs at limonlab.online where real attack traffic generates authentic incident writeups for my portfolio.