kavklaw@llm $ cat network-defense-guide.md
β±οΈ 25 min read Β· Build layered network defenses that detect, block, and monitor threats
Network defense is hands-on β you'll need access to systems you're defending or a lab environment to practice in:
iptables/nftables (Linux) or Windows Firewall. For practice, any Linux VM will do.sudo apt install snort) or Suricata (sudo apt install suricata). Both are free and open source. Snort 3 and Suricata are both multi-threaded. Performance depends on traffic, rules, and hardware β benchmark in your environment.tcpdump (CLI). Both pre-installed on most security distros.For a home lab, two VMs on a virtual network give you everything you need: one as the "server" running iptables/Snort, and one as the "attacker" generating traffic to test your rules.
Need to harden a Linux server right now? This iptables configuration creates a "default deny" firewall β it drops all incoming traffic except what you explicitly allow (SSH, HTTP, HTTPS). Even if you've never configured a firewall before, you can copy these commands and have a solid baseline in under 5 minutes:
# Basic iptables hardening for a web server
# ββββββββββββββββββββββββββββββββββββββββββ
# Flush existing rules
sudo iptables -F
sudo iptables -X
# Set default policies: deny everything
sudo iptables -P INPUT DROP
sudo iptables -P FORWARD DROP
sudo iptables -P OUTPUT ACCEPT
# Allow loopback (localhost traffic)
sudo iptables -A INPUT -i lo -j ACCEPT
# Allow established/related connections (this is the key rule β it lets
# responses to YOUR outgoing requests come back in, while still blocking
# unsolicited incoming connections)
sudo iptables -A INPUT -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT
# Allow SSH (restrict to your IP if possible!)
sudo iptables -A INPUT -p tcp --dport 22 -s YOUR_IP/32 -j ACCEPT
# Allow HTTP and HTTPS
sudo iptables -A INPUT -p tcp --dport 80 -j ACCEPT
sudo iptables -A INPUT -p tcp --dport 443 -j ACCEPT
# Allow ICMP ping (optional)
sudo iptables -A INPUT -p icmp --icmp-type echo-request -j ACCEPT
# Log dropped packets (for monitoring)
sudo iptables -A INPUT -j LOG --log-prefix "DROPPED: " --log-level 4
# Save the rules (persist across reboots)
sudo iptables-save | sudo tee /etc/iptables/rules.v4
# Or on RHEL (legacy): sudo service iptables save
# Note: Modern RHEL/CentOS uses firewalld (firewall-cmd) or nftables instead of iptables
That's a solid starting point. Let's build a thorough understanding of network defense.
Defense in depth is the foundational strategy of network security: use multiple layers of defense so that if one layer fails, others still protect you. No single security control is perfect β layering compensates for individual weaknesses.
ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β Defense in Depth Layers β
β β
β Layer 7: MONITORING & RESPONSE β
β βββ SIEM (centralized log monitoring), log analysis, IR β
β β
β Layer 6: DATA SECURITY β
β βββ Encryption, access controls, DLP (Data Loss Prevention)β
β β
β Layer 5: APPLICATION SECURITY β
β βββ Secure coding, input validation, WAF rules β
β β
β Layer 4: HOST SECURITY β
β βββ OS hardening, EDR, host firewall β
β β
β Layer 3: INTRUSION DETECTION/PREVENTION β
β βββ IDS/IPS (Snort, Suricata) β
β β
β Layer 2: NETWORK SEGMENTATION β
β βββ VLANs, DMZ, internal firewalls β
β β
β Layer 1: PERIMETER DEFENSE β
β βββ Firewalls, WAF, DDoS protection β
ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
Each layer addresses different threats: the perimeter blocks known-bad traffic, segmentation limits lateral movement if breached, IDS/IPS catches attack patterns, host security protects individual systems, application security prevents code-level attacks, data security is the last line of defense, and monitoring catches what slips through everything else.
Every layer serves a purpose. Firewalls block unauthorized traffic but can't inspect encrypted content. IDS detects attack patterns but can't block a zero-day. Encryption protects data but doesn't prevent unauthorized access by someone with legitimate credentials. Together, they create a defense that's much stronger than any individual component.
Not all firewalls are created equal. Understanding the types helps you choose the right tool for each layer:
The simplest firewall type. Examines each packet individually based on source/destination IP, ports, and protocol. It has no concept of "sessions" or "connections."
Stateless firewall decisions: "Is this packet allowed based on my rules?" Checks source IP, destination port, and protocol for each packet independently.
Weakness: can't track connection state. An attacker can send ACK packets that "look like" responses to connections that never existed.
Tracks the state of network connections. Understands that an incoming SYN-ACK is a response to an outgoing SYN, so it only allows packets that belong to legitimate conversations.
A stateful firewall maintains a connection table tracking source/destination IPs, ports, and state (NEW, ESTABLISHED, RELATED). When a response packet arrives, it checks: "Does this belong to a known connection?" If yes β allow. If no β drop.
# iptables is a STATEFUL firewall when using conntrack:
sudo iptables -A INPUT -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT
# This rule handles all legitimate response traffic automatically
Adds application awareness, deep packet inspection, and integrated IPS. Can identify and control applications regardless of port (e.g., blocking BitTorrent even on port 80).
NGFW capabilities:
Examples: Palo Alto, Fortinet FortiGate, Cisco Firepower. For home/small business: pfSense, OPNsense (open source).
Specifically protects web applications by inspecting HTTP/HTTPS traffic for attacks like SQL injection, XSS, and directory traversal.
WAF operates at Layer 7 (application layer), inspecting HTTP requests for malicious patterns: SQL injection (' OR 1=1 --), XSS (<script>), directory traversal (../../etc/passwd), command injection, and file inclusion.
Tools: ModSecurity (open source, works with Apache/Nginx/IIS), OWASP Core Rule Set (CRS), AWS WAF, Azure WAF, Cloudflare WAF (cloud-native).
ModSecurity example rule:
SecRule REQUEST_URI "@detectSQLi" \
"id:942100,\
phase:2,\
block,\
msg:'SQL Injection Attack Detected'"
iptables is the traditional Linux firewall tool (actually a front-end for the netfilter kernel framework). nftables is its modern replacement, but iptables remains widely used.
# iptables chain architecture:
# ββββββββββββββββββββββββββ
# INCOMING traffic: β PREROUTING β INPUT β (local process)
# OUTGOING traffic: (local process) β OUTPUT β POSTROUTING β
# FORWARDED traffic: β PREROUTING β FORWARD β POSTROUTING β
#
# Each chain has a DEFAULT POLICY (ACCEPT or DROP)
# Rules are evaluated top-to-bottom; first match wins
# View current rules
sudo iptables -L -n -v # List all rules with packet counts
sudo iptables -L -n --line-numbers # Show rule numbers
# === INPUT CHAIN (incoming traffic to this host) ===
# Allow all traffic from localhost
sudo iptables -A INPUT -i lo -j ACCEPT
# Allow established connections (critical rule!)
sudo iptables -A INPUT -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT
# Allow SSH from specific subnet
sudo iptables -A INPUT -p tcp --dport 22 -s 10.0.0.0/24 -j ACCEPT
# Allow HTTP and HTTPS from anywhere
sudo iptables -A INPUT -p tcp --dport 80 -j ACCEPT
sudo iptables -A INPUT -p tcp --dport 443 -j ACCEPT
# Rate limit SSH connections (anti-brute-force)
sudo iptables -A INPUT -p tcp --dport 22 -m conntrack --ctstate NEW \
-m recent --set --name SSH
sudo iptables -A INPUT -p tcp --dport 22 -m conntrack --ctstate NEW \
-m recent --update --seconds 60 --hitcount 4 --name SSH -j DROP
# Block specific IP
sudo iptables -A INPUT -s 192.168.1.100 -j DROP
# Log then drop all other incoming traffic
sudo iptables -A INPUT -j LOG --log-prefix "INPUT DROP: "
sudo iptables -A INPUT -j DROP
# === OUTPUT CHAIN (outgoing traffic from this host) ===
# Block outgoing connections to a specific IP (C2 blocking)
sudo iptables -A OUTPUT -d 185.234.72.19 -j DROP
# === MANAGEMENT ===
# Delete a rule by number
sudo iptables -D INPUT 3
# Insert a rule at position (before other rules)
sudo iptables -I INPUT 1 -s 10.0.0.50 -j ACCEPT
# Flush all rules (reset)
sudo iptables -F
# Save rules (persist across reboot)
sudo iptables-save > /etc/iptables/rules.v4 # Debian/Ubuntu
sudo service iptables save # RHEL/CentOS (legacy; modern RHEL uses firewalld/nftables)
# nftables syntax is cleaner and more powerful than iptables
# Create a basic server firewall with nftables
sudo nft add table inet filter
sudo nft add chain inet filter input { type filter hook input priority 0 \; policy drop \; }
sudo nft add chain inet filter forward { type filter hook forward priority 0 \; policy drop \; }
sudo nft add chain inet filter output { type filter hook output priority 0 \; policy accept \; }
# Allow loopback
sudo nft add rule inet filter input iifname lo accept
# Allow established connections
sudo nft add rule inet filter input ct state established,related accept
# Allow SSH, HTTP, HTTPS
sudo nft add rule inet filter input tcp dport { 22, 80, 443 } accept
# Rate limit SSH
sudo nft add rule inet filter input tcp dport 22 ct state new limit rate 3/minute accept
# Log and drop everything else
sudo nft add rule inet filter input log prefix \"INPUT DROP: \" drop
# View rules
sudo nft list ruleset
# Save configuration
sudo nft list ruleset > /etc/nftables.conf
# Windows Firewall with Advanced Security (PowerShell)
# ββββββββββββββββββββββββββββββββββββββββββββββββββββ
# View all firewall profiles
Get-NetFirewallProfile | Format-Table Name, Enabled, DefaultInboundAction
# Enable firewall on all profiles
Set-NetFirewallProfile -Profile Domain,Public,Private -Enabled True
# Set default deny inbound
Set-NetFirewallProfile -Profile Public -DefaultInboundAction Block
# Allow specific port
New-NetFirewallRule -DisplayName "Allow HTTP" -Direction Inbound -Protocol TCP -LocalPort 80 -Action Allow
# Allow RDP from specific subnet
New-NetFirewallRule -DisplayName "Allow RDP from Management" `
-Direction Inbound -Protocol TCP -LocalPort 3389 `
-RemoteAddress "10.0.0.0/24" -Action Allow
# Block outbound to specific IP (C2 blocking)
New-NetFirewallRule -DisplayName "Block C2" -Direction Outbound `
-RemoteAddress "185.234.72.19" -Action Block
# List all rules
Get-NetFirewallRule | Where-Object {$_.Enabled -eq "True"} |
Format-Table DisplayName, Direction, Action -AutoSize
# Disable a rule
Disable-NetFirewallRule -DisplayName "Allow HTTP"
# Remove a rule
Remove-NetFirewallRule -DisplayName "Allow HTTP"
# Export/Import firewall config
netsh advfirewall export "C:\firewall-backup.wfw"
netsh advfirewall import "C:\firewall-backup.wfw"
Intrusion Detection Systems (IDS) and Intrusion Prevention Systems (IPS) are like security cameras and guards for your network. They monitor traffic for malicious activity. The key difference is the response:
IDS (Intrusion Detection System) β PASSIVE: monitors and alerts, does NOT block
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
βββββββ ββββββββββ βββββββ
β Net βββββΆβ Switch βββββΆβ Net β Deployment: tap/span port
βββββββ ββββ¬ββββββ βββββββ Pros: no risk of blocking legit traffic
β (mirror) Cons: attacker isn't stopped
βΌ
βββββββββββ
β IDS β β Alerts to SIEM/analyst
βββββββββββ
IPS (Intrusion Prevention System) β ACTIVE: monitors AND blocks
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
βββββββ βββββββββββ βββββββ
β Net βββββΆβ IPS βββββΆβ Net β Deployment: inline
βββββββ βββββββββββ βββββββ Pros: stops attacks in real-time
β Cons: risk of false positives
βΌ Alerts + Blocks
Detection Methods:
Major Tools: Snort (open source, most widely used), Suricata (high-performance, multi-threaded), Zeek/Bro (network analysis framework).
Snort is the most widely used open-source IDS/IPS. It works by comparing network traffic against a set of rules you define. If traffic matches a rule, Snort fires an alert (or blocks it, if running in IPS mode). Understanding rule syntax lets you create custom detections for threats specific to your environment.
# Snort Rule Structure:
# action protocol src_ip src_port -> dst_ip dst_port (options)
# Basic rule: detect ICMP ping
alert icmp any any -> $HOME_NET any (msg:"ICMP Ping Detected"; sid:1000001; rev:1;)
# Detect SSH brute force (multiple connection attempts)
alert tcp $EXTERNAL_NET any -> $HOME_NET 22 \
(msg:"SSH Brute Force Attempt"; \
flow:to_server,established; \
threshold:type both, track by_src, count 5, seconds 60; \
sid:1000002; rev:1;)
# Detect SQL injection in HTTP
alert tcp $EXTERNAL_NET any -> $HOME_NET $HTTP_PORTS \
(msg:"SQL Injection Attempt"; \
flow:to_server,established; \
content:"UNION"; nocase; \
content:"SELECT"; nocase; distance:0; \
sid:1000003; rev:1;)
# Detect Nmap SYN scan
alert tcp $EXTERNAL_NET any -> $HOME_NET any \
(msg:"Nmap SYN Scan Detected"; \
flags:S; \
threshold:type both, track by_src, count 20, seconds 5; \
sid:1000004; rev:1;)
# Detect reverse shell (outbound shell to external IP)
alert tcp $HOME_NET any -> $EXTERNAL_NET any \
(msg:"Possible Reverse Shell"; \
flow:to_server,established; \
content:"/bin/sh"; \
sid:1000005; rev:1;)
# Detect PowerShell encoded command
alert tcp any any -> $HOME_NET any \
(msg:"Encoded PowerShell Command"; \
flow:to_server,established; \
content:"powershell"; nocase; \
content:"-enc"; nocase; distance:0; within:20; \
sid:1000006; rev:1;)
# Detect known C2 communication (IOC-based)
alert tcp $HOME_NET any -> [185.234.72.19] any \
(msg:"Known C2 Communication Detected"; \
sid:1000007; rev:1;)
Rule Options Reference:
msg: β alert messageflow: β direction and connection statecontent: β pattern to match in packet payloadnocase β case-insensitive matchingdistance: β offset from previous matchwithin: β how many bytes to search after distancethreshold: β rate limiting (don't alert on every packet)sid: β unique rule ID (custom rules: 1000001+)rev: β rule revision numberπ‘ Pro Tip: When writing Snort rules, be specific enough to minimize false positives but broad enough to catch variants. Test rules in IDS mode (alert only) before deploying in IPS mode (block). One bad rule that blocks legitimate traffic can cause a major outage.
threshold:type both, track by_src, count 5, seconds 60 option do?threshold option controls alert generation. type both means it alerts once per threshold period. track by_src tracks per source IP. count 5, seconds 60 means it triggers after 5 matching events within 60 seconds. This is ideal for detecting brute force attacks β a single failed login isn't suspicious, but 5 in a minute is.While firewalls and IDS/IPS actively block or alert on threats, network monitoring gives you deep visibility into what's happening on your network. Monitoring tools passively record traffic so you can detect anomalies, investigate incidents, and understand your network's normal behavior.
Zeek is a network analysis framework β much more than an IDS. It passively watches network traffic and generates detailed, structured logs of everything it sees. Think of it as a flight recorder for your network. It creates logs in /opt/zeek/logs/current/:
conn.log β every connection (source, dest, port, duration, bytes)dns.log β every DNS query and responsehttp.log β every HTTP request (method, URL, user-agent, response)ssl.log β every TLS/SSL connection (server name, certificate)files.log β every file transferred over the networkweird.log β unusual/suspicious protocol behavior# Read Zeek logs with zeek-cut:
cat conn.log | zeek-cut id.orig_h id.resp_h id.resp_p proto service duration
# Find top talkers:
cat conn.log | zeek-cut id.orig_h id.resp_h orig_bytes | sort -k3 -rn | head -20
# Find DNS queries for suspicious domains:
cat dns.log | zeek-cut query | sort | uniq -c | sort -rn | head -30
# Find large file transfers:
cat files.log | zeek-cut source tx_hosts rx_hosts total_bytes mime_type | sort -k4 -rn | head
# Detect beaconing (regular interval callbacks to C2):
cat conn.log | zeek-cut id.orig_h id.resp_h id.resp_p duration | \
awk '{print $1,$2,$3}' | sort | uniq -c | sort -rn | head
# tcpdump β command-line packet capture
sudo tcpdump -i eth0 -w capture.pcap
# Capture only specific traffic
sudo tcpdump -i eth0 port 80 or port 443
sudo tcpdump -i eth0 host 10.0.0.5
sudo tcpdump -i eth0 'tcp[tcpflags] & tcp-syn != 0' # SYN packets only
# Capture with rotation (long-term monitoring)
sudo tcpdump -i eth0 -w /captures/traffic-%Y%m%d%H%M.pcap -G 3600 -C 100M
# Detect port scans in real-time
sudo tcpdump -i eth0 'tcp[tcpflags] == tcp-syn' -c 100 | \
awk '{print $5}' | cut -d'.' -f1-4 | sort | uniq -c | sort -rn
# ntopng β web-based network traffic monitoring
# Real-time visibility into network flows, top talkers,
# application protocols, and alerts
# Access via https://your-server:3000
Network segmentation divides your network into isolated zones, limiting the damage an attacker can do if they breach one segment.
VLANs (Virtual LANs) β logical network separation at Layer 2. Each VLAN is a separate broadcast domain, requiring inter-VLAN routing (through a firewall for control).
Example VLAN Architecture:
ββββββββββββββββββββββββββ
VLAN 10 β Management (10.0.10.0/24) β IT admin workstations, mgmt interfaces
VLAN 20 β Servers (10.0.20.0/24) β Web servers, app servers, databases
VLAN 30 β Workstations (10.0.30.0/24) β Employee computers
VLAN 40 β Guest WiFi (10.0.40.0/24) β Isolated guest access (internet only)
VLAN 50 β IoT/OT (10.0.50.0/24) β Cameras, printers, building systems
DMZ (Demilitarized Zone) β network segment between the internet and internal network. Hosts public-facing services (web servers, email, DNS).
DMZ Firewall Rules:
Internet β DMZ: Allow HTTP/HTTPS
DMZ β Internal: DENY (or very limited)
Internal β DMZ: Allow (for management)
Internet β Internal: DENY
Zero Trust Architecture β "Never trust, always verify" β even for internal traffic.
Principles:
Implementation: micro-segmentation, identity-based access (not network-location-based), continuous verification (not just at login), encrypted traffic everywhere (even internal).
DNS monitoring is critical for detecting malware and C2. What to monitor:
DNS Sinkholing β redirect malicious domain queries to a safe server, preventing malware from reaching its C2. Using Unbound:
# /etc/unbound/unbound.conf
local-zone: "evil-domain.com" redirect
local-data: "evil-domain.com A 10.0.0.100" # Sinkhole IP
Also consider Pi-hole for network-wide DNS filtering (blocks ads, tracking, and known-malicious domains).
Detect DNS tunneling: look for high query volume, long subdomain names, TXT/NULL record types, encoded data in subdomains (e.g., aGVsbG8gd29ybGQ.tunnel.evil.com).
# DNS query logging with Zeek β find suspiciously long queries:
cat dns.log | zeek-cut query | awk '{print length, $0}' | sort -rn | head -20
# Queries longer than 50 characters are suspicious
Honeypots are decoy systems designed to attract and detect attackers. Any interaction with a honeypot is suspicious by definition β no legitimate user should be accessing it.
Low-interaction: simulates services (SSH, HTTP, SMB). Fast to deploy, limited interaction. Tools: Cowrie (SSH/Telnet), Dionaea (multi-protocol).
High-interaction: real systems designed to be attacked. Full interaction, more realistic, but riskier. Tools: T-Pot (all-in-one honeypot platform).
Cowrie SSH Honeypot β emulates an SSH server, logs all commands (github):
docker run -d -p 2222:2222 cowrie/cowrie
When an attacker connects (ssh root@honeypot -p 2222), they get a fake shell and everything is logged: credentials attempted, commands executed, files downloaded, and lateral movement attempts.
T-Pot β all-in-one honeypot platform (github). Includes Cowrie, Dionaea, Honeytrap, Conpot, and more with a web dashboard and Elastic Stack for log analysis.
Honeypot Placement Strategy β place honeypots in each network segment:
Any traffic TO a honeypot = investigation trigger. Zero false positive rate β no legitimate user should ever access a honeypot.
π‘ Pro Tip: Honeypots have a near-zero false positive rate. No legitimate user should be connecting to a decoy system. This makes honeypot alerts extremely high-fidelity. Deploy at least one in each network segment and set up immediate alerts for any interaction.
1. BASELINE β Know your network: document all segments/VLANs, inventory public-facing services, map normal traffic patterns, identify critical assets.
2. PERIMETER HARDENING β Review firewall rules (remove any/any rules), ensure default deny inbound, implement WAF, deploy DDoS protection, restrict management access to trusted IPs.
3. INTERNAL SEGMENTATION β Implement VLANs with inter-VLAN firewalls, create DMZ, isolate sensitive segments, begin zero trust implementation.
4. DETECTION DEPLOYMENT β Deploy IDS/IPS at boundaries, install Zeek for network logging, enable DNS query logging, deploy honeypots in each segment, centralize logs to SIEM.
5. MONITORING & TUNING β Create alert rules, tune to reduce false positives, establish threat hunting schedule, review rules quarterly, conduct regular pen testing.
β Mistake #1: Default allow policies.
Firewalls should default to DROP/DENY. Allow only what's explicitly needed. Many organizations have firewalls with permissive defaults that provide a false sense of security.
β Mistake #2: Flat network with no segmentation.
If an attacker compromises one system, they can reach everything. Network segmentation with firewalled boundaries between segments limits lateral movement dramatically.
β Mistake #3: IDS deployed but alerts ignored.
An IDS that generates thousands of unreviewed alerts is useless. Tune your rules to reduce noise, integrate alerts into your SIEM, and establish a process for investigating high-priority alerts.
β Mistake #4: "Set it and forget it" firewall rules.
Networks change. Applications change. Rules that were correct six months ago may now be overly permissive or unnecessarily restrictive. Review firewall rules quarterly and remove stale entries.
β Mistake #5: No egress filtering.
Most firewalls focus on inbound traffic but allow all outbound traffic. This lets malware communicate with C2 servers freely. Implement egress filtering β only allow outbound traffic on ports and to destinations that are business-justified.
β Mistake #6: Trusting the internal network.
Traditional network security assumes "inside is safe." Zero trust architecture recognizes that attackers will eventually get inside, so internal traffic should be verified and monitored just like external traffic.
Your IDS alerts show the following pattern from IP 203.0.113.50:
- 500+ SYN packets to different ports on your web server
in a 10-second window
- No established connections
- All SYN packets have the same source port
-m conntrack --ctstate ESTABLISHED,RELATED rule uses connection tracking to only allow packets that belong to existing, legitimate connections (ESTABLISHED) or are related to them (RELATED β like ICMP error messages). This is the cornerstone of a stateful firewall β it lets responses through while blocking unsolicited inbound traffic. Combined with a default DROP policy, this is the foundation of Linux firewall security.