Linux Security Fundamentals
A server that boots, serves traffic, and never gets patched is not "working fine" — it's accumulating risk silently, because every unpatched service and every overly broad permission is a door someone else can eventually find. This module is not about one tool; it's about a set of layers that, together, make it measurably harder for an attacker to get in, and measurably faster for you to notice and respond when something goes wrong. This article lays out the vocabulary and mental model the rest of the module builds on.
What You Will Learn
By the end of this article you will be able to:
- explain the difference between authentication and authorization, and where each can fail;
- explain DAC versus MAC and why a Linux system typically has both;
- describe defense in depth and apply it to a concrete server;
- list the main categories of Linux security controls and where each one lives in this course;
- reason about attack surface as something you actively reduce, not something you defend passively.
Authentication vs. Authorization
These two words get used almost interchangeably in casual conversation, but they answer different questions, and conflating them is a common source of security misconfiguration:
- Authentication answers "who are you?" — a password check, an SSH key, a TOTP code.
- Authorization answers "what are you allowed to do, now that I know who you are?" — file permissions, sudoers rules, a firewall rule, an SELinux policy.
A system can authenticate someone correctly and still authorize them far too broadly — a legitimate user with sudo ALL=(ALL) NOPASSWD: ALL is a correctly authenticated user with an authorization problem. Nearly everything in this module either strengthens authentication (PAM, password policy, key-based SSH from an earlier module), strengthens authorization (least privilege, sudo scoping, ACLs, SELinux/AppArmor), or gives you the ability to detect when either one failed (auditd, log analysis).
DAC and MAC: Two Layers of Access Control
Linux's traditional permission model — the rwx bits, ownership, chmod — is Discretionary Access Control (DAC): the file's owner decides who can access it, and the kernel enforces that decision. It's called "discretionary" because the decision is up to whoever owns the resource, not a system-wide policy.
Mandatory Access Control (MAC) — SELinux on the RHEL family, AppArmor on Ubuntu — sits on top of DAC and enforces a separate, system-defined policy that the resource owner cannot override. A process can be root, own a file outright, and pass every DAC check, and MAC can still deny the action, because the security policy — not the file owner — decides what a given process type is allowed to touch.
getenforce # SELinux: reports Enforcing, Permissive, or Disabled
aa-status # AppArmor: reports loaded profiles and their mode
This two-layer design is deliberate: DAC alone means a single compromised process running as a legitimate user (a web server that got exploited, say) can do anything that user could do — read the SSH keys in /home, write to any file the user owns. MAC constrains that process to only the specific files, ports, and capabilities its policy allows, regardless of what the underlying Linux permissions would otherwise permit. SELinux and AppArmor covers both in depth, later in this module.
Defense in Depth
No single control is perfect — a firewall rule can be misconfigured, a password can leak, a patch can lag. Defense in depth means stacking independent controls so that one failure doesn't equal a full compromise. A rough model of the layers, from outermost to innermost:
Network -> firewall (ufw/nftables), fail2ban, exposed ports minimized
Authentication -> SSH keys, PAM, password policy, MFA where warranted
Authorization -> least privilege, sudo scoping, file permissions, ACLs
Mandatory access control -> SELinux/AppArmor confining what a process can do even as root
Detection -> auditd, centralized logging, log analysis
Recovery -> patching cadence, backups (covered in the automation module), incident response
Interview angle: defense in depth vs. a single strong control
A common interview question is some version of "if you could only implement one security control, which would it be?" The correct answer rejects the premise: a single control, however strong, is a single point of failure. A firewall that blocks everything except port 22 does nothing if the SSH daemon itself has weak authentication; strong SSH authentication does nothing if the account it protects has unrestricted sudo with no audit trail. The interview-ready answer names the layers and explains that they're independent on purpose — a compromise at one layer shouldn't automatically cascade into every layer above it.
Attack Surface: What You Can Actually Reduce
Attack surface is the sum of everything an attacker could potentially interact with: every listening port, every installed package with a network-facing daemon, every account that can log in, every sudo rule, every writable file a compromised process could reach. Unlike "threats," which are largely outside your control, attack surface is something you directly shrink:
ss -tulpn # what's actually listening
systemctl list-unit-files --state=enabled # what starts automatically
dpkg -l | wc -l # how much is installed at all
A server running only what it needs — no example web apps left over from setup, no unused database engine still listening on a public interface, no forgotten test account — has fundamentally less to defend than one running a full desktop-equivalent package set "just in case." Server Hardening, the closing article of this module, turns this principle into a concrete checklist.
Where the Rest of This Module Fits
This module builds outward from a single server's authorization model to the whole detection pipeline:
- Least Privilege — the organizing principle behind almost every other article here.
- sudo Security — hardening and auditing the most common way ordinary users become root, building on Root and sudo from the users and permissions module.
- PAM Basics — the pluggable authentication framework sudo, login, and SSH all sit on top of.
- Password Policies — enforcing password strength and rotation system-wide, beyond a single account's settings.
- SELinux and AppArmor — mandatory access control in depth.
- Firewall and UFW and iptables and nftables — controlling what reaches the host at all.
- fail2ban — automatically reacting to repeated attack attempts.
- auditd Basics — recording security-relevant events the kernel sees.
- Permission Audit — turning ad-hoc permission checks into a repeatable process.
- Security Log Analysis — reading what auditd, PAM, and sshd actually recorded.
- Server Hardening — assembling all of the above into a single, ordered checklist.
A Server's Security Is a Process, Not a State
A server hardened once and never revisited drifts back toward insecurity: packages age, a "temporary" firewall rule from a debugging session gets forgotten, an account added for a contractor never gets removed. Every article in this module pairs a control with a way to verify it's still doing its job — systemctl status, journalctl, getenforce, ufw status verbose — because a control no one checks is a control that quietly stops working without anyone noticing.
Common Mistakes
- Treating security as a one-time setup task. Patching, log review, and account audits need to recur on a schedule, not happen once during initial provisioning.
- Confusing "no errors" with "secure." A server can run without complaints while still exposing an unpatched service, an overly broad sudo rule, or a world-writable directory — absence of visible problems is not the same as an actual audit.
- Reaching for a single tool as "the" security solution. fail2ban without key-based SSH, or a firewall without patched services behind it, each address only one layer while leaving the others exposed.
Exercises
- For a server you manage or a lab VM, list three concrete things that would reduce its attack surface right now if removed or disabled, and three that would reduce it further if you had more time.
- Run
getenforce(oraa-statuson Ubuntu) and explain, in a sentence, what the result means for a process that already has correct DAC permissions on a file. - Pick one security incident scenario (a leaked password, a misconfigured sudoers entry, an exposed database port) and describe which defense-in-depth layer should have caught it, and which layer would have limited the damage if that first one failed.
Summary
Security on a Linux server rests on distinguishing authentication from authorization, layering DAC with MAC, stacking independent controls so no single failure is catastrophic, and actively shrinking what's exposed rather than only reacting to threats. The rest of this module works through each layer in turn, starting with the principle that ties nearly all of them together: least privilege.