This page is a working reference, not a tutorial. Each section is a self-contained answer to a real question that comes up the first time you administer a Linux system: how do I make an account, lock one, share a directory with a team, get my coworker SSH access, mount the new disk? Every command shown is exactly what you'd type at a real prompt.
The accompanying hands-on lab threads all eight topics into a single onboarding scenario — create a team, give them shared storage, get them on SSH, then off-board one of them. If you do the lab, you'll use everything here at least once.
01Creating users
A user account in Linux is a row in /etc/passwd, a row in /etc/shadow (with the hashed password), a primary group, optional secondary groups, a home directory, and a login shell. Two tools create users: useradd and adduser. They are not the same tool, and which one is available depends on your distribution.
useradd — the portable workhorse
useradd is part of the shadow-utils package and exists on essentially every modern Linux distribution. It is low-level: it makes the account, but it doesn't set a password, doesn't always create a home directory, and doesn't ask you any questions. You give it flags; it does exactly what you said.
Minimal usage
That creates the account but, on most distros, does not create /home/alice, leaves the account locked (no password), and uses the system default shell (often /bin/sh). The result is usually not what you wanted.
Practical usage — the flags that actually matter
That command creates alice with a home directory at /home/alice, bash as her login shell, a human-readable comment ("GECOS" field) listing her name and department, and membership in two supplementary groups.
Common flags
| Flag | What it does |
|---|---|
| -m | Create the user's home directory (skeleton files from /etc/skel are copied in). Without -m, no home directory exists and the user can't log in cleanly. |
| -M | Explicitly do not create a home directory (for service accounts that don't need one). |
| -s SHELL | Set the login shell. /bin/bash for human users, /usr/sbin/nologin for service accounts that should never log in interactively. |
| -c "COMMENT" | The GECOS field — traditionally the user's full name, phone, room number. Modern usage: just the full name and maybe a department. |
| -G g1,g2 | Supplementary groups (comma-separated, no spaces). Membership is set exactly to this list — existing memberships are wiped. Use usermod -aG later to append instead of replace. |
| -g GROUP | Primary group. By default, useradd creates a new group with the same name as the user (USERGROUPS_ENAB in /etc/login.defs). |
| -u UID | Specify the user's UID. Useful when you need the UID to match across machines (e.g., for shared NFS mounts). |
| -d /path | Custom home directory path (default /home/<name>). |
| -r | Create a system account (UID below 1000, no aging, no home by default). Use for daemons and services. |
| -e YYYY-MM-DD | Account expiration date. After this date, the account is disabled. |
| -f DAYS | Days after password expiry before the account is locked. 0 = lock immediately on expiry. |
adduser — the same thing, except when it isn't
There are two different adduser commands in the wild, and they behave completely differently. Knowing which one you have matters.
Debian / Ubuntu adduser
What it is: a Perl script (a friendly wrapper around useradd) that walks you through the whole account-creation process interactively.
What it does for you: creates the home directory, copies the skeleton files, picks a sane UID/GID, sets the shell, prompts you for the GECOS fields and the password, and asks for confirmation.
When you want it: interactive use on a Debian/Ubuntu box. It's the friendlier choice when you're sitting at a terminal making one account by hand.
RHEL / Rocky / Fedora / SUSE adduser
What it is: a symbolic link directly to useradd. Same binary, same flags, no interactive prompts at all.
What it does for you: exactly what useradd does. Nothing more.
When you want it: never specifically. If you're on RHEL/Rocky/Fedora, use useradd directly — adduser is just a different name for the same thing.
Debian-style adduser in action
Other ways to create users
newusers— bulk-create users from a file in/etc/passwdformat. Useful when onboarding a whole class at once.- Ansible / configuration management — modules like
ansible.builtin.userwrapuseraddbut make the operation idempotent (running it twice doesn't break anything). This is how user provisioning is done at scale. - GUI tools — GNOME Settings → Users, KDE System Settings,
system-config-users(older RHEL). Useful on a workstation; never used on a server. - LDAP / Active Directory — the user doesn't live in
/etc/passwdat all; PAM and NSS talk to a directory service. The commands above are for local accounts.
When to use which
Writing a script. Provisioning many accounts. Running on RHEL/Rocky/Fedora/SUSE. Need predictable, scriptable behavior. Want exact control over UID, GID, shell, and home.
You're on Debian or Ubuntu, you're at a terminal, and you're making one account interactively. The wrapper will handle the home directory, password, and GECOS in one pass without you needing to remember the flags.
-m with useradd on RHEL. The account is created, but /home/<user> doesn't exist. The user logs in, lands in /, can't write anywhere, and everyone is confused. Always pass -m for human users.
02Setting passwords & aging
Creating the account is half the work; the password (and its lifecycle) is the other half. Two commands cover almost everything: passwd sets and manages the password itself, and chage manages the aging policy — how long before it expires, how soon before then to warn the user, how to force a change on the next login.
passwd — setting the password
Set a user's password (root)
Change your own password (any user)
Force a password change at next login
Standard practice when a help desk resets a password for someone: set a temporary password, then force the user to change it the moment they log in. Two ways to do this:
Both work by setting the "last changed" date to a value that makes the system consider the password expired. The next time alice logs in — on console, SSH, anywhere — she'll be prompted to set a new password before she can do anything else.
passwd flag reference
| Flag | What it does |
|---|---|
| -e | Expire the password immediately. Forces a change at next login. |
| -l | Lock the account by prefixing the password hash with ! in /etc/shadow. The user can't log in with a password, but SSH keys still work. This is not a full disable. |
| -u | Unlock a previously locked account. |
| -d | Delete the password entirely. The user can log in with no password (dangerous). Almost always wrong. |
| -S | Status: show the password state for the user. Output tells you whether the password is set, locked, or expired. |
| -n DAYS | Minimum days between password changes. 1 stops users from changing the password back immediately after it's reset. |
| -x DAYS | Maximum days the password is valid. 90 = enforce a quarterly change. |
| -w DAYS | Days before expiry to start warning the user at login. |
| -i DAYS | Days after expiry before the account itself is locked. |
chage — the aging tool you'll actually use
When you need to control when a password expires, when the user is warned, and when the account itself goes inactive — that's chage. (Pronounced "change-age" or "shaj"; depends on who you ask.)
Inspect the current policy
Set a 90-day password policy with 14-day warning
Reads as: maximum age 90 days, minimum 1 day between changes (prevents instant-revert), warn for 14 days before the password expires.
Force a password change at next login (again, the chage way)
Set the account itself to expire on a specific date
chage flag reference
| Flag | What it does |
|---|---|
| -l | List the current aging info for the user (the inspect command). |
| -d DAYS | "Last changed" date in days since epoch. -d 0 forces a change at next login. |
| -m DAYS | Minimum days between changes. Stops "change, then change back" workflows. |
| -M DAYS | Maximum days between changes. The classic "passwords expire every 90 days" knob. |
| -W DAYS | Days before password expiry to start warning the user. |
| -I DAYS | Days after password expiry before the account becomes inactive. |
| -E YYYY-MM-DD | Account expiration date. After this, login is denied entirely. |
System-wide defaults
The defaults that useradd and chage apply when you don't specify flags live in /etc/login.defs. The interesting lines:
If your policy requires 90-day rotation, set PASS_MAX_DAYS here and every new account inherits it. Changing this file does not retroactively update existing users — for those, run chage against each.
PASS_MAX_DAYS.
03Disabling accounts
"Disable this account" sounds simple. It is not. The default approach — locking the password — only blocks password-based login. If the user has an SSH key in their ~/.ssh/authorized_keys, they can still log in. If they have a running session, they can still use it. A proper disable closes every door at once.
Why "lock" is not "disable"
That L means the hash in /etc/shadow now has a ! prefix; no password will ever match it. But:
- SSH key authentication doesn't check the password — bob can still log in with his key.
- Any session bob already has open is unaffected.
- Sudo via NOPASSWD rules still works.
- API tokens, cron jobs running as bob, scheduled tasks — all untouched.
A real disable closes every path.
The proper disable recipe
After those six steps, bob cannot log in with a password, cannot log in with an SSH key, cannot land in a working shell even if those two somehow succeed, has no running sessions, and has no scheduled jobs that will fire later. That is disabled.
Disable vs delete
Deletion is the next step after disable — and it's a separate decision.
userdel -r deletes the home directory with no prompt. If bob had work product there, it's gone. For real offboarding, archive /home/bob first (tar czf bob-archive.tgz /home/bob), then delete.
04Groups, in depth
A group is a named collection of users that can be granted permissions as a unit. Instead of giving alice, bob, and carol each their own permission to read /srv/projects/teamA/, you create a group called teamA, add the three of them to it, and grant the group read access. Now adding a fourth person (or removing one) is a single command and doesn't touch the directory at all.
This sounds trivial, and at the level of three users it is. At the level of three hundred users across a dozen projects, it is the only sustainable way to manage access. Groups are why Linux administration scales.
Primary vs supplementary groups
Every Linux user has exactly one primary group, which determines the default group ownership of files they create. They can also have zero or more supplementary groups (also called secondary groups), which grant additional access.
Here alice's primary group is alice (gid 1003), and her supplementary groups are developers, teamA, and sudo. When she runs touch newfile, the file's group ownership is alice — her primary. To make team files default-group teamA instead, you use the setgid bit on the directory (covered in Topic 5).
Creating a group
Listing groups and their members
Three commands cover everything you'll need to ask.
What groups exist on this system?
Same as cat /etc/group on a system with only local accounts; getent additionally pulls in LDAP/AD groups if the system is joined to a directory.
Who is in this specific group?
What groups is this specific user in?
Adding and removing members
The single most important fact about adding a user to a group: always use the -a flag with usermod -G. Without -a, you replace the user's entire set of supplementary groups with the one you just specified. People have wiped out a user's sudo access this way, often without realizing it.
Add alice to teamA (APPEND — the right way)
Add alice to teamA (WRONG — this replaces all her supplementary groups)
Remove alice from teamA
There's no usermod -d for groups — gpasswd -d is the standard way to remove one user from one group without touching the rest of their memberships.
Change alice's primary group
Temporarily switch primary group in your session
Removing or renaming a group
teamA's GID from 2001 to 3000 and there are existing files owned by gid 2001, those files now appear to belong to "an unknown group" (the number 2001 with no name). Either avoid changing GIDs, or run find / -gid 2001 -exec chgrp 3000 {} + right after.
The shape of /etc/group
Every group is one line, four colon-separated fields:
- groupname — the name you use in commands
- x — placeholder where the group password used to live (essentially never used today)
- GID — the numeric group ID; what the kernel actually checks against
- members — comma-separated list of users for whom this group is supplementary. Users whose primary group is this one are not listed here — their membership is implied by their
/etc/passwdentry.
Special groups worth knowing
- root (gid 0) — superuser. Membership here is almost as dangerous as being root.
- sudo (Debian/Ubuntu) / wheel (RHEL/Rocky/Fedora) — users in this group can run
sudo. Adding someone here is how you grant admin access. - docker — users in this group can talk to the Docker daemon. That daemon runs as root, so
dockermembership is effectively root access. Treat it like membership insudo. - adm, systemd-journal — read access to system logs without being root.
- shadow — read access to
/etc/shadow. Granting this is granting offline password-crack access.
When permissions are granted to individuals, every onboard and offboard touches every resource the user can access. When permissions are granted to groups, onboarding is "add user to group" and offboarding is "remove user from group" — the resources don't move.
The rule: grant permissions to groups, put users into groups, and try very hard to never grant a permission to a single named user.
05Creating directories
mkdir is the simplest command in this reference, but a handful of flags turn it from "make one directory" into "build out a whole project tree in one line with the right permissions."
Basic usage
Create parents as needed
The -p flag is the single most-used mkdir option. It creates every directory in the path that doesn't already exist, and silently does nothing for the ones that do. Safe to run twice.
Set the mode (permissions) at creation
Without -m, the new directory's permissions are governed by your umask. With -m, you pick exactly the mode you want, ignoring umask.
Bash brace expansion — multiple directories in one call
Common flag reference
| Flag | What it does |
|---|---|
| -p | Create parent directories as needed; succeed silently if the target already exists. |
| -m MODE | Set the mode at creation. Use octal: 0755, 0750, 0700. |
| -v | Verbose — print one line per directory created. Useful for sanity-checking brace-expansion explosions. |
| -Z | Set the SELinux security context on the new directory (on SELinux-enabled systems). |
After creating — ownership and the setgid trick
Creating the directory is step one. Step two, for a shared team directory, is usually to (a) set the group, (b) grant the group write access, and (c) make sure every file created inside the directory also belongs to that group automatically.
The setgid bit on a directory (the leading 2 in 2770) means: any file or subdirectory created inside this directory inherits the directory's group, not the creator's primary group. This is exactly the behavior you want for shared team storage.
·
0755 — public-readable (web roots, system binaries)·
0750 — private to a group (team home, shared scripts)·
2770 — shared team writable, setgid for group inheritance·
0700 — private to owner (~/.ssh, secrets)
06SSH — and the root login question
SSH is how you'll log into every Linux server you administer for the rest of your career. Setting it up correctly — key-based authentication, the right users allowed in, and a deliberate decision about root login — is the single highest-leverage security action you take on a new system.
Install and start the SSH server
The service is named ssh on Debian-family and sshd on RHEL-family. The configuration file is the same on both: /etc/ssh/sshd_config.
Set up key-based authentication
Passwords are guessable; SSH keys are not (when generated with a modern algorithm). The standard setup is: generate a key on your local machine, copy the public half to the server, then disable password authentication on the server entirely.
On your local machine (the client)
Use ed25519, not rsa. It's shorter, faster, and at least as strong. Always set a passphrase — it's what protects the key if your laptop is stolen.
Copy the public key to the server
If ssh-copy-id isn't available, do it by hand
Note the permissions: ~/.ssh must be 700 and authorized_keys must be 600. SSH will refuse to use them otherwise — this is a frequent source of "why won't my key work?" frustration.
The root login question
Should the root account be allowed to log in via SSH? This is one of the few security questions where the right answer is almost always "no" — but understanding why matters, because there are scenarios where you'll need to override it.
Disable root SSH (the default for hardened systems)
Why disable root SSH
- Attribution. Every command run as root via SSH appears in logs as "root did this." If alice and bob both have root SSH, you can't tell them apart in an incident. If they each log in as themselves and
sudo, you can. - Attack surface. "root" is the one account name an attacker can guess without doing any reconnaissance. Disabling it removes the easiest brute-force target from the menu.
- Accident containment. If alice's account is compromised, the attacker has alice's permissions. If she also routinely SSH'd as root, the attacker has root. Forcing the sudo step is one more checkpoint — one more chance to notice.
Enable root SSH (the rare valid cases)
There are three options that allow root login at all:
yes— root can log in with password or key. Almost never the right choice.prohibit-password— root can log in with an SSH key, but not with a password. Used by major cloud providers (AWS Amazon Linux, GCP COS) for the initial root account: the key was placed by the provisioner and there is no password to brute-force.forced-commands-only— root can log in with a key, but only to run a specific command tied to that key (usingcommand="..."inauthorized_keys). Useful for automation: a backup system can SSH as root only to run the backup script.
Other sshd_config settings worth knowing
| Setting | What it does |
|---|---|
| PasswordAuthentication no | Disable password login entirely. Keys only. The single biggest hardening step you can take after disabling root. |
| PubkeyAuthentication yes | Allow public-key authentication. On by default; verify it. |
| AllowUsers alice bob | Only these users can SSH. Everyone else is denied even if their credentials are correct. |
| AllowGroups developers | Only members of these groups can SSH. Pairs perfectly with the group strategy from Topic 4. |
| Port 2222 | Listen on a non-default port. Marginal security benefit (reduces drive-by scans, doesn't stop a real attacker), but quiets the logs. |
| MaxAuthTries 3 | Disconnect after N failed auth attempts in a single session. |
| ClientAliveInterval 300 | Send a keepalive every 300 seconds. With ClientAliveCountMax 2, drops idle sessions after ~10 minutes. |
sshd -t parses the config and reports errors without restarting the service. A typo in sshd_config can lock you out of the server. Open a second SSH session before you restart, so if the new config breaks login, you still have a way in.
07chroot jails — and what replaced them
A chroot jail is a Unix isolation technique: you take a process and tell the kernel, "as far as you're concerned, this directory is the root of the filesystem." The process can see /usr/lib, /etc/passwd, and so on, but those paths all resolve under the jail directory, not the real system. To the jailed process, the rest of the filesystem doesn't exist.
It is a beautiful idea, it was the original "I'd like this process to be contained" mechanism on Unix, and on modern systems it has been almost entirely superseded by containers — for a reason worth understanding.
A short history
The chroot() system call was added to Version 7 Unix in 1979. Bill Joy used it in 1982 to test installations of BSD. By the 1990s, it was the standard way to run a network-facing daemon (BIND, FTP servers, anonymous HTTP) in a sandbox: build a minimal copy of /usr/lib, /bin, and /etc inside /var/named/chroot/, then start the daemon with chroot /var/named/chroot /usr/sbin/named. If the daemon was exploited, the attacker landed inside the jail, not the real filesystem.
FreeBSD took the idea further in 2000 with the jail() syscall — an extended chroot that also isolated the process from the host's process table, network stack, and user namespace. FreeBSD jails are still in active use today.
What chroot actually does (and doesn't)
What chroot isolates
Filesystem view. The process sees only the subtree under the new root.
That's it.
What chroot does NOT isolate
Process table. The jailed process can see (and signal) every other process on the host.
Network. Same interfaces, same routes, same firewall.
Users. UID 0 inside is UID 0 outside. Root in the jail is root on the host.
Mounts. The jailed process can mount and unmount filesystems if it has the privilege.
Combine those gaps with the fact that a process running as root inside a chroot can call chroot() again to break out, and you have the core security problem: chroot was never designed as a hard security boundary. It was a way to constrain a benign process to a tidy view of the filesystem.
mkdir foo; chroot foo; cd ../../../../..; chroot . — you're back at the real /. The chroot syscall doesn't change what "parent directory" means at the kernel level; it only changes where / resolves to for path lookups.
What replaced chroot
Linux gradually grew a set of kernel features that, taken together, provide what chroot was reaching for and more:
- Mount namespace (Linux 2.4.19, 2002) — gives a process its own view of the filesystem, mounts and all. This is the proper version of what chroot was approximating.
- PID namespace (2.6.24, 2008) — the process has its own process table; the host's processes are invisible.
- Network namespace — own interfaces, own routes, own firewall, own listening ports.
- UTS namespace — own hostname.
- IPC namespace — own System V IPC.
- User namespace (3.8, 2013) — UID 0 inside maps to an unprivileged UID outside. This is the one that finally makes "root inside the container can't damage the host" achievable.
- cgroups (Linux 2.6.24+) — resource limits on CPU, memory, I/O, devices. Independent of namespaces but used alongside.
Put namespaces and cgroups together, wrap them in tooling that builds and runs filesystem images, and you have a container. That's all a container is, at the kernel level: a regular Linux process running inside several namespaces with cgroup limits applied. There's no virtual machine, no separate kernel; it's just very thorough scoping.
What you'll actually use
- Docker — the tool that made containers mainstream. Builds images, runs containers, manages networking and storage. Still the most common entry point.
- Podman — Docker-compatible CLI from Red Hat, daemonless and capable of running rootless. The default on RHEL 8+.
- containerd / CRI-O — the actual container runtimes underneath Kubernetes. Most students will meet these only through K8s.
- systemd-nspawn — the systemd project's lightweight container manager. Great for "just give me a chroot with namespaces" without pulling in the Docker stack.
- LXC / LXD — Linux Containers; full-system containers (think "lightweight VM") rather than per-application. Common in Proxmox and Ubuntu environments.
- gVisor, Kata Containers — hardened runtimes. gVisor implements a userspace kernel between the container and the real one; Kata runs each container in a tiny VM. Both for workloads where standard namespace isolation isn't trusted enough.
Where chroot still matters
chroot is not dead. It's just no longer the answer to "how do I sandbox a thing." It's still the right tool for:
- SFTP-only users via SSH's
ChrootDirectorysetting — the most common operational use of chroot today. - System recovery — boot from a live USB, mount the broken root partition,
chroot /mnt, and now your shell behaves as if it were running on the broken system. You can reinstall the bootloader, fix/etc/fstab, regenerate initramfs. - Package build environments —
debootstrap,mock,pbuilderall use chroot (sometimes layered with namespaces) to give you a clean target distribution to build inside. - BIND and a handful of legacy daemons still ship with chroot support out of habit, although containers have largely overtaken this.
chroot was the first attempt at "let me give this process a smaller world." It worked well enough for benign cases and badly for adversarial ones. Modern containers are the answer to the same question, except they isolate everything the kernel can be asked to scope — filesystem, processes, network, users, resource limits — not just the filesystem path lookup.
You'll meet chroot in the wild via SFTP jails and recovery boots. You'll live in containers.
08Mounting drives — and what mapping means
On Linux, every piece of storage — a local disk, a USB drive, a network share, an ISO image — must be mounted at a directory before you can read from or write to it. The directory becomes the entry point; everything you do at that path under the hood reaches the storage device.
Windows administrators often ask whether "mounting" is the same as "mapping." The answer is yes, in spirit, and no, in implementation. We'll get to that.
What "mount" actually means
A new disk shows up to the kernel as a block device — something like /dev/sdb for a SATA disk or /dev/nvme0n1 for an NVMe drive. The disk usually has one or more partitions: /dev/sdb1, /dev/sdb2. Each partition holds a filesystem (ext4, xfs, ntfs, vfat).
Until you mount that filesystem, it's invisible to your shell. You can't cd into it. You can't read its files. The kernel knows it exists; it just hasn't been wired into the directory tree yet.
Discover what's there
In that output, sda2 is the root filesystem (already mounted at /), and sdb1 is a 500 GB partition that's been formatted but not yet mounted — no mountpoint listed.
Mount it
Now anything you do under /mnt/data — reading, writing, creating files — happens on /dev/sdb1. Unmount when finished:
Discovery and inspection commands
| Command | What it tells you |
|---|---|
| lsblk | Tree view of all block devices: disks, partitions, what they're mounted on. |
| df -h | Mounted filesystems with sizes used / free in human-readable units. |
| findmnt | Pretty tree of every active mount, showing source, type, and options. |
| blkid | UUIDs and labels for every block device; used to write reliable /etc/fstab entries. |
| mount | With no arguments, lists every currently mounted filesystem. |
Persistent mounts — /etc/fstab
A mount made with the mount command lasts until the next reboot. To make a mount persistent — come up automatically every time the system starts — add an entry to /etc/fstab. Each line is one mount.
Use UUID= rather than /dev/sdb1. Device names can change between reboots (the disk that was sdb last week could be sdc after you add another); UUIDs don't. Get the UUID from blkid.
After editing /etc/fstab, test before rebooting:
Useful mount options
| Option | What it does |
|---|---|
| ro | Mount read-only. Useful for evidence preservation in forensics, or for protecting a reference filesystem. |
| nosuid | Ignore setuid/setgid bits on this filesystem. Stops a user from sneaking a setuid-root binary onto a removable disk. |
| nodev | Ignore device files on this filesystem. Stops a malicious device node from granting unintended access. |
| noexec | Refuse to execute binaries from this filesystem. Common on /tmp and user data drives. |
| noatime | Don't update access times on read. Significant performance improvement for high-read workloads. |
| defaults | Shorthand for rw, suid, dev, exec, auto, nouser, async. The "normal" mount. |
Network mounts — NFS and CIFS/SMB
You can mount storage that lives on another machine over the network. Two common protocols:
Both are then accessible exactly the same way as a local mount — programs reading from /mnt/projects have no idea the bytes are crossing the network.
"Mount" vs "map" — the Windows question
In day-to-day conversation, the two terms are used interchangeably. The distinction comes from how the two operating systems organize their filesystem namespace.
Linux: mount
One unified filesystem tree starting at /. Any device, any network share, any image, gets attached at some directory within that tree.
A new disk doesn't get a letter — it gets a path: /mnt/data, /srv/projects, /home on its own disk, whatever you choose.
The kernel concept is "mount" — attaching a filesystem at a directory.
Windows: map
Drive letters: C:, D:, E:. Each device or share gets its own top-level letter.
net use Z: \\fileserver\share "maps" the network share to drive Z:. Now Z: is a top-level namespace just like C:.
The OS concept is "map" — assigning a network resource to a drive letter.
The reason this question keeps coming up: Windows can also mount a volume into an empty folder on NTFS (Disk Management → Change Drive Letter and Paths → Mount in the following empty NTFS folder), which behaves much like Linux mounting. And Linux can use automounters to make drives appear under /mnt/auto/ as if they had been "mapped." So the line between the two terms is blurrier than vocabulary alone suggests. The cleanest answer:
- Linux mounts a filesystem at a directory in a single unified tree.
- Windows maps a remote share to a drive letter in a flat top-level namespace.
- Both make remote or new storage accessible. The vocabulary follows the namespace conventions of the host OS.
Why mount something in the first place
Four typical reasons to mount a drive:
- New local storage. You added a disk; you want to use it. Mount it where applications expect to find data.
- Shared storage. A team shares a directory served from a fileserver. NFS or SMB mount it to every workstation that needs access.
- External media. USB stick, external drive, ISO image — you mount it to read its contents.
- Isolation. Putting
/homeor/varon its own partition (and mounting them withnodev,nosuid) limits the damage from a runaway log or a user with too much creative freedom.
Linux's filesystem is one tree. Mounting is how anything new joins that tree. The directory you mount onto is just an attachment point — the storage itself can be a local disk, a partition, a remote share, an encrypted image, or a tmpfs filesystem in RAM. The semantics are the same once it's mounted.
"Mapping," in the Windows sense, is the equivalent operation in an OS that uses drive letters instead of a unified tree.
References
Formatted in APA 7. Pattern to memorize: Author(s). (Year). Title of work (Identifier). Publisher. URL. Names are alphabetized by the first author's last name; italics on the work title, not on the author or publisher.
- FreeBSD Project. (n.d.). jail(8): FreeBSD system manager's manual. https://www.freebsd.org/cgi/man.cgi?jail
- Grassi, P. A., Fenton, J. L., Newton, E. M., Perlner, R. A., Regenscheid, A. R., Burr, W. E., Richer, J. P., Lefkovitz, N. B., Danker, J. M., Choong, Y.-Y., Greene, K. K., & Theofanos, M. F. (2017). Digital identity guidelines: Authentication and lifecycle management (NIST Special Publication No. 800-63B, Rev. 3). National Institute of Standards and Technology. https://doi.org/10.6028/NIST.SP.800-63b
- Kerrisk, M. (n.d.-a). fstab(5): Linux manual page. Linux man-pages project. https://man7.org/linux/man-pages/man5/fstab.5.html
- Kerrisk, M. (n.d.-b). mount(8): Linux manual page. Linux man-pages project. https://man7.org/linux/man-pages/man8/mount.8.html
- Kerrisk, M. (n.d.-c). namespaces(7): Linux manual page. Linux man-pages project. https://man7.org/linux/man-pages/man7/namespaces.7.html
- OpenBSD Project. (n.d.). sshd_config(5): OpenSSH daemon configuration file. https://man.openbsd.org/sshd_config
- shadow-maint. (n.d.). shadow-utils [Source code repository]. GitHub. https://github.com/shadow-maint/shadow
- Wirzenius, L., Oja, J., Stafford, S., & Weeks, A. (2004). The Linux system administrator's guide (Version 0.9). The Linux Documentation Project. https://tldp.org/LDP/sag/html/index.html