Linux: Security and Hardening
Shield your Linux servers against intrusion, unauthorized escalation, and data theft. Master the principle of least privilege, SSH defense, Fail2ban, Mandatory Access Control (SELinux and AppArmor), kernel auditing, and encryption.
11.1 Security Basics
System security is a continuous defensive discipline rather than a one-time configuration step. Hardening a Linux installation requires minimizing exposure, isolating permissions, and enforcing defense-in-depth across network interfaces, local user accounts, and running background daemons.
11.1.1 Principle of Least Privilege
Every process, user, and background service should possess only the bare minimum system rights necessary to execute its intended function:
Least Privilege Guardrails
- Unprivileged Service Daemons:Never launch network-facing servers (such as Nginx, Redis, or PostgreSQL) as the root account. Allocate dedicated system accounts with non-login shells (e.g.,
/usr/sbin/nologin). - Scoped Sudo Privileges:Grant administrators granular sudo privileges in
/etc/sudoers.d/for explicit commands rather than unrestricted, persistent root shell access. - Filesystem Boundaries:Restrict write access to production application directories to the deployment user, granting the runtime web server process read-only permissions.
11.1.2 Attack Surface: Services, Ports, and Users
Every listening network port, active daemon, and authorized shell account represents a prospective point of exploitation. Reducing the attack surface minimizes these entry vectors:
| Exposure Vector | Inspection Command | Hardening Action |
|---|---|---|
| Listening Sockets | ss -tulnp | Stop unneeded services or bind them to localhost (127.0.0.1) |
| Enabled Daemons | systemctl list-unit-files --state=enabled | Disable unused boot services via sudo systemctl disable --now <unit> |
| Interactive Shells | grep -E 'sh$' /etc/passwd | Lock dormant accounts (passwd -l) and assign /sbin/nologin |
| Unused Packages | apt list --installed | Remove extraneous compilers, test utilities, and development tools |
Network and account audit
Load it, then press Enter to run the checks.
# 1. Inspect listening network sockets with process ownership sudo ss -tulnp # 2. Identify enabled systemd services scheduled to launch on boot systemctl list-unit-files --type=service --state=enabled # 3. Find all accounts with valid interactive login shells grep -E '(/bin/bash|/bin/sh)$' /etc/passwd # 4. Lock password and expire credentials for an inactive user sudo passwd -l tempuser sudo chage -E 0 tempuser
11.2 Securing Access
Remote administrative access is the primary focus of automated internet scans and brute-force intrusion attempts. Hardening the OpenSSH daemon, enforcing multi-factor authentication, and deploying dynamic rate limiters prevents unauthorized access.
11.2.1 Hardening OpenSSH Server
Enforce cryptographic public key authentication and disallow password attempts inside /etc/ssh/sshd_config.d/security.conf:
| Directive | Recommended Value | Security Defense Purpose |
|---|---|---|
| PermitRootLogin | no | Blocks direct root SSH logins; requires standard user authentication first |
| PasswordAuthentication | no | Completely disables password prompts; eliminates brute-force dictionary attacks |
| PubkeyAuthentication | yes | Enforces cryptographic key verification (RSA 4096-bit or Ed25519) |
| MaxAuthTries | 3 | Disconnects connection attempt after 3 unsuccessful authentication tries |
| ClientAliveInterval | 300 | Sends keepalive checks every 5 minutes to disconnect stale abandoned sessions |
Safe sshd configuration test
Validate the config before reloading the daemon.
# Test sshd configuration syntax without restarting the daemon sudo sshd -t # If test passes cleanly, reload sshd without terminating active connections sudo systemctl reload sshd
11.2.2 Fail2ban Against Brute-Force Attacks
Fail2ban scans system authentication logs in real time for repeated login failures. When an IP address exceeds the configured threshold, Fail2ban dynamically injects temporary firewall drop rules:
Fail2ban Jail Configuration
- /etc/fail2ban/jail.local:Create a local override configuration rather than modifying
jail.confdirectly to preserve custom rules across package updates. - bantime & findtime:Set
findtime = 600(10-minute window) andbantime = 3600(1-hour block) to penalize automated attack scripts. - fail2ban-client status sshd:Displays active jails, current banned IP count, and total failure attempts.
# /etc/fail2ban/jail.local [sshd] enabled = true port = ssh maxretry = 3 findtime = 600 bantime = 3600
Fail2ban setup and status
Enable the daemon, then check and unban.
# Start and enable daemon sudo systemctl enable --now fail2ban # Check jail status and unban an IP address if needed sudo fail2ban-client status sshd sudo fail2ban-client set sshd unbanip 192.0.2.1
11.2.3 Two-Factor Authentication (2FA / TOTP)
Multi-Factor SSH Authentication
- PAM Module (libpam-google-authenticator):Integrates standard Time-based One-Time Password (TOTP) algorithm support into Linux PAM stack.
- Dual-Factor Requirement:Require both an SSH key (something you have) and a TOTP token from an authenticator app (something generated) for maximum access security.
- Emergency Scratch Codes:Always save one-time emergency backup scratch codes in an offline encrypted password vault.
11.3 Mandatory Access Control
Standard Linux file permissions represent Discretionary Access Control (DAC), where owners decide permissions on their files. Mandatory Access Control (MAC) enforces kernel-level security policies that constrain programs and users regardless of standard root file permissions.
11.3.1 SELinux Modes and Contexts
Security-Enhanced Linux (SELinux) is standard on RHEL, Fedora, CentOS, and Rocky Linux. It assigns cryptographic labels (contexts) in the format user:role:type:level to every process, file, and network socket:
| SELinux Mode | Kernel Enforcement | Denials Logged | Runtime Command |
|---|---|---|---|
| Enforcing | Active policy enforced; unauthorized operations blocked | Logged to audit log | sudo setenforce 1 |
| Permissive | No operations blocked; used for debugging policy rules | Logged as warnings | sudo setenforce 0 |
| Disabled | SELinux kernel module inactive; requires reboot to alter | None | /etc/selinux/config |
SELinux inspection
Check mode, labels, and recent denials.
# View SELinux status and operational mode sestatus # Inspect security context labels on files (-Z flag) ls -lZ /var/www/html/ # Output: system_u:object_r:httpd_sys_content_t:s0 index.html # Restore default security context according to policy sudo restorecon -Rv /var/www/html/ # Inspect audit log for access vector cache (AVC) denial events sudo ausearch -m AVC,USER_AVC -ts recent
11.3.2 AppArmor Profiles
AppArmor is the default MAC system on Ubuntu, Debian, and openSUSE. It uses path-based profiles located in /etc/apparmor.d/. Profiles operate in either Enforce (blocks violations) or Complain (logs warnings without blocking) mode:
| Feature | AppArmor | SELinux |
|---|---|---|
| Primary Ecosystem | Ubuntu, Debian, openSUSE | RHEL, Rocky Linux, AlmaLinux, Fedora |
| Access Control Model | Path-based security profiles | Label-based Type Enforcement (TE) + MLS |
| Configuration Path | /etc/apparmor.d/ | /etc/selinux/config |
| Diagnostic Utility | aa-status, aa-complain, aa-enforce | sestatus, getenforce, restorecon |
AppArmor profile management
Check status, switch modes, and reload.
# View loaded AppArmor profiles and enforcement status sudo aa-status # Switch profile to Complain mode for non-blocking debugging sudo aa-complain /etc/apparmor.d/usr.sbin.nginx # Re-enable strict enforcement mode sudo aa-enforce /etc/apparmor.d/usr.sbin.nginx # Reload all profiles from configuration directory sudo systemctl reload apparmor
11.4 Auditing and Integrity
Continuous auditing and baseline integrity monitoring ensure you detect unauthorized configuration adjustments, file tampering, and malware installations promptly.
11.4.1 Linux Audit Daemon (auditd)
The auditd subsystem tracks kernel-level security events including system calls, unauthorized file modifications to sensitive configuration paths, and elevation events:
Audit Rule Definitions
- File Watches (auditctl -w):Watch specific files for write (
w) or attribute change (a) operations:auditctl -w /etc/shadow -p wa -k shadow_mod. - Query Records (ausearch):Search audit log events by identifier key:
ausearch -k shadow_mod --interpret. - Summary Reporting (aureport):Generate concise audit summaries for failed authentications (
aureport -au) and system anomalies.
11.4.2 Rootkit Detection and File Integrity (AIDE)
AIDE (Advanced Intrusion Detection Environment) computes cryptographic hashes of critical binaries, libraries, and configuration files to detect unauthorized tampering:
Integrity Verification Workflow
- 1. Initialize Baseline Hash Database:Run
sudo aideinitto snapshot clean system state, then activate withsudo cp /var/lib/aide/aide.db.new /var/lib/aide/aide.db. - 2. Verify Against Baseline:Execute
sudo aide --checkto identify modified binaries, altered permissions, or new unexpected files. - 3. Rootkit Scanners (rkhunter / chkrootkit):Scan for known rootkit signatures, hidden processes, and suspicious kernel modules.
11.4.3 Automated Security Scanning with Lynis
Lynis Host Auditing
- System Audit Execution:Run
sudo lynis audit systemto perform in-depth inspection of kernel settings, open ports, SSH configurations, and user accounts. - Hardening Index Score:Outputs an overall security hardening score (0-100) alongside actionable suggestions and prioritized warnings.
- Log Review:Detailed findings and recommendations are recorded in
/var/log/lynis.log.
11.5 Encryption
Protect confidential data at rest and in transit across three distinct layers: GPG for file-level encryption and signing, LUKS for full-disk block encryption, and Let's Encrypt for automated TLS certificates.
11.5.1 GPG (GNU Privacy Guard) Basics
GPG Cryptographic Operations
- Symmetric Encryption: gpg -c file.txt:Encrypts a file with a shared passphrase using AES256.
- Asymmetric Keypair: gpg --full-generate-key:Generates a public/private keypair for recipient-based encryption.
- Digital Signatures: gpg --detach-sign file.tar.gz:Creates a detached cryptographic signature to verify archive authenticity without modifying original content.
- Verification: gpg --verify file.tar.gz.sig file.tar.gz:Validates that the file has not been altered since the signature was generated.
GPG encryption and signing
Encrypt, decrypt, sign, and verify.
# Encrypt file symmetrically with AES-256 gpg --symmetric --cipher-algo AES256 secret.txt # Decrypt encrypted ciphertext file gpg --decrypt secret.txt.gpg > secret.txt # Sign release archive with detached ASCII-armored signature gpg --armor --detach-sign release.tar.gz # Verify detached signature against the archive gpg --verify release.tar.gz.asc release.tar.gz
11.5.2 LUKS Disk Encryption (Data at Rest)
Linux Unified Key Setup (LUKS) provides transparent block-device encryption managed through the cryptsetup utility:
LUKS Volume Lifecycle
- 1. Format Block Device: cryptsetup luksFormat /dev/sdb1:Initializes LUKS partition header and establishes key slots.
- 2. Open Mapping: cryptsetup open /dev/sdb1 secure_store:Decrypts partition and establishes a cleartext device mapper node at
/dev/mapper/secure_store. - 3. Format and Mount:Format device with standard ext4/xfs:
mkfs.ext4 /dev/mapper/secure_storeand mount to directory. - 4. Close Mapping: cryptsetup close secure_store:Unmounts filesystem and closes cryptographic mapping, locking data at rest.
11.5.3 TLS Certificates with Let's Encrypt (Data in Transit)
Certbot TLS Automation
- Automated Provisioning:Run
sudo certbot --nginx -d example.comto automatically validate domain ownership, issue an X.509 certificate, and configure Nginx. - Auto-Renewal Verification:Certbot installs a systemd timer (
certbot.timer). Test the renewal workflow usingsudo certbot renew --dry-run. - Certificate Paths:Certificates reside in
/etc/letsencrypt/live/<domain>/fullchain.pemwith private key inprivkey.pem.
11.6 Interactive Lab: Security Auditing and User Shells
Practice identifying system accounts, checking listening network ports, and reviewing SSH server defaults with the commands below. Press Load in Terminal to open them in the Linux terminal:
Security Auditing and User Shells
Load these in the terminal, then press Enter to run them.
$ grep -E "(/bin/bash|/bin/sh)$" /etc/passwd$ ss -tuln$ id$ cat /etc/issue$ cat /etc/ssh/sshd_config
Knowledge Check: Module 11 Security and System Hardening
1. Which SSH configuration directive prevents attackers from logging in directly as the superuser?
2. Which tool monitors authentication logs and bans offending IP addresses using firewall rules?
3. In SELinux, which command restores the default security file contexts defined by system policy?
4. What are the two operational modes for AppArmor security profiles?
5. Which utility queries and filters events logged by the Linux audit daemon auditd?
6. Which command-line tool manages block device encryption using the LUKS standard?