Skip to content

34 β€” Network Defence Tools

Level: Advanced Β· Time: ~22 min Β· Prerequisites: Lesson 33 β€” Password, Crypto and Secrets Tools


Why this matters

Lesson 18 β€” Network Security Controls designed the controls: deny by default, separate the zones, filter what leaves, log what you refuse. This lesson is the build half of that pair β€” the open-source software that actually implements each control on a real network. The difference between a design and a defence is whether somebody typed the rules, tested them from both sides, and can find the log line when it fires. Everything here runs on a small box, a virtual machine or a spare host, and the whole set together is a fair approximation of a commercial network perimeter.


The mental model: the controls, and the tools that implement them

Control you designed The tool What it gives you
Default-deny ingress and egress the Linux packet filter (nftables), with a simplified front end for the common cases only the services you explicitly named are reachable
Zone boundaries and routing a firewall distribution (pfSense or OPNsense) routing, NAT, per-rule logging, VPN termination, sensor integration, a web interface
Detect in depth Suricata or Snort rule-based detection on the wire, passive first, inline once tuned
Block repeated abuse automatically Fail2ban or CrowdSec an address is banned after it fails enough times
Remove opportunistic malware before it resolves Unbound, Pi-hole, AdGuard Home a resolver you control, with curated response filtering
Early warning with almost no false positives honeypots (T-Pot, Cowrie, OpenCanary) an alert on any interaction, because nothing legitimate should connect

One control per row, one tool per control. Teams get into trouble when they install three overlapping tools and maintain none of them; pick the row, implement it, test it, and record that you did.


Host and edge firewalls: rule order decides everything

The modern Linux packet filter is nftables, and its rule evaluation is the fact that trips up everyone: rules are evaluated in order, the first match wins, and the policy attached to the end of the chain is what happens when nothing matched earlier. Getting the order wrong does not produce an error β€” it produces a hole.

#!/usr/sbin/nft -f
# /etc/nftables.conf β€” allow by exception, deny by default
flush ruleset

table inet filter {
    chain input {
        type filter hook input priority 0; policy drop;
        iif "lo" accept
        ct state established,related accept
        ct state invalid drop
        tcp dport { 22, 443 } accept
        icmp type echo-request limit rate 5/second accept
        log prefix "nft-in-drop: " level info
    }
    chain forward { type filter hook forward priority 0; policy drop; }
    chain output  { type filter hook output  priority 0; policy accept; }
}

Read it line by line. policy drop is the default for anything unmatched β€” without it the whole ruleset is decorative, because everything is still allowed. iif "lo" accept keeps local services talking over loopback, or unrelated things break and look like application bugs. ct state established,related accept allows the return traffic for connections you started, without which browsing and updates stop dead the moment you apply the rules. ct state invalid drop discards packets with nonsense state. tcp dport { 22, 443 } accept names the services you actually serve, so keep that list short and reviewed β€” it is the difference between a firewall and a business outage. And log prefix is the evidence that a rule fired, with a prefix you can grep; without it you can never prove any of this works. The forward chain is dropped too, because traffic routed between your own segments is exactly what a perimeter rule set usually forgets.

A simplified front end, ufw, writes the same kind of rules for you and is fine when your needs are ordinary. Use one of the two per host and know which is in charge:

sudo ufw default deny incoming
sudo ufw allow 22/tcp                   # or: ufw limit 22/tcp to rate-limit repeat offenders
sudo ufw allow from 10.20.30.0/24 to any port 5432 proto tcp
sudo ufw enable && sudo ufw status verbose

Making it survive a reboot and a mistake:

sudo nft -c -f /etc/nftables.conf          # syntax check, applies nothing
sudo nft list ruleset > /root/rules-backup.nft
sudo systemctl enable --now nftables       # load /etc/nftables.conf at boot
sudo journalctl -k -g 'nft-in-drop'        # confirm your refusals are being logged

[!WARNING] Changing firewall rules over SSH is how people lock themselves out of a server they can only reach remotely. Snapshot the current ruleset first, and schedule a restore a few minutes ahead with at or a sleep in the background, so cancelling the job is the only step needed to undo a mistake.

Testing is not optional: apply the rule, probe from another host (nmap -p 22,443 <host> or a plain curl), and then confirm the expected log line appeared. A rule you have not tested from both sides is a guess β€” and every change ends with the same two questions: does the intended traffic still work, and does the log now prove the rule is live?


Firewall and routing platforms

