Logging, Hardening & the Linux Security Baseline
Chapter 10 closes out the Linux track of the Foundations phase. It pulls together everything from the earlier chapters — permissions, users, processes, services, and networking — into the discipline of actually securing and monitoring a box: where logs live and how to read them, how auditd provides fine-grained visibility, and the concrete hardening steps that turn a default Linux install into something resembling a real security baseline. Every offensive technique explored in the rest of this notebook has a defensive mirror here; this chapter is that mirror.
Why Logging and Hardening Close Out This Track
Section titled “Why Logging and Hardening Close Out This Track”Up to this point the track has been mostly about capability — how to navigate, script, filter text, manage processes, and move network traffic. This chapter is about accountability and reduction of attack surface: knowing what happened on a box after the fact, and reducing how much can happen on it in the first place. These two concerns — visibility and hardening — are the daily bread of SOC analysts, DFIR responders, and anyone doing compliance work (CIS benchmarks, PCI-DSS, SOC 2), and they are exactly what a penetration tester or red-teamer is trying to evade or bypass. Understanding both sides makes you dramatically better at each.
flowchart TD
A[Linux Security Baseline] --> B[Logging & Visibility]
A --> C[Hardening & Attack Surface Reduction]
B --> B1[syslog / journald]
B --> B2[auditd]
B --> B3[Centralized log shipping]
C --> C1[Minimal services / firewall]
C --> C2[Access control - sudo, PAM, SSH]
C --> C3[Mandatory Access Control - AppArmor/SELinux]
C --> C4[CIS Benchmarks]
Foundations: Where Linux Logs Actually Live
Section titled “Foundations: Where Linux Logs Actually Live”The classic syslog-style logs
Section titled “The classic syslog-style logs”| Path | Contents |
|---|---|
/var/log/auth.log (Debian/Ubuntu) or /var/log/secure (RHEL/CentOS) | authentication events — logins, sudo usage, SSH connections |
/var/log/syslog (Debian/Ubuntu) or /var/log/messages (RHEL/CentOS) | general system messages |
/var/log/kern.log | kernel messages |
/var/log/dmesg | boot-time kernel ring buffer |
/var/log/apache2/ or /var/log/httpd/, /var/log/nginx/ | web server access/error logs |
/var/log/faillog, /var/log/lastlog | failed and successful login history, binary format |
/var/log/wtmp, /var/log/btmp | login records (last, lastb read these) |
tail -f /var/log/auth.log # live-follow authentication eventsgrep "Failed password" /var/log/auth.log | tail -20last -a # recent logins with source hostlastb # recent FAILED logins (btmp)lastlog # last login time per userjournald — the systemd-centric log store
Section titled “journald — the systemd-centric log store”Covered briefly in the previous chapter, journalctl is now the primary log interface on most modern distros, often in addition to traditional syslog files:
journalctl -xe # recent logs with extra explanation, end of outputjournalctl -u sshd --since today # one service, today onlyjournalctl -p err..alert # priority range filterjournalctl --vacuum-time=7d # prune logs older than 7 daysWhy it works:
journaldstores logs in a structured binary format (not plain text), which is why you query it withjournalctlinstead ofgreping a file directly — this also means metadata (PID, UID, boot ID, systemd unit) is preserved per entry in a way flat text logs lose, which is exactly why forensic tooling prefers it when available.
auditd: Kernel-Level Visibility
Section titled “auditd: Kernel-Level Visibility”auditd is the Linux Audit daemon — it hooks directly into the kernel’s audit subsystem to log security-relevant events (execve, file access, permission changes) with a level of detail syslog was never designed to provide.
sequenceDiagram
participant Kernel
participant AuditSub as Kernel Audit Subsystem
participant Auditd as auditd daemon
participant Log as /var/log/audit/audit.log
Kernel->>AuditSub: syscall event (matches a loaded rule)
AuditSub->>Auditd: emit audit record
Auditd->>Log: write structured event
Installing and controlling auditd
Section titled “Installing and controlling auditd”sudo apt install auditd audispd-plugins # Debian/Ubuntusudo systemctl enable --now auditdsudo auditctl -l # list currently loaded rulesWriting audit rules
Section titled “Writing audit rules”# Watch for ANY execution (a process being run) system-widesudo auditctl -a always,exit -F arch=b64 -S execve -k exec_tracking
# Watch a specific sensitive file for any write accesssudo auditctl -w /etc/shadow -p wa -k shadow_watch
# Watch for any changes to sudoerssudo auditctl -w /etc/sudoers -p wa -k sudoers_watch-k attaches a searchable “key” tag to matching events, which makes querying far easier:
sudo ausearch -k shadow_watch # find all events tagged with this keysudo ausearch -k exec_tracking -i # -i "interprets" numeric UIDs/syscalls into namessudo aureport --auth # summarized authentication reportsudo aureport -x # summarized executable reportPersisting rules across reboots means writing them into /etc/audit/rules.d/audit.rules rather than only running auditctl interactively (which is lost on reboot).
Why this matters: this is precisely the mechanism behind “we can see exactly what command an attacker ran, as what user, at what time” in almost every real Linux incident response writeup —
auditd’sexecvetracking is what turns “a process ran” into “here is the full command line, working directory, and parent process for every single execution on this box.”
Hardening: Reducing What Can Go Wrong
Section titled “Hardening: Reducing What Can Go Wrong”The CIS Benchmark mental model
Section titled “The CIS Benchmark mental model”The Center for Internet Security (CIS) publishes distro-specific hardening benchmarks (e.g., “CIS Ubuntu 22.04 Benchmark”) that are the industry-standard checklist for “what does a hardened Linux box look like.” You won’t memorize every control, but understanding the categories gives you the right mental model:
mindmap
root((CIS-style Hardening Categories))
Filesystem
Separate partitions
Disable unused filesystems
Mount options - noexec/nosuid
Services
Disable unnecessary daemons
Remove unused packages
Network
Firewall default-deny
Disable IPv6 if unused
Kernel network hardening sysctl
Access control
SSH hardening
sudo least privilege
Password policy / PAM
Logging & auditing
auditd rules
Centralized log shipping
Log rotation and retention
Concrete, immediately-actionable hardening steps
Section titled “Concrete, immediately-actionable hardening steps”Firewall — default deny with ufw or nftables:
sudo ufw default deny incomingsudo ufw default allow outgoingsudo ufw allow 22/tcp # only what you actually needsudo ufw enablesudo ufw status verboseSSH hardening (revisit /etc/ssh/sshd_config):
PermitRootLogin noPasswordAuthentication noPubkeyAuthentication yesAllowTcpForwarding no # unless the box legitimately needs tunneling (see previous chapter)MaxAuthTries 3Kernel network hardening via sysctl:
net.ipv4.conf.all.rp_filter = 1 # anti-spoofing (reverse path filtering)net.ipv4.icmp_echo_ignore_broadcasts = 1net.ipv4.tcp_syncookies = 1 # SYN flood mitigationnet.ipv4.conf.all.accept_redirects = 0kernel.dmesg_restrict = 1 # unprivileged users can't read kernel logssudo sysctl --systemPassword and account policy via PAM (/etc/pam.d/common-password on Debian):
password requisite pam_pwquality.so retry=3 minlen=14 difok=3fail2ban — automated brute-force banning:
sudo apt install fail2bansudo systemctl enable --now fail2bansudo fail2ban-client status sshd # see currently banned IPs for the SSH jailfail2ban watches log files (often auth.log/journald) for repeated failure patterns and dynamically inserts firewall rules to ban the offending IP for a configurable window — a lightweight, extremely common first line of defense against SSH brute forcing.
Mandatory Access Control: AppArmor and SELinux
Section titled “Mandatory Access Control: AppArmor and SELinux”Standard Linux permissions (covered in Chapter 3) are discretionary — the file owner decides who can access it. Mandatory Access Control (MAC) systems add a second, kernel-enforced layer that even root cannot casually bypass, confining what a process can do regardless of file permissions.
- AppArmor (Ubuntu/Debian default) — profiles are path-based and relatively easy to read:
/etc/apparmor.d/usr.sbin.nginxrestricts exactly what the nginx binary can touch, network-wise and filesystem-wise. - SELinux (RHEL/CentOS/Fedora default) — label-based, more powerful and more complex, using “contexts” (
system_u:object_r:httpd_sys_content_t) rather than plain paths.
# AppArmorsudo aa-status # see loaded profiles and their mode (enforce/complain)sudo aa-enforce /etc/apparmor.d/usr.sbin.nginxsudo aa-complain /etc/apparmor.d/usr.sbin.nginx # log-only mode, useful while tuning a new profile
# SELinuxgetenforce # Enforcing / Permissive / Disabledsudo setenforce 1 # force Enforcing models -Z /var/www/html/ # view SELinux contexts on filessudo semanage fcontext -a -t httpd_sys_content_t "/srv/web(/.*)?"Why this matters offensively too: a huge number of real-world web app exploits that “should” have led to full RCE are actually contained by SELinux/AppArmor — the process gets code execution, but the MAC policy blocks it from reading
/etc/shadowor making outbound connections. RecognizingPermission deniederrors that don’t match normal Unix permissions is a strong signal you’ve hit a MAC policy, not a Unix permission wall — checkingdmesg | grep -i apparmororausearch -m avcconfirms it instantly.
Building a Practical Hardening + Audit Lab
Section titled “Building a Practical Hardening + Audit Lab”In a lab VM:
- Install
auditdand add a watch rule on/etc/passwdand/etc/shadow(-w /etc/shadow -p wa -k shadow_watch). - Trigger it:
sudo cat /etc/shadow > /dev/null, then confirm the event withausearch -k shadow_watch -i. - Set up
ufwwith a default-deny incoming policy, allow only SSH, and verify withnmapfrom another machine that no other ports respond. - Install
fail2ban, then from a second machine deliberately fail SSH login 5+ times and confirm the source IP gets banned (fail2ban-client status sshd). - Check
aa-status(orgetenforceon an RHEL-family box) and note which profiles/policies are active versus complain/permissive — a real hardening review would flag every “complain”/“permissive” entry as a gap to close.
This lab exercises the full loop: harden something, generate the exact event that should be caught, and confirm your logging/audit layer actually caught it — the habit that separates “we have a firewall” from “we have evidence our firewall does anything.”
Advanced Techniques & Edge Cases
Section titled “Advanced Techniques & Edge Cases”- Log tampering is a real attacker technique. Attackers with root frequently clear or edit
/var/log/auth.log,wtmp, or shell history to hide tracks. Immutable, remote log shipping (forwarding logs to a separate syslog/SIEM server the moment they’re generated) defeats this — if the log left the box before it was deleted locally, the attacker’s cleanup is too late. - Auditd rule ordering and performance. Overly broad rules (watching every
execveon a busy production server) generate enormous log volume and can measurably affect performance; scope rules to specific paths/UIDs where possible, or accept the overhead deliberately for high-value hosts. noexec/nosuidmount options on/tmpand other user-writable partitions block a large class of “drop a binary in/tmpand execute it” techniques used by both attackers and CTF privesc chains — but be aware some legitimate software (and some CTF exercises specifically) expect/tmpto be executable, so test before deploying broadly.- Rotation and retention tuning (
logrotate,journalctl --vacuum-size) matters for compliance: many standards (PCI-DSS) mandate a minimum retention period, and a box that silently rotates/deletes logs too aggressively can fail an audit even if the logging itself was configured correctly.
Real-World Application
Section titled “Real-World Application”- Compliance-driven hardening: CIS Benchmarks, PCI-DSS, HIPAA, and SOC 2 audits all reference concrete Linux configuration checks nearly identical to what’s in this chapter — hardening scripts built around CIS controls are standard deliverables in GRC and cloud security engagements.
- DFIR case studies: real breach post-mortems (e.g., numerous publicly documented ransomware and cryptomining incidents) repeatedly cite “no centralized logging,” “auth.log rotated/deleted before analysis,” or “auditd not installed” as the reason root cause could not be conclusively established — this chapter’s content is literally the difference between a resolvable incident and an unresolved one.
- Pentest reporting: a professional pentest report routinely includes a “detective controls” or “logging & monitoring” finding alongside pure vulnerability findings — testers are expected to comment on whether their own activity would have been detected, which requires understanding exactly what’s covered in this chapter.
Detection & Defense: Blue Team Angle
Section titled “Detection & Defense: Blue Team Angle”This entire chapter is the blue team angle, but concretely:
- Ship logs off-box immediately (syslog-ng/rsyslog forwarding, or an agent like Filebeat/Wazuh) so local tampering can’t erase evidence.
- Alert on auditd’s own health —
auditdstopping unexpectedly, orauditctl -lreturning fewer rules than expected, is itself a signal worth alerting on (it’s a known attacker technique to disable audit logging before further action). - Baseline
aa-status/getenforceacross your fleet — any host silently running in permissive/complain mode has quietly lost a real layer of defense, often without anyone noticing. - Watch
/etc/sudoers,/etc/passwd,/etc/shadow, and SSH config for unauthorized changes via file integrity monitoring plus theauditdwatches shown above — these four files/directories cover a disproportionate share of real persistence and privilege escalation activity.
Blue Team CTF / detection challenge angle — A very common exercise: given an
audit.log/auth.logexcerpt, identify what an attacker did, in order — typically login, privilege escalation attempt viasudoor a SUID binary, a suspiciousexecveof an unusual binary path, then log tampering. Reconstructing that timeline purely fromausearch/grepoutput is a recurring DFIR-flavored CTF category worth deliberate practice.
Bug Bounty Angle — Logging/hardening gaps aren’t directly reportable bugs in most bug bounty programs (they’re infrastructure config, usually out of scope), but they matter for two reasons: (1) some programs specifically include “insufficient logging” as a valid finding under OWASP’s broader vulnerability categories when chained with another bug, and (2) demonstrating that a vulnerability you found would have gone completely undetected (no logging, no alerting) is powerful supporting evidence when arguing for higher severity in your writeup.
CTF Angle — Forensics categories frequently hand you a log file (auth.log, audit.log, or a full disk image) and ask “what did the attacker do and in what order.” Tools:
ausearch,aureport,grep/awk(Chapter 7), andlast/lastb. Worked pattern: start withlastbfor failed logins to find the brute-force window,grep "Accepted"inauth.logfor the successful login, thenausearch -ts recent -k exec_tracking(if auditd was running) to reconstruct exactly what commands ran afterward.
Common Mistakes & How to Overcome Them
Section titled “Common Mistakes & How to Overcome Them”| Mistake | Symptom | Fix |
|---|---|---|
| Assuming default install is “secure enough” | Unnecessary services/ports exposed | Explicitly review and apply a CIS-style checklist |
| Local-only logging | Attacker deletes/edits logs, no evidence remains | Ship logs off-box in real time |
| Overly broad auditd rules | Massive log volume, missed signal in noise | Scope rules to specific sensitive paths/syscalls |
| Treating AppArmor/SELinux denials as “broken app” and disabling MAC entirely | Loses a real defense layer | Use complain/permissive mode to tune the profile instead of disabling it |
| No automated brute-force protection | SSH gets hammered continuously | Deploy fail2ban (or equivalent) as a baseline, not an afterthought |
Final Revision / Summary
Section titled “Final Revision / Summary”- Linux logs live in two overlapping worlds: classic flat-text syslog files (
/var/log/auth.log,/var/log/syslog) and the structuredjournaldstore queried viajournalctl. auditdhooks the kernel directly, giving execve-level and file-access-level visibility that syslog alone can’t provide —auditctlto set rules,ausearch/aureportto query them.- Hardening follows a repeatable shape: minimize attack surface (firewall default-deny, disable unused services), harden access control (SSH config, sudo, PAM password policy), add automated response (fail2ban), and add a mandatory access control layer (AppArmor/SELinux) as defense in depth.
- CIS Benchmarks are the industry reference checklist for “what does hardened actually mean” per distro.
- Mnemonic: “See it, Stop it, Seal it” — logging/auditd (see it), firewall/fail2ban/SSH hardening (stop it), AppArmor/SELinux (seal it even if the first two fail).
Cheat Sheet / Quick Reference
Section titled “Cheat Sheet / Quick Reference”# Logstail -f /var/log/auth.logjournalctl -u sshd --since todaylast -a / lastb / lastlog
# auditdsudo auditctl -w /etc/shadow -p wa -k shadow_watchsudo ausearch -k shadow_watch -isudo aureport --auth
# Firewallsudo ufw default deny incomingsudo ufw allow 22/tcpsudo ufw enable
# fail2bansudo fail2ban-client status sshd
# MACsudo aa-status # AppArmorgetenforce # SELinux
# sysctl hardeningsudo sysctl --systemPractice Labs & Resources
Section titled “Practice Labs & Resources”- CIS Benchmarks (cisecurity.org) — download the free PDF for Ubuntu or your distro of choice and work through the “Level 1” controls as a checklist against a lab VM.
- TryHackMe “Linux Hardening” and “Auditd” rooms — guided, graded exercises building auditd rules and confirming they fire.
- Lynis (
github.com/CISOfy/lynis) — a free automated hardening-audit tool; run it against your lab VM before and after applying this chapter’s steps to see a measurable score improvement. - HackTheBox / TryHackMe “DFIR”-tagged rooms — practice reconstructing an attacker timeline purely from log excerpts, mirroring the CTF Angle worked pattern above.
- OpenSCAP /
oscap— open-source tooling that can automatically evaluate a box against a CIS or DISA STIG profile, useful for turning this chapter’s manual checklist into an automated, repeatable scan.
Discussion
Questions, corrections, or something to add? Comment with your GitHub account.