Skip to content
WAHUKEZA

Protect · Availability

Know you are under DDoS, from your own routers and hosts. With an alarm, and an all-clear.

Read-only telemetry from the links and servers you own, learned per hour of the week, turned into one alarm per attack with a typed, machine-readable incident, and an all-clear that closes the same incident when it is over. Your deception fabric corroborates. Nothing in the module can change a router or a host: this is detection, never mitigation.

Inputs

Two small agents on infrastructure you own. One fabric you already run.

A honeypot is never the target of a flood, and a SYN that never completes a handshake never reaches it. So detection comes from your routers and your servers; the sensors add the one thing they can see: whether the sources are real.

cti-flow

NOC collector

One per management domain, on a Linux VM or a NanoPi-class board at your NOC.

  • Interface counters by read-only SNMP v2c GET every 10 s: bytes and packets in and out, link speed, uptime. This is the detection signal.
  • NetFlow v5, v9 and IPFIX on one UDP port, folded per minute. This is attribution: what kind of flood, aimed at which of your addresses, from which source networks.
  • Under export overload it sheds flows, never counters: attribution degrades, detection does not.

Detects floods and link saturation

cti-vitals

Linux host agent

On the internet-facing servers you choose: web, DNS, mail, VPN.

  • The kernel’s own counters every 5 s: SYN cookies sent, listen-queue overflows, backlog drops, passive opens, established connections, UDP receive errors, softnet drops, conntrack fill, interface rates, load.
  • Runs unprivileged; every file it reads is world-readable. One HTTPS report every 15 s.
  • Sends no address of any kind: the counters carry none.

Detects SYN floods and exhaustion

deception fabric

Your sensors, as corroboration

Already deployed; nothing to install.

  • A flood’s source networks that completed a handshake with one of your sensors in the last 24 h are real hosts, not spoofed; the event says so and gains confidence.
  • A fleet-wide surge of new sources while your links are quiet is its own, Medium-severity event: a canary for attention.
  • It never decides alone, and the module never changes a sensor, a session or an indicator.

Corroborates, never decides

Architecture

Counters decide. Flows explain. Sensors corroborate.

A spoofed flood can overflow a router’s flow cache; it cannot overflow its interface counters. So counters are the detection signal, flows are attribution, and the deception fabric is evidence about the sources, never the detection of record.

signalfromtrusted as
Interface counters
Volumetric floods, link saturation
router · SNMP GET, 10 sDetection: constant cost, keeps working on a saturated link
Flow aggregates
SYN-only share, reflector ports, packet size, targets, source spread
router · NetFlow v5/v9, IPFIXAttribution: a spoofed flood can overflow a router’s flow cache
Kernel counters
SYN floods, connection exhaustion, floods that complete handshakes
host · /proc, 5 sDetection: the kernel’s own verdict
New-source surge and overlap
Whether the flood’s sources are real hosts
deception fabricCorroboration only: spoofed sources never overlap
InternetfloodBorder routerRouterOS 6 / 7Your serviceLinux · cti-vitalsDeception fabricyour sensorscti-flowNOC collectorflow exportSNMP GET · read-onlyWahukezabaseline · detectoraggregatescorroborationkernel countersIncident + all-clearwebhook · pager · SIEM
Every telemetry arrow points towards the platform. None points back into your network.

Privacy on an ISP’s links

No subscriber address leaves the collector.

On a provider’s links, flow records are subscribers’ personal data. The collector keeps a minute of flows in memory, folds them into aggregates, discards them and writes no file. The host agent has no addresses to send.

  • Targets are yours only. A destination is named only if it is inside the service prefixes you declared; every other destination folds into one bucket called “other”.
  • Sources are networks, not people. At most the twenty busiest source networks per minute, as /24 (IPv6 /48), the attacker side, never an individual address.
  • Enforced on arrival. A router entry naming a target outside its prefixes, or a source finer than /24, is refused and counted, not stored.
what leaves the box · per router, every 15 s
  • interfacesbps and pps in and out, link speed
  • per minutedatagrams received and shed
  • distinct-source count (capped at 65,536)
  • packets by protocol; 16 busiest destination ports
  • SYN-only share, average packet size, reflector-port share
  • targets≤ 10 addresses inside your own prefixes, rest as “other”
  • sources≤ 20 networks as /24 (/48) with their share of packets

never  a flow record · a packet · a subscriber address · a raw 10-second sample

Detection model

Normal is learned per link, per metric, per hour of the week.

