Network Security: Firewalls, IDS & VPNs
Learn how to defend networks with firewalls, IDS/IPS, VPNs, and network segmentation — and understand the attacker's perspective on each control.
Learning Objectives
- → Explain stateful vs stateless firewall operation
- → Configure iptables/nftables rules for common security policies
- → Distinguish IDS, IPS, and SIEM roles
- → Understand VPN protocols: WireGuard, OpenVPN, IPsec
- → Design a segmented network with DMZ and zero trust principles
Firewalls
A firewall filters traffic based on rules — allow or deny packets.
Stateless vs Stateful
Stateless: rules on single packet header (src/dst IP, port, protocol)
+ Fast, simple
- Can't detect split-packet attacks, reply traffic must be explicitly allowed
Stateful: tracks connection state (SYN → ESTABLISHED → FIN)
+ Allows reply traffic automatically (ESTABLISHED,RELATED)
+ Detects TCP state anomalies
- More resource intensive
iptables (Linux)
# List current rules
iptables -L -v -n
# Default policies (drop everything not explicitly allowed)
iptables -P INPUT DROP
iptables -P FORWARD DROP
iptables -P OUTPUT ACCEPT
# Allow established/related connections (stateful)
iptables -A INPUT -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT
# Allow loopback
iptables -A INPUT -i lo -j ACCEPT
# Allow SSH (be careful — do this FIRST)
iptables -A INPUT -p tcp --dport 22 -j ACCEPT
# Allow HTTP and HTTPS
iptables -A INPUT -p tcp --dport 80 -j ACCEPT
iptables -A INPUT -p tcp --dport 443 -j ACCEPT
# Allow ICMP ping
iptables -A INPUT -p icmp --icmp-type echo-request -j ACCEPT
# Rate-limit SSH (anti-brute-force)
iptables -A INPUT -p tcp --dport 22 -m recent --set --name SSH --rsource
iptables -A INPUT -p tcp --dport 22 -m recent --update --seconds 60 --hitcount 4 --name SSH --rsource -j DROP
# Log and drop everything else
iptables -A INPUT -j LOG --log-prefix "DROPPED: " --log-level 4
iptables -A INPUT -j DROP
# Save rules
iptables-save > /etc/iptables/rules.v4
UFW (Uncomplicated Firewall)
ufw default deny incoming
ufw default allow outgoing
ufw allow ssh
ufw allow 80/tcp
ufw allow 443/tcp
ufw limit ssh # rate limiting
ufw enable
ufw status verbose
Network Segmentation & DMZ
Internet
│
[Firewall 1]
│
[DMZ] — web servers, email, DNS (partially trusted)
│
[Firewall 2]
│
[Internal Network]
├── [VLAN: Finance]
├── [VLAN: Engineering]
└── [VLAN: Security/SOC]
DMZ (Demilitarized Zone): hosts public-facing services. Compromise of DMZ host doesn't give direct access to internal network.
VLAN segmentation: separate network segments by function — breach in one VLAN can't directly reach others.
IDS and IPS
| Type | Action | Placement |
|---|---|---|
| NIDS (Network IDS) | Detect, alert | Inline or span port |
| NIPS (Network IPS) | Detect, block | Inline only |
| HIDS (Host IDS) | Detect on host | Each server |
Snort/Suricata Rules
# Detect SSH brute force
alert tcp any any -> $HOME_NET 22 (
msg:"SSH Brute Force Attempt";
flow:to_server,established;
threshold: type both, track by_src, count 5, seconds 60;
sid:1000001; rev:1;
)
# Detect SQL injection attempt
alert http any any -> $HTTP_SERVERS any (
msg:"SQL Injection UNION attempt";
flow:to_server,established;
content:"UNION"; nocase;
content:"SELECT"; nocase;
sid:1000002; rev:1;
)
Detection Methods
| Method | How | Pros | Cons |
|---|---|---|---|
| Signature | Match known patterns | Low false positives | Misses zero-days |
| Anomaly | Baseline + deviation | Catches unknowns | High false positives |
| Behavioral | Process/flow analysis | Context-aware | Complex |
VPNs
WireGuard (Modern)
# Server setup
wg genkey | tee server_private.key | wg pubkey > server_public.key
# /etc/wireguard/wg0.conf (server)
[Interface]
PrivateKey = <server_private_key>
Address = 10.8.0.1/24
ListenPort = 51820
PostUp = iptables -A FORWARD -i wg0 -j ACCEPT; iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE
[Peer]
PublicKey = <client_public_key>
AllowedIPs = 10.8.0.2/32
# Start
wg-quick up wg0
# Client config
[Interface]
PrivateKey = <client_private_key>
Address = 10.8.0.2/24
DNS = 1.1.1.1
[Peer]
PublicKey = <server_public_key>
Endpoint = server.example.com:51820
AllowedIPs = 0.0.0.0/0 # route all traffic through VPN
VPN Protocols Comparison
| Protocol | Security | Performance | Use Case |
|---|---|---|---|
| WireGuard | Excellent | Best | Modern, recommended |
| OpenVPN | Good | Moderate | Legacy, broad support |
| IPsec/IKEv2 | Good | Good | Corporate, mobile |
| L2TP/PPTP | Broken | N/A | Never use |
Zero Trust Architecture
Old model: "Trust but verify" — implicit trust inside the perimeter
Zero Trust: "Never trust, always verify" — no implicit trust anywhere
Principles:
1. Verify every user and device, every access request
2. Least-privilege access — only what's needed, when needed
3. Assume breach — design to contain lateral movement
4. Inspect and log all traffic (even internal)
Zero Trust implementation:
- Identity: MFA for everything, no passwords alone
- Device: endpoint compliance check before access
- Network: microsegmentation, service mesh
- Application: per-application auth, not network trust
- Data: classification and DLP
On a Linux VM: (1) set default DROP policy on INPUT and FORWARD, (2) allow SSH only from your IP, (3) allow HTTP/HTTPS from anywhere, (4) add rate limiting for SSH (max 3/min), (5) add logging for dropped packets, (6) save rules and verify they survive reboot. Test by scanning from another host with nmap.
What does the default DROP policy on INPUT do?
Why should SSH rules go BEFORE the default DROP rule?
Configure WireGuard: (1) generate server + client key pairs, (2) write wg0.conf for server and client, (3) enable IP forwarding on server (sysctl net.ipv4.ip_forward=1), (4) add NAT masquerade iptables rule, (5) connect client and verify traffic routes through VPN with curl ifconfig.me from client.
Why is IP forwarding required on the VPN server?
Write Snort rules to detect: (1) nmap SYN scan (many half-open connections from one source), (2) SSH brute force (>5 attempts/minute), (3) HTTP requests with 'UNION SELECT' in the URI, (4) data exfiltration over DNS (queries > 60 chars). Test each rule against simulated traffic.
What is the difference between a signature-based and anomaly-based IDS?