Security Analysis & Controls
Objective
Conduct a structured threat assessment on a provided network topology representing a small business with a DMZ, internal LAN, and cloud-hosted application tier. Using the STRIDE threat model, identify attack vectors, rate risks using a likelihood-impact matrix, and implement compensating controls including Linux firewall rules (iptables/UFW), Azure Network Security Group rules, fail2ban configuration, and a hardened SSH policy. Document all findings in a structured security report.
Tools & Technologies
STRIDE threat modeling— Spoofing, Tampering, Repudiation, Information Disclosure, Denial of Service, Elevation of Privilegeiptables / UFW— Linux host-based firewallAzure NSG— cloud-layer network security groupsfail2ban— automated brute-force protectionNmap— port scanning and service enumerationLynis— Linux security audit toolOpenVAS / Greenbone— vulnerability scanningauditd— Linux kernel audit frameworkCIS Benchmarks— security hardening reference
Architecture Overview
Step-by-Step Process
Applied STRIDE to each system component, documenting threat descriptions, affected assets, and initial risk ratings before any controls were in place.
# Threat register excerpt (documented in spreadsheet)
# Asset: Web Server (DMZ)
# S — Spoofing: Attacker impersonates legitimate user via session hijacking
# T — Tampering: Defacement via web application vulnerability (SQLi/RCE)
# R — Repudiation: No access logging configured on web server
# I — Info Disc: Directory listing enabled, exposes file structure
# D — DoS: No rate limiting; susceptible to HTTP flood
# E — EoP: Running Apache as root increases blast radius
# Asset: SSH Service (Firewall/Servers)
# S — Spoofing: Password authentication enables credential stuffing
# D — DoS: Unlimited login attempts exhaust connection table
Used Nmap to enumerate open ports and services on the target topology, and Lynis to audit the Linux configuration against CIS benchmarks.
# Full port scan of web server
nmap -sV -sC -p- --min-rate 1000 172.16.1.10 -oN scan_webserver.txt
# OS detection and script scan
nmap -A -T4 192.168.1.50
# Linux security audit with Lynis
sudo lynis audit system --quick
# Review: /var/log/lynis.log
# Key findings: world-writable files, no password aging, no auditd
# Check for listening services
ss -tlnp
# Identify: Apache, sshd, mysqld, rpcbind (unexpected)
Replaced the permissive default policy with a deny-all baseline, adding explicit rules for each required service. Applied connection tracking to statefully permit established sessions.
# Flush existing rules and set deny-all defaults
sudo iptables -F
sudo iptables -X
sudo iptables -P INPUT DROP
sudo iptables -P FORWARD DROP
sudo iptables -P OUTPUT ACCEPT
# Allow loopback
sudo iptables -A INPUT -i lo -j ACCEPT
# Allow established/related connections
sudo iptables -A INPUT -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT
# Allow SSH only from management subnet
sudo iptables -A INPUT -p tcp --dport 22 -s 192.168.1.0/24 -j ACCEPT
# Allow HTTP/HTTPS to DMZ web server
sudo iptables -A INPUT -p tcp --dport 80 -j ACCEPT
sudo iptables -A INPUT -p tcp --dport 443 -j ACCEPT
# Log dropped packets
sudo iptables -A INPUT -j LOG --log-prefix "IPT-DROP: " --log-level 4
# Persist
sudo iptables-save | sudo tee /etc/iptables/rules.v4
Configured fail2ban with custom jails for SSH, Apache, and a custom application log pattern. Set ban thresholds appropriate for the environment.
# /etc/fail2ban/jail.local
[DEFAULT]
bantime = 3600
findtime = 600
maxretry = 5
banaction = iptables-multiport
[sshd]
enabled = true
port = 22
filter = sshd
logpath = /var/log/auth.log
maxretry = 3
bantime = 86400
[apache-auth]
enabled = true
port = http,https
filter = apache-auth
logpath = /var/log/apache2/error.log
maxretry = 5
sudo systemctl enable --now fail2ban
sudo fail2ban-client status
sudo fail2ban-client status sshd
Enabled the Linux audit daemon with rules to log privilege escalation, file access in sensitive directories, and all authentication events. Hardened SSH to use only ed25519 keys and modern ciphers.
# auditd rules — /etc/audit/rules.d/hardening.rules
-w /etc/passwd -p wa -k identity
-w /etc/shadow -p wa -k identity
-w /etc/sudoers -p wa -k sudoers
-a always,exit -F arch=b64 -S execve -F euid=0 -k root_commands
-w /var/log/auth.log -p rwa -k auth_log
sudo auditctl -R /etc/audit/rules.d/hardening.rules
sudo systemctl restart auditd
sudo ausearch -k identity | tail -20
# SSH hardening — /etc/ssh/sshd_config
Protocol 2
PermitRootLogin no
PasswordAuthentication no
PubkeyAuthentication yes
KexAlgorithms curve25519-sha256,[email protected]
Ciphers [email protected],[email protected]
MACs [email protected]
LoginGraceTime 30
MaxAuthTries 3
ClientAliveInterval 300
ClientAliveCountMax 2
sudo sshd -t # validate config
sudo systemctl restart ssh
Complete Workflow
Challenges & Solutions
- iptables rules not surviving reboots — Rules are in-memory only by default. Installed
iptables-persistentand usednetfilter-persistent saveto persist rules to/etc/iptables/rules.v4. - fail2ban banning legitimate admin IP — Initial config had no
ignoreipsetting. Added the management subnet to the[DEFAULT]ignore list in jail.local to prevent lockout. - auditd generating excessive log volume — The
-a always,exit -S execverule captured every single process execution. Narrowed to-F euid=0to audit only root-level command execution. - Post-hardening SSH connection refused — The new cipher list excluded the algorithm the management workstation's older OpenSSH client was using. Added one compatible modern cipher to allow the admin workstation to connect.
Key Takeaways
- STRIDE is most effective when applied per-component, not per-system — each asset has a different threat profile that requires targeted controls.
- Deny-all firewall policies with explicit allow rules are significantly more secure than permit-all with explicit deny — the attack surface is minimized by default.
- fail2ban requires an
ignoreipconfiguration for all management networks — getting locked out of a production server by your own security tool is a real operational risk. - auditd rules need careful tuning between coverage and log volume — over-auditing creates noise that obscures genuine security events during analysis.