For every source, interface and metric, the platform keeps the median and the median absolute deviation for each of the week’s 168 hours, over the last 14 days. Monday 09:00 is compared with Mondays at 09:00, not with Sunday night.

  • Seven days of learning. A new or reset source is charted but never pages, and gets one notification when learning completes.
  • Open. A metric above the larger of median + 6 × MAD, 5 × median and an absolute floor, for three consecutive samples.
  • Close. Every triggering metric back under twice its median for five minutes, while the source keeps reporting. Silence never closes an attack.
  • One attack, one page. A flood that dips and returns inside the close window extends the same event.
  • No data is not no attack. A source silent for five minutes is marked offline with its own notification; an open event stays open.
  • Confidence, explained. How far above baseline, +15 when a second independent source agrees, +15 when your sensors have met the source networks, −20 when flow export was degraded.
hour-of-week baseline (median ± MAD)openclosealarm · 3 samples overall-clear5 quiet mintime →
Illustration, not data.

Event kinds

Nine kinds, read in a fixed order from the evidence.

A closed vocabulary: the same strings are stored on the event, sent in the webhook and used in the deduplication key. A new kind is a design change, never a configuration edit.

kindwhat it meansread fromseverity
syn-floodThe host is issuing SYN cookies, or most of the TCP flows are SYN-only while TCP carries most of the traffic.host · flowsHigh
udp-amplificationUDP-dominant, at least half the flows from known reflector ports (DNS, NTP, SSDP, memcached and eight more), large average packets.flowsHigh
udp-floodUDP-dominant traffic far above normal that does not look like reflection.flowsHigh
icmp-floodICMP-dominant traffic far above normal.flowsHigh
link-saturationInbound traffic at 90 % of the link’s capacity or more. Stamped beside the flood kind, and it sets the severity.interface countersCritical
connection-exhaustionThe connection-tracking table is 90 % full, or listen queues overflow while packet rates look normal.hostCritical
http-floodEstablished connections or accepted handshakes jump while packet rates look normal: an application-layer flood that completes its handshakes.hostHigh
volumetric-unknownWell above baseline, and none of the shapes above fits.anyHigh
fabric-surgeA surge of new sources across your sensors while your own links stay quiet. Confidence is capped: the fabric does not measure your links.deception fabricMedium

Reflector ports are a closed, cited list of twelve: 19, 53, 111, 123, 137, 161, 389, 1900, 3283, 5353, 10001, 11211.

The alarm

A machine-readable incident. Then an all-clear that closes the same incident.

Every alarm carries what a defender downstream needs to act: the kind, the target, the device and interface, peak against baseline, the source networks (marked as seen by your sensors, or as a spoofable claim) and how sure the platform is. When it is over, the same body comes again with status ended.

  • Pager. PagerDuty and Opsgenie key the open and the all-clear to one incident, so the all-clear resolves it there.
  • Webhook. An HMAC-signed availability_event body your own automation can consume, the documented contract for anything that raises a defence and must be told to lower it. Slack too.
  • SIEM. A dedicated availability stream, one event per open and per end, to any of the five SIEM destinations.
  • Playbooks. An availability event triggers notify, call-webhook and open-ticket. Endpoint response and sharing to a group are refused on this trigger.
  • It gets through. A failed page or all-clear is retried for 24 hours, and the console says plainly when an all-clear could not be sent.
availability_event · #42High · confidence 85

syn-flood

source
bgw-01 · router · collector noc-1
interface
sfp-sfpplus1
target
203.0.113.10 · 412k pps
peak
3.1 Gbit/s · 480k pps vs baseline 240 Mbit/s · 31k pps
sources
198.51.100.0/2411 %seen by your sensors192.0.2.0/246 %spoof likely · claim
fabric
23 % of source networks met your sensors · flow export complete
  1. 10:14:30episode starts
  2. 10:15:00status: open → webhook, PagerDuty, Opsgenie, SIEM, bell
  3. 10:47:10status: ended → the same incident resolved

dedupKey availability:3:syn-flood:2026-11-05T10:14:30Z · all-clear adds :ended

Sample incident, documentation addresses.

Time to alarm

As fast as each signal’s own cadence allows.

These are design targets that follow from how often each input reports, not a measured SLA. Verify them on your own links, with a controlled test against your own address under your written authorisation.

  • ~15 s

    Host counters

    Three consecutive 5-second samples, delivered in one report.

    design target

  • ~45 s

    Interface counters

    Three consecutive 15-second reports from the collector.

    design target

  • ~3 min

    Flow-derived metrics

    One value per completed minute of flow export.

    design target