The moment you need zones, NAT, a VPN and per-rule logging, a host-based filter becomes the wrong tool. Two open-source distributions turn a small box or virtual machine into a real firewall: pfSense (Community Edition, FreeBSD based) and OPNsense, which began as a fork of it. Either is a defensible choice; both give you the same short list of capabilities.

Capability What it buys you in practice
Stateful firewall with per-rule logging every refused packet has a reason attached to it
Routing and VLAN support zones that actually route, instead of one flat network
NAT and port forwarding controlled publication of internal services, and a record of it
VPN termination (IPsec, OpenVPN, WireGuard) remote access without exposing anything to the internet
IDS/IPS packages the sensor from Lesson 31 running where the traffic already is

For a home lab this is the upgrade that changes everything β€” you stop having a router and start having a perimeter you can see, log, segment and test. It is the natural centrepiece of the lab you build in Lesson 37. Requirements are modest: two network interfaces and any small machine capable of running a FreeBSD image.


From monitoring to blocking, and automated abuse mitigation

You already met the engines in Lesson 31. From the operating side, the sequence matters more than the configuration:

  1. Run passive. Copy traffic from a span port or tap and alert only. Learn your own noise.
  2. Tune. Disable rules that cannot apply, whitelist your own scanners and backups, and record every change.
  3. Watch only what you plan to block. For a week, run the candidate rules in log-only mode and read every hit.
  4. Block. Only now put the sensor inline, where dropping becomes possible.

Doing step 4 first is the classic error, and it is expensive: the inline sensor does not know that the nightly backup job or the payroll system looks like exfiltration, and now every false positive is an outage. The rule is simple β€” never let a rule block traffic you have not watched it match for a week.

Abuse mitigation is the smaller, satisfying tool in this section: watch a log, and ban an address that fails too often. The two established options are Fail2ban, which knows your logs, and CrowdSec, which knows your logs and shares signals with other installations so an address that attacked someone else can be blocked before it reaches you.

# /etc/fail2ban/jail.local
[sshd]
enabled  = true
maxretry = 5
findtime = 10m
bantime  = 1h
sudo fail2ban-client status sshd
sudo fail2ban-client set sshd unbanip 203.0.113.9     # you will need this the day it bans a colleague
cscli decisions list                                  # CrowdSec's view of current bans
cscli collections install crowdsecurity/sshd
cscli bouncers add <name>                             # the component that enforces a decision
It does well It cannot do
Quieting SSH brute force within minutes of installation see an attack not written to the log it watches
Reacting to repeated web authentication failures stop a distributed attempt spread thinly across many addresses
Giving you a configurable, auditable reaction with an unban path know that the address it just banned is your own monitoring host or your office

Two habits make it safe: whitelist your own management network before enabling it, and never let it be the only control on an exposed service β€” it buys you quiet, not protection. CrowdSec's community sharing is genuinely useful and worth understanding before you enable it, because it means sending information about attacks against your network to a central service.


DNS filtering and resolution

Name resolution is where a large share of opportunistic malware announces itself, so it is worth owning. Two pieces, often on the same host: a recursive resolver you control (Unbound, with DNSSEC validation enabled), and a blocking layer in front of it for the network (Pi-hole or AdGuard Home, with curated blocklists) that answers known-bad names with nothing instead of an address.

What this achieves: a large slice of malware, advertising and tracking infrastructure simply fails to resolve, and your DNS logs become a detection source β€” because queries that never resolve still leave a record of which host asked.

It achieves It breaks, and why that matters
Removes name resolution for known-bad domains across every device on the LAN an over-broad blocklist takes down a legitimate service, and it will look like something else
Gives you a query log per host, which is a detection source in its own right anything using encrypted DNS to a third party bypasses your filter entirely
Cheap, central and immediate β€” one machine protects every client it does not stop malware that reaches an address directly, nor stop data leaving

So it is a strong layer and a poor substitute: it does not replace egress control (what is allowed to leave) and it does not replace endpoint security. The practical rule for a small network is to make your resolver the only one reachable and to deny outbound DNS to anything else β€” otherwise every device with a hard-coded setting walks around your filter.

Virtual private networks belong in the same section because they are now easy enough to be routine. WireGuard is the modern default for both site-to-site and remote access: a very small configuration, a tiny attack surface, and in-kernel performance.

# /etc/wireguard/wg0.conf β€” server side, one block per device
[Interface]
Address    = 10.99.0.1/24
ListenPort = 51820
PrivateKey = <server private key>
[Peer]
PublicKey  = <laptop public key>
AllowedIPs = 10.99.0.2/32
wg genkey | tee private.key | wg pubkey > public.key
sudo wg-quick up wg0
sudo wg show                       # peers, handshakes and transfer counters

