01 · Network Security Deep Dive¶
Level 1 Module 2 covered how packets move. This module goes one layer deeper: how firewalls actually decide what to drop, how an IDS spots an attack in traffic, and how to read a packet capture yourself instead of trusting a summary. You'll run a local firewall, generate traffic that should and shouldn't pass, and inspect it in Wireshark.
Scope: your own machine and lab VMs only
Every capture and scan in this module runs against 127.0.0.1 or a
local VM you control. Capturing or scanning traffic on a network you
don't own or have written authorization to test is illegal in most
jurisdictions.
1. Stateful vs. stateless firewalls¶
A stateless (packet-filtering) firewall evaluates each packet in
isolation against a rule list — source/destination IP, port, protocol. A
stateful firewall tracks connections: it remembers that 10.0.0.5
opened an outbound TCP connection to port 443, and automatically allows the
return traffic for that specific connection without a separate inbound
rule. Nearly every modern firewall (iptables/nftables, Windows Firewall,
cloud security groups) is stateful by default — this is what lets "allow
outbound, deny inbound" work as a sane default policy.
| Type | Decision basis | Example |
|---|---|---|
| Stateless | Each packet alone | Classic ACLs on old routers |
| Stateful | Connection state table | iptables -m state, AWS Security Groups |
| Application-layer (NGFW/WAF) | Payload content, not just headers | Blocks a SQLi pattern even on an "allowed" port 443 |
2. Build and test a local firewall policy¶
On a Linux VM (or WSL), inspect and set a default-deny inbound policy 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 rule inet filter input ct state established,related accept
sudo nft add rule inet filter input iif lo accept
sudo nft add rule inet filter input tcp dport 22 accept
This reads as: drop everything inbound by default, except traffic that's
part of an already-established connection (ct state established,related
— the stateful part), loopback, and new SSH connections on port 22.
Test it from another host or namespace:
nc -zv <vm-ip> 22 # succeeds — explicitly allowed
nc -zv <vm-ip> 80 # times out — no rule allows it, default policy drops it
3. Capture and read the traffic¶
Start a capture while you run the test above:
Open /tmp/fw_test.pcap in Wireshark (or tcpdump -r /tmp/fw_test.pcap -nn
on the CLI) and find the three-way handshake for the port 22 attempt:
For the port 80 attempt you'll see only the outgoing SYN — no response at
all, because policy drop silently discards the packet rather than
replying with a RST (a REJECT rule would instead send a visible
RST/ICMP unreachable). This silent-vs-rejected distinction matters for
recon: an attacker running a port scan can often tell a "closed but
responsive" port from a "filtered/dropped" port, which leaks information
about which policy is in effect.
4. Detecting a scan with an IDS¶
Install Suricata (or use Zeek) on the same VM and point it at the interface:
Run a scan against the VM from another host:
Tail the alert log:
08/29/2026-10:14:02 [**] [1:2210036:1] SURICATA STREAM Packet with invalid ack [**]
08/29/2026-10:14:03 [**] [1:2001219:19] ET SCAN Potential SSH Scan [**] {TCP} 10.0.0.10:51321 -> 10.0.0.5:22
Suricata matched the burst of half-open connections to many ports in a
short window against a signature (ET SCAN) — this is the same principle
behind every network IDS: known-bad patterns in traffic, whether that's a
scan signature, a known exploit byte sequence, or a beaconing interval to a
known-bad IP.
5. Segmentation and the principle of least network access¶
The other half of network security is architectural, not per-packet: network segmentation. A flat network where every host can reach every other host means a single compromised laptop can pivot to the database server. VLANs, subnets with firewall rules between them, and a DMZ for internet-facing services all implement the same idea as Level 1's least privilege, applied to network paths instead of user permissions — a web server should be able to reach only its database on only the DB port, nothing else.
How It Actually Works: how an IDS actually matches a signature against a live stream¶
A network IDS like Snort/Suricata doesn't "read" traffic the way a human reads a log — it reassembles a raw stream of packets into ordered TCP segments (undoing fragmentation and out-of-order delivery first, since an attacker can deliberately fragment an attack across multiple packets specifically to make each individual packet look benign), then runs the reassembled byte stream through a multi-pattern matching engine. Most production engines use an automaton-based algorithm (Aho–Corasick is the classic choice): every signature's content pattern is compiled once into a single finite-state machine that can search for thousands of patterns simultaneously in one pass over the bytes, rather than checking one pattern at a time — this is what makes signature matching feasible at multi-gigabit line rates. A rule like
alert tcp any any -> $HOME_NET 22 (msg:"SSH brute force attempt";
flow:to_server; content:"SSH-2.0"; threshold:type threshold,
track by_src, count 5, seconds 60; sid:1000010;)
encodes both a content match (does this byte sequence appear in the
stream at all) and a stateful condition (threshold, which requires the
engine to keep a per-source counter across multiple packets over a time
window) — meaning the IDS is simultaneously running the pattern-matching
automaton and maintaining small pieces of session state, which is exactly
why signature-based detection has a real, bounded computational cost per
connection rather than being "free."
Segmentation's actual enforcement point is the same conntrack/ACL mechanism from Module 1's firewalls, applied at a boundary between VLANs or subnets rather than at the internet edge: a router or L3 switch consults its access control list on every packet crossing between segments, and because each segment is a separate broadcast domain, a compromised host in one VLAN physically cannot see ARP or broadcast traffic from another VLAN even before any ACL is evaluated — the isolation is partly structural (separate Ethernet broadcast domain) and partly policy (the ACL), which is why segmentation degrades gracefully even if one ACL rule is misconfigured, unlike a flat network where a single firewall bypass exposes everything.
Key terms¶
| Term | Meaning |
|---|---|
| Stateful firewall | Tracks connection state to auto-allow return traffic |
| Default-deny | Block everything not explicitly allowed |
| DROP vs. REJECT | Silent discard vs. an explicit refusal response |
| IDS/IPS | Intrusion Detection/Prevention System — flags (or blocks) malicious traffic patterns |
| Segmentation | Splitting a network into zones with controlled paths between them |
| DMZ | A network zone for internet-facing hosts, isolated from the internal network |
Exercise¶
- Reproduce the
nftablespolicy above in a VM and confirm port 22 is reachable and port 80 is not, capturing both attempts withtcpdump. - Change the port 80 rule's policy from
dropto an explicitreject(nft insert rule inet filter input tcp dport 80 reject with tcp reset) and capture the difference in the response packet. - Install Suricata (or Zeek) in your lab VM, run an
nmap -sSscan against it from another VM, and paste the resulting alert log line. - Design (on paper — a diagram is fine) a three-zone segmentation for a small company: a public web server, an internal database, and employee workstations. List exactly which zone can initiate a connection to which, and on what ports.
- Written answer: explain why "default-deny inbound, default-allow outbound with logging" is a common baseline policy, and one scenario where you'd also want to restrict outbound traffic.