Deployment

Five steps, and none of them gives us a way into your network.

  1. 01

    Register

    An Admin registers each router and host as a traffic source. Nothing is created automatically: a report from an unknown name is refused.

  2. 02

    Mint a key

    One key per agent, carrying only the isolated availability:report scope. It can report traffic and read nothing back; an admin key does not work on that channel.

  3. 03

    Install

    cti-flow at the NOC and cti-vitals on exposed Linux servers: one standard-library Go binary each, an unprivileged user, a hardened systemd unit, a kill-switch file.

  4. 04

    Point the routers

    On MikroTik RouterOS 6 and 7: one Traffic-Flow target, one read-only SNMP community that admits the collector only, two firewall lines. Through your own change process.

  5. 05

    Learn, then page

    Seven days of learning per source: charted, never paged. One notification when learning completes; from then on, alarms and all-clears.

Your routers stay yours

Nothing on the router can be changed by the platform.

The collector reads; it cannot write. There is no SNMP SET in the binary (a safety test fails the build if the SET message type ever appears), no RouterOS API, SSH or REST client, and no way to run a command. It opens one UDP listener for flow export and one socket to port 161, and reports over HTTPS.

  • RouterOS 6 and 7. The mixed-fleet common denominator: Traffic-Flow v9 and SNMP v2c GET, both generations.
  • Collector only. The community’s address list and a firewall rule admit the collector and nobody else; the setup guide also restricts RouterOS’s default community.
  • Reversible in four lines. Four commands remove the flow target, switch Traffic-Flow off, and remove the community and both firewall rules.
RouterOS · per router
# attribution: flow export to the collector
/ip traffic-flow set enabled=yes interfaces=<wan> \
    active-flow-timeout=1m inactive-flow-timeout=15s
/ip traffic-flow target add dst-address=<collector> \
    port=2055 version=9

# detection: read-only SNMP, collector only
/snmp set enabled=yes
/snmp community add name=<ro-community> \
    addresses=<collector>/32 read-access=yes write-access=no
/ip firewall filter add chain=input protocol=udp \
    dst-port=161 src-address=<collector> action=accept
/ip firewall filter add chain=input protocol=udp \
    dst-port=161 action=drop

Detection only, on purpose

Mitigation needs a credential that can change your network. We chose not to hold one.

  • no RTBH · no FlowSpec · no firewall push

    Nothing is announced or blocked

    No blackhole route, no FlowSpec rule, no address-list push, no rate limit, no call to a scrubbing provider’s API. Neither agent nor the platform holds a credential that could do any of it.

  • your runbook

    The hand-off is yours

    Calling your ISP or switching on your scrubbing service stays in your runbook. The incident carries what they will ask for (target, kind, rates, source networks), and the all-clear tells them when to stand down.

  • never minted

    A flood never feeds the blocklist

    Source networks from a volumetric attack are claims, and spoofable. Turning them into indicators could write your own customers into your blocklist, so the module mints nothing.

Straight answer

Honest limits.

  • Linux hosts only

    The host agent reads Linux kernel counters. There is no Windows agent yet; on any other platform the binary says so and exits.

  • SNMP v2c, no sFlow

    Read-only v2c GET is what a mixed RouterOS fleet speaks. SNMPv3, sFlow and the RouterOS 7 REST API are not supported yet; flow data comes from NetFlow v5/v9 or IPFIX (RouterOS Traffic Flow).

  • A week-long attack becomes normal

    The baseline follows the data. A sustained attack that runs through the learning window, or for a week, teaches the baseline. Learn on a representative week; resetting learning discards an inflated baseline.

  • Only what you point it at

    It sees the links and hosts you instrument. An attack on infrastructure it has no telemetry from, or one stopped upstream, is invisible to it.

  • Spoofed sources stay claims

    Flow attribution names source networks, not attackers. Only networks your sensors have met are marked real; everything else is shown as a claim.

  • Slow application attacks

    Low-rate attacks such as slowloris register only where the host’s own counters show connection exhaustion. A flash crowd and an attack are not told apart without host or sensor evidence.

Licensing

A module of its own, scoped by traffic sources.

Availability & DDoS detection sits outside the four packages and is licensed separately. It is scoped by the number of traffic sources you register: each router and each host is one.

Point one router at it.

One collector, one border router, one exposed server. After seven days of learning you will know what normal looks like on your links, and the first time it stops being normal.