Defense in Depth
Defense in depth is the principle that no single security control should be the sole barrier between an attacker and your assets. Controls are layered so that if one fails - through misconfiguration, zero-day vulnerability, or user error - others remain. Each layer reduces likelihood of full compromise.
External attacker │ ▼ [Network perimeter firewall] ← Layer 1: stops port scans, blocks known-bad IPs │ bypassed? ▼ [Network IDS/IPS] ← Layer 2: detects/blocks malicious traffic patterns │ bypassed? ▼ [Host-based firewall] ← Layer 3: restricts per-host network access │ bypassed? ▼ [OS access controls + auth] ← Layer 4: requires valid credentials │ bypassed? ▼ [Application-level controls] ← Layer 5: input validation, auth, ACLs │ bypassed? ▼ [Data encryption at rest] ← Layer 6: even raw disk access reveals nothing │ Attacker has encrypted bytes - useless without the keyAttack Surface Reduction
Section titled “Attack Surface Reduction”Attack Vectors and Attack Surface
Section titled “Attack Vectors and Attack Surface”Attack vector: a specific method by which an attacker can gain access (email attachment, open port, unpatched service, physical USB).
Attack surface: the sum of all attack vectors - everything exposed that an attacker could potentially interact with.
The core principle: reduce the attack surface to reduce the chance any vector leads to compromise.
Large attack surface: Small attack surface:───────────────────────────── ────────────────────────────────Many open ports Only necessary ports openMany installed services Only required services runningAll users are local admins Least privilege; no local admin by defaultDefault credentials unchanged All defaults changed; secrets rotatedOld software versions Patch management in place; latest versionsUsers can install software Application allowlisting enforcedVerbose error messages Generic error messages; logging internallyNo network segmentation VLANs + ACLs between segmentsDisabling Unnecessary Components
Section titled “Disabling Unnecessary Components”# Linux: list all running services and disable what's not neededsystemctl list-units --type=service --state=running
# Disable a service permanentlysystemctl disable --now avahi-daemon # mDNS - rarely needed on serverssystemctl disable --now cups # printing service - not on serverssystemctl disable --now rpcbind # NFS dependency - remove if no NFS
# Check open ports (what's listening)ss -tulpn # show all listening sockets + process namesnmap -sS localhost # external view of open ports
# Remove unused packagesapt list --installed 2>/dev/null | grep -v base # review installed packagesapt autoremove # remove orphaned dependencies# Windows: disable unnecessary servicesGet-Service | Where-Object { $_.Status -eq "Running" } | Select-Object Name, DisplayNameSet-Service -Name "Fax" -StartupType DisabledStop-Service -Name "Fax"
# List listening ports with process namesnetstat -tulpn # Linuxnetstat -ano | findstr LISTEN # WindowsHost-Based Firewalls
Section titled “Host-Based Firewalls”Network firewalls protect the perimeter. Host-based firewalls protect individual machines - even from compromised peers on the same internal network.
Why Host Firewalls Matter
Section titled “Why Host Firewalls Matter”An internal network is not “trusted.” Once an attacker compromises one machine, they pivot laterally. Host firewalls limit what a compromised peer can reach:
Scenario: Workstation A gets ransomware via phishing Without host firewall: ransomware spreads directly to File Server over SMB With host firewall on File Server: File Server only allows SMB from specific IPs → Ransomware blockediptables Basic Hardening
Section titled “iptables Basic Hardening”# Start with a clean slate - flush all rulesiptables -F && iptables -X
# Default policy: DROP everythingiptables -P INPUT DROPiptables -P FORWARD DROPiptables -P OUTPUT ACCEPT # usually allow all outbound; restrict as needed
# Allow loopbackiptables -A INPUT -i lo -j ACCEPT
# Allow established/related connections (stateful firewall - don't block responses)iptables -A INPUT -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT
# Allow SSH from management network onlyiptables -A INPUT -s 10.0.0.0/24 -p tcp --dport 22 -m conntrack --ctstate NEW -j ACCEPT
# Allow HTTPS from anywhereiptables -A INPUT -p tcp --dport 443 -m conntrack --ctstate NEW -j ACCEPT
# Log and drop everything elseiptables -A INPUT -j LOG --log-prefix "DROPPED: " --log-level 4iptables -A INPUT -j DROP
# Save rules permanentlyiptables-save > /etc/iptables/rules.v4# nftables (modern replacement for iptables)nft add table ip filternft add chain ip filter input { type filter hook input priority 0 \; policy drop \; }nft add rule ip filter input ct state established,related acceptnft add rule ip filter input ip saddr 10.0.0.0/24 tcp dport 22 acceptnft add rule ip filter input tcp dport 443 acceptBastion Hosts
Section titled “Bastion Hosts”A bastion host is a hardened, minimally exposed host that acts as the single entry point into a sensitive network zone:
Internet │ ▼[Bastion Host] - only SSH/RDP port exposed; hardened OS; enhanced logging │ ▼[Internal Admin Network] - only accessible FROM bastion ├── Core Auth Servers (AD/LDAP/RADIUS) ├── Database servers └── Infrastructure devices (routers, switches)Bastion host hardening:
- Full disk encryption
- No unnecessary services (single-purpose)
- Strict firewall rules (allow only from known IPs)
- Certificate-only SSH access (no password auth)
- All sessions logged (with
auditd/tlog/Teleport) - MFA required for access
# SSH hardening on a bastion host (/etc/ssh/sshd_config)PermitRootLogin noPasswordAuthentication noChallengeResponseAuthentication noUsePAM yes # allows PAM MFA integrationPubkeyAuthentication yesAuthorizedKeysFile .ssh/authorized_keysAllowGroups bastion-users # restrict to specific groupClientAliveInterval 300 # disconnect idle sessions after 5 minClientAliveCountMax 0LogLevel VERBOSE # log all key fingerprintsLogging, Monitoring and SIEM
Section titled “Logging, Monitoring and SIEM”What to Log
Section titled “What to Log”Minimum security log coverage: Authentication events → successful logins, failures, lockouts, MFA challenges Privilege escalation → sudo, su, runas, setuid executions Network connections → firewall allow/deny, VPN connect/disconnect File access → reads/writes to sensitive directories (/etc, /root, PCI data) Process execution → new process creation (especially unusual paths/parents) System changes → configuration changes, software installs, user creation DNS queries → unusual domains; C2 callback detection# Configure auditd to log privilege escalation and file access# Monitor /etc/passwd and /etc/shadow modification-w /etc/passwd -p wa -k identity-w /etc/shadow -p wa -k identity-w /etc/sudoers -p wa -k sudoers
# Log all commands run via sudo-a always,exit -F arch=b64 -S execve -F uid=0 -k root_commands
# Log writes to sensitive areas-w /etc/ -p wa -k etc_changes-w /tmp/ -p wx -k tmp_exec
# Reload rulesauditctl -R /etc/audit/rules.d/hardening.rulesausearch -k sudoers # review sudoers changesSIEM Overview
Section titled “SIEM Overview”A SIEM (Security Information and Event Management) system:
- Collects logs from endpoints, servers, firewalls, applications
- Normalises different formats into a common schema
- Correlates events across multiple systems and timewindows
- Alerts when correlation rules match (e.g., “5 failed logins, then success, from same IP”)
- Retains logs for compliance periods
| SIEM | Notes |
|---|---|
| Splunk Enterprise Security | Industry standard; powerful query language (SPL); expensive |
| Elastic SIEM (ELK Stack) | Open-source; highly customisable; more setup effort |
| Microsoft Sentinel | Cloud-native; integrates with Azure/M365; pay-per-GB |
| IBM QRadar | Enterprise; strong compliance reporting |
| rsyslog + Graylog | Self-hosted; lower cost; less ML/automation |
# Centralise logs with rsyslog - forward to SIEM over TCP*.* @@siem.internal:514 # TCP (reliable)# or*.* @siem.internal:514 # UDP (lower overhead)
# Send only auth logs to SIEMauth,authpriv.* @@siem.internal:514
# Verify rsyslog is forwardingsystemctl restart rsysloglogger "test message from $(hostname)" # check SIEM receives itAntimalware Protection
Section titled “Antimalware Protection”Antivirus
Section titled “Antivirus”Antivirus uses signatures - databases of known malware patterns. It:
- Monitors new/modified files for matching patterns
- Scans email attachments and downloads
- Can detect known threats quickly and cheaply
Limitations:
- Zero-day malware has no signature yet - undetected until vendor releases signature update
- Polymorphic malware mutates to avoid signature match
- AV software itself has a large attack surface (runs at high privilege, processes untrusted content)
Binary Allowlisting (Application Allowlisting)
Section titled “Binary Allowlisting (Application Allowlisting)”Instead of blocking known-bad (blocklist/AV), allowlisting only permits known-good:
Blocklist (AV model): Allow everything EXCEPT known-badAllowlist model: Block everything EXCEPT known-good approved softwareAdvantages:
- Blocks unknown/zero-day malware automatically
- Prevents users installing unapproved software
Disadvantages:
- High operational overhead - every new app must be reviewed and approved
- Software updates must be re-approved or signature-verified
- Vendor code-signing certificates become a trust anchor
# Linux: use AppArmor (profile-based) or SELinux (label-based)# AppArmor - restrict what an application can doaa-genprof /usr/bin/nginx # generate a profile by watching executionaa-enforce /usr/bin/nginx # enforce the profileapparmor_status # show enforced/complaining profiles
# SELinux - check what's being blockedgetenforce # shows Enforcing/Permissive/Disabledausearch -m AVC -ts recent # show recent SELinux denialsaudit2allow -a # suggest policy to allow denied actionsSoftware Signing and Trust
Section titled “Software Signing and Trust”Binary allowlisting systems can be configured to trust code-signing certificates:
Software vendor signs binary: Sign: openssl dgst -sha256 -sign vendor-key.pem -out app.sig app.bin Verify: openssl dgst -sha256 -verify vendor-cert.pem -signature app.sig app.bin
Trust chain: Root CA → Vendor CA → Vendor code signing cert → signed binaryFull Disk Encryption (FDE)
Section titled “Full Disk Encryption (FDE)”FDE ensures that if a device is physically stolen, the data is unreadable without the key.
How FDE Works
Section titled “How FDE Works”Boot sequence with FDE: Power on → UEFI/BIOS loads bootloader from encrypted disk → User enters passphrase (or TPM provides key automatically) → Disk encryption key unlocked → OS boots normally
Without passphrase: Stolen disk appears as encrypted random bytes - useless to attackerKey Storage Strategies
Section titled “Key Storage Strategies”| Strategy | How | Trade-off |
|---|---|---|
| Passphrase only | User enters passphrase at every boot | Secure; inconvenient; remote reboot = locked out |
| TPM-sealed key | Key sealed to TPM; auto-released if PCR values match | Transparent to user; vulnerable to PCR bypass attacks |
| TPM + PIN | TPM provides part of key; user provides PIN | Balance of security and automation |
| Key escrow | Backup recovery key stored securely by IT | Allows recovery if passphrase forgotten |
# Linux: LUKS full disk encryption# Check if disk is encryptedcryptsetup status /dev/mapper/sda2_crypt
# View LUKS header infocryptsetup luksDump /dev/sda2
# Add a recovery key (key escrow)cryptsetup luksAddKey /dev/sda2 # prompts for new passphrase
# Backup the LUKS header (critical - store securely offsite)cryptsetup luksHeaderBackup /dev/sda2 --header-backup-file /secure/sda2-luks-header.bin
# macOS: Check FileVault statusfdesetup statusfdesetup list # list users who can unlock
# Windows: Check BitLocker statusmanage-bde -status C:manage-bde -protectors -get C: # see key protectors (TPM, Recovery Key, etc.)Secure Boot
Section titled “Secure Boot”Secure Boot prevents an attacker with physical access from replacing boot components with malicious versions:
Without Secure Boot: Attacker boots from USB → replaces bootloader → installs rootkit at boot level
With Secure Boot: UEFI checks bootloader signature against stored Platform Key (PK) Unsigned or untrusted bootloader → refused to executeSecure Boot chain: UEFI firmware (PK) → Key Exchange Key (KEK) → Signature Database (db) → bootloader signature
# Check Secure Boot status on Linuxmokutil --sb-state# Or via kernelcat /sys/firmware/efi/efivars/SecureBoot-*/ # raw value
# Check on WindowsConfirm-SecureBootUEFI # PowerShell - returns True if Secure Boot enabledSoftware Patch Management
Section titled “Software Patch Management”Unpatched software is the single most common entry point in enterprise breaches. Heartbleed, EternalBlue (MS17-010), Log4Shell - all were fully patchable before exploitation.
Patch Prioritisation
Section titled “Patch Prioritisation”Risk = CVSS Score × Asset Criticality × Exploitation Status
Priority: Critical (CVSS 9.0+) + internet-facing + exploit in wild → patch within 24–48h High (7.0–8.9) + internal service + PoC public → patch within 1 week Medium (4.0–6.9) + no known exploit → patch within 30 days Low (<4.0) → next scheduled window# Debian/Ubuntu: check for security updatesapt list --upgradable 2>/dev/null | grep -i securityunattended-upgrade --dry-run -v # preview what auto-upgrade would do
# RHEL/CentOS: check security advisoriesyum updateinfo list securitydnf check-update --security
# View CVEs patched by a specific package updateapt changelog <package> | grep CVE
# Windows: check for missing patches with PowerShellGet-HotFix | Sort-Object InstalledOn | Select-Object -Last 10(New-Object -ComObject Microsoft.Update.Session).CreateUpdateSearcher().Search("IsInstalled=0").UpdatesPatch Testing Process
Section titled “Patch Testing Process”New patch released → Test in non-production environment (staging/dev) → Validate that critical services still function → Check for regressions (automated test suite where available) → Deploy to small pilot group → Monitor for 24–48h → Deploy to full fleet via patch management tool (WSUS, Ansible, Puppet, SCCM)Application and Browser Hardening
Section titled “Application and Browser Hardening”Application Policy Categories
Section titled “Application Policy Categories”| Category | Policy |
|---|---|
| Allowed software | Only business-related applications; approved via IT request |
| Banned categories | P2P/torrent software, licence key generators, cracked software, personal cloud sync to unmanaged storage |
| Update requirement | Must be on N or N-1 version; patches applied within SLA |
| Browser extensions | Allowlist of approved extensions; all others blocked via GPO/MDM |
Browser Security Hardening
Section titled “Browser Security Hardening”# Check TLS certificate from command lineopenssl s_client -connect example.com:443 -servername example.com 2>/dev/null | \ openssl x509 -noout -subject -issuer -dates
# Verify site certificate chainopenssl s_client -connect example.com:443 -showcerts 2>/dev/null | \ grep -E "subject|issuer"
# Verify file hash matches developer-published hashsha256sum downloaded-file.tar.gz# Compare to hash published on vendor websiteBrowser hardening policy elements:
- HTTPS enforced - block HTTP navigation to sensitive sites (HSTS preload list)
- Certificate validation - alert on invalid/expired certs; block if revoked (OCSP)
- Extension control - only IT-approved extensions permitted (enforced via GPO/MDM profile)
- Password manager - company-approved password manager required; browser native storage for work accounts
- Sync control - disable sync to personal accounts on managed browsers
- Content security - ad blocker + script blocker on high-risk sites
# Chrome enterprise policy (deploy via GPO or Intune)# Block extensions not in allowlist{ "ExtensionInstallBlocklist": ["*"], "ExtensionInstallAllowlist": [ "ghbmnnjooekpmoecnnnilnnbdlolhkhi", # Google Docs Offline "...approved extension IDs..." ], "ExtensionInstallForcelist": [ "cfhdojbkjhnklbpkdaibdccddilifddb" # Adblock Plus (force-install) ]}Defense in Depth Checklist
Section titled “Defense in Depth Checklist”Use this as a baseline hardening checklist:
NETWORK LAYER [ ] Perimeter firewall with implicit deny + allow-list [ ] Network IDS/IPS deployed (Snort/Suricata) [ ] VLANs separating user, server, management, guest traffic [ ] DHCP snooping + DAI + IPSG on switches [ ] WPA3 or 802.1X for wireless
HOST LAYER [ ] Host-based firewall enabled (iptables/nftables/Windows Firewall) [ ] Full disk encryption (LUKS, BitLocker, FileVault) [ ] Secure Boot enabled [ ] Antivirus/EDR installed and updated [ ] Local admin rights removed from standard users [ ] Unnecessary services disabled and ports closed
APPLICATION LAYER [ ] All software on latest supported version [ ] Patch SLA defined and enforced (critical: 48h, high: 1 week) [ ] Application allowlisting where feasible [ ] Browser extension allowlist enforced [ ] Input validation + parameterised queries in web apps
IDENTITY LAYER [ ] MFA required for all accounts (admin: hardware key) [ ] Least privilege: no standing admin rights; just-in-time access [ ] Service accounts use managed identities, not human credentials [ ] Password manager deployed; complexity requirements enforced
DATA LAYER [ ] Data classification policy in place [ ] Sensitive data encrypted at rest and in transit [ ] Backup policy: 3-2-1 (3 copies, 2 media types, 1 offsite) [ ] Backup restoration tested regularly [ ] Data destruction process for decommissioned hardware
MONITORING LAYER [ ] Centralised logging (rsyslog → SIEM) [ ] Authentication events logged and alerted on failures [ ] Privileged access logging (sudo, admin actions) [ ] Log retention meets compliance requirements [ ] Incident response plan documented and tested (tabletop annually)