An older protocol (OpenVPN, TLS-based) is still worth knowing because appliances, partners and old clients insist on it. But the protocol is not where remote access goes wrong β€” the rules matter more than the technology: MFA at the layer that authenticates the person (WireGuard's static key is a device credential, not a login), a unique key per device, no shared credentials, connection logging you actually read, and never exposing RDP or SSH directly to the internet as a shortcut.

For consumer hardware, replacement firmware such as OpenWrt (and the older DD-WRT and FreshTomato builds) turns a supported router into a device running the same firewall engine as your servers, with VPN and DNS filtering packages available. Check the model is properly supported, with enough flash and memory, before you overwrite anything.


Deception, the reference layout, and the verification habit

Honeypots are the highest signal-to-noise control in this entire course, because their rule is absolute: nothing legitimate ever connects to them, so every interaction is an alert. Shapes vary from a single SSH service that logs the username and password pairs attackers try, to a full distribution (T-Pot) that runs many emulated services behind dashboards for analysis. A small, lightweight option (OpenCanary) alerts on any touch across several protocols and runs happily on modest hardware.

Two conditions make a honeypot work: put it on its own network segment with no route to anything real, and alert on any interaction rather than trying to classify it. The credential pairs collected by an SSH honeypot are also the most persuasive evidence you will ever get for your password policy: they are literally the passwords attackers try first.

A reference small network from these components alone:

Position Component What it buys
Edge firewall distribution on a small box, default-deny with logging routing, NAT, zones, VPN, the log of everything refused
Between zones IDS sensor on a span port, becoming inline on the server zone detection where internal movement happens
Every host nftables or ufw as a second, independent layer defence that survives a perimeter mistake
Exposed services Fail2ban or CrowdSec with your management network whitelisted quiet logs and a defended SSH port
Remote access WireGuard, one key per device, MFA at the portal access with nothing published to the internet
Dead-end segment one honeypot an alert whenever anything touches it

And the habit that ties it together: after every change, test from both sides and confirm the log line. From outside, prove the port is closed; from inside, prove the service still works; then find the refusal in the log with the prefix you chose. A firewall job is finished when the evidence exists, not when the commit is saved.


Attack it / Defend it

The attack How it works The control that stops it
Internet-wide scanning for open ports sweep the address space for anything listening default-deny ingress, short allowlists, a log of refusals
SSH brute force repeated password attempts against an exposed port key-only authentication, Fail2ban or CrowdSec, MFA, no root login
Lateral movement between zones use a foothold to reach other internal hosts segmentation at the firewall, inter-zone rules that allow only what is needed
Data exfiltration through the perimeter send data out over an allowed port egress filtering by destination and volume, plus the traffic analysis from Lesson 31
Remote access with a shared or stolen key reuse one credential across devices and staff one key per device, MFA at the portal, connection logs, revoke and reissue access
Anything reaching a honeypot automated scanning and exploitation attempts the honeypot itself: an alert on every touch, and evidence for your password policy
Blocking too early with an inline sensor a false positive drops production traffic passive first, log-only weeks, tuned rule sets, then block

Key takeaways

  • Rule order and the default policy are the whole firewall. First match wins; anything unmatched meets the policy, so an oversight in order becomes an open door.
  • A firewall change is not finished until it is tested from both sides and the log line proves the rule fired. Snapshot and schedule a rollback before editing over SSH.
  • A firewall distribution is the best value upgrade for a lab, because zones, logging, VPN and sensors all arrive together.
  • Abuse mitigation buys quiet, not protection, and it will ban your own users if you do not whitelist your management network.
  • DNS filtering removes a large slice of opportunistic malware and is not a substitute for egress control β€” anything using its own encrypted DNS walks around it.

Check yourself

  1. Your default-deny ruleset allows established,related before the service rules, then drops. Why does the order of those two matter, and where is your evidence that it works?
  2. You must change firewall rules on a server you can only reach over SSH. What two things do you do before applying them, and why?
  3. Give one thing Fail2ban does well and one thing it cannot do, and name the configuration mistake that gets a colleague banned.
  4. Your DNS filter blocks a domain a user needs. What do you do, and what does that tell you about relying on DNS filtering as a control?
  5. Why is a honeypot's alert quality better than a signature-based IDS, and where must it be placed?

Next

Lesson 35 β€” SIEM, Logging and Monitoring Stacks