Hardening Checklists

Updated

September 4, 2026

Hardening Checklists

Hardening is not a one-time “secure the router” checkbox. It is a repeatable set of gates you run after every design change. This chapter consolidates edge, control-plane, ACL, and ops hygiene into checklists you can attach to Containerlab labs (mid-2026 open stack: FRR, Linux, optional SR Linux notes).

Learning goals

By the end of this chapter you can:

  • Run role-based hardening checklists (edge, P, lab host)
  • Turn checklist items into automated verify-hard.sh probes
  • Balance security with operability (break-glass paths)
  • Record exceptions with expiry and owner
  • Apply the same gates to dual-home and fabric labs

How to use these lists

  1. Pick the role of the device or lab.
  2. Mark each item: Pass / Fail / N/A / Exception.
  3. Failures become backlog; exceptions need owner + date.
  4. Automate the boring Pass/Fail checks.
  5. Re-run after every topology or policy change.
Design → Implement → Functional verify → Hardening verify → Document

Checklist 0 — Lab hygiene (every topology)

# Gate Pass looks like
0.1 Topology in git .clab.yml + configs committed
0.2 Addressing plan No overlapping accidental spaces
0.3 Secrets No production passwords in repo
0.4 Destroy works containerlab destroy -c clean
0.5 Logs bound Evidence survives destroy
0.6 Images free Main path needs no paid license
0.7 Resource note RAM/CPU expected documented

Checklist 1 — Management plane

# Gate Pass looks like
1.1 SSH/API not on all interfaces blindly Listen limited or filtered
1.2 Mgmt sources limited ACL/CoPP allow jump net only
1.3 Auth Keys or strong lab passwords; no default vendor admin left
1.4 Banner / MOTD Optional but marks non-prod
1.5 Out-of-band story Console or dual path to recover
1.6 Telemetry endpoints known Who scrapes what
1.7 DNS for mgmt names Optional but reduces fat-finger

Linux probes

# who listens?
docker exec clab-X-r1 ss -lntp
# INPUT policy not wide open without reason
docker exec clab-X-r1 iptables -L INPUT -n -v | head

Checklist 2 — Control plane & routing

# Gate Pass looks like
2.1 Passive interfaces on access LANs No accidental OSPF on user ports
2.2 BGP peer ACLs / TTL security as applicable Only intended peers
2.3 Max-prefix on eBGP Limit configured + action known
2.4 Prefix filters in and out Negative hijack test fails closed
2.5 Router-IDs unique Documented
2.6 Auth on IGP/BGP where in scope Or explicit exception
2.7 CoPP/receive ACL present on edges Matrix documented
2.8 Loop prevention No rediscovery of classic redistrib loops

FRR probes

docker exec clab-X-r1 vtysh -c 'show ip ospf interface'
docker exec clab-X-r1 vtysh -c 'show bgp summary'
docker exec clab-X-r1 vtysh -c 'show run' | grep -E 'prefix-list|route-map|max-prefix|passive'

Checklist 3 — Data plane filters

# Gate Pass looks like
3.1 Written policy exists Prose before rules
3.2 Default stance explicit Deny or allow documented
3.3 Positive tests Needed paths work
3.4 Negative tests Forbidden paths fail
3.5 Anti-spoof (uRPF-like idea) As scope allows
3.6 Directed broadcast / dangerous services off No chargen era nonsense
3.7 IPv6 filters parity Not “v6 open because forgot”

Checklist 4 — Edge services

# Gate Pass looks like
4.1 DHCP pools correct giaddr/relay tested
4.2 NAT scoped Only intended interfaces
4.3 VRRP/anycast VIP documented Single master observed
4.4 DNS dependency known Outage drill done once
4.5 Time sync chrony/ntp status OK
4.6 Logging on role changes VRRP/BGP flap visible

Checklist 5 — Secrets, users, supply chain

# Gate Pass looks like
5.1 Image sources pinned Digests/tags known
5.2 No shared root SSH everywhere Or accepted lab-only risk noted
5.3 CI does not print secrets Logs clean
5.4 Third-party scripts reviewed Especially curl

Checklist 6 — Resilience & abuse

# Gate Pass looks like
6.1 Link failure drill Recover within budget
6.2 Peer failure drill Documented
6.3 Flood to RE drill Transit survives
6.4 Config rollback Known good in git
6.5 Capacity headroom Lab not at 100% RAM always

Role profiles (quick)

Lab host (Containerlab hypervisor)

  • Disk for images; unused labs destroyed
  • Access limited to operators
  • sysctl baseline documented
  • Docker/podman not exposed to world

FRR edge CE

  • Checklists 1–4 heavily
  • Dual-home policies + VRRP tracking story
  • Export only owned space

FRR P / fabric leaf

  • Minimal services listening
  • Underlay filters; no customer ACLs confusion
  • ECMP + BFD timer sanity
  • CoPP light but present

Linux bridge “switch”

  • No IP on data plane unless needed
  • STP/loop story if L2 loops possible
  • Do not run random services on bridge NS

Exception register template

ID Control Reason Owner Expiry Review
E-001 BGP without TTL security Lab only single hop you 2026-12-01

Exceptions without expiry become permanent holes.

Automating gates — verify-hard.sh

#!/usr/bin/env bash
set -euo pipefail
LAB=${LAB:-clab-dualhome}
fail() { echo "FAIL: $*" >&2; exit 1; }
pass() { echo "PASS: $*"; }

# 2.4 negative: hijack absent on pe1
if docker exec ${LAB}-pe1 vtysh -c 'show bgp ipv4 uni' 2>/dev/null | grep -q '203.0.113.0'; then
  fail "hijack prefix present"
else
  pass "no hijack prefix"
fi

# 1.2 example: ssh port not open to all — soft check listening interfaces
docker exec ${LAB}-ce1 ss -lntp | grep -q ssh && pass "sshd present" || pass "no sshd (ok if unused)"

# 4.3 VIP answers
docker exec ${LAB}-h1 ping -c1 -W1 192.168.50.254 >/dev/null && pass "VIP" || fail "VIP"

# 0.1 topology file exists
test -f dualhome.clab.yml && pass "topology file" || fail "missing topology"

echo "HARDENING SMOKE OK"

Wire into Makefile:

smoke: ; ./verify.sh
hard:  ; ./verify-hard.sh

Predict → observe → fix (meta-drill)

Break one control on purpose:

# remove FROM-CE filter on pe1 in lab

Predict | verify-hard.sh fails hijack test when you advertise junk |
Observe | script FAIL line |
Fix | restore route-map; re-run |

Never disable a gate silently—disable via exception register.

Mapping to prior chapters

Chapter theme Checklist
ACL thinking 3.x
CoPP 2.7, 6.3
QoS don’t police control into death; document classes
Dual-home edge 2.x + 4.x
Name/time/log 4.4–4.6, 0.5

Optional SR Linux

Export checklist to NOS-specific show commands in an appendix note. Same gates: peer authenticity, prefix limits, mgmt ACL, logging. Free community image is for dialect practice, not a second security model.

Definition of done — hardened lab

  • Role checklist completed with Pass/Fail
  • Exceptions registered
  • verify.sh + verify-hard.sh green
  • One intentional fail demonstrated (gate works)
  • Rollback path known

Common mistakes

Mistake Symptom
Checklist once, never again Drift
Automating only happy path False green
Lockout without console Unrecoverable lab (or prod!)
Copying bank-grade CoPP into tiny lab Protocols die
Paper checklists not in repo Lost tribal knowledge

Summary

  • Hardening is repeatable gates, not a mood
  • Use role-based checklists + exception register
  • Automate negative tests (hijack, flood survival, mgmt limits)
  • Re-run after every material change
  • Operability (break-glass) is part of security

Next part: overlays and tunnels—why we encapsulate, and how free stacks practice VXLAN/EVPN-class ideas.