FlowSpec mitigation
RTBH blackholing (remotely-triggered blackhole — a BGP route that drops all traffic to the victim) takes the whole victim offline — it trades the attack for an outage. BGP FlowSpec (RFC 8955 for IPv4, RFC 8956 for IPv6) instead distributes a rule that drops only the matching attack traffic, so the victim keeps serving everything else.
iDry-run first
The generated rules appear in /api/v1/attacks (method, flowspec), in /api/v1/bans,
and in notifications before you ever set dry_run: false — so you can confirm them
against your upstream's FlowSpec support first. See Going live.
Enabling FlowSpec
Set the mitigation method to flowspec. The default method is blackhole (RTBH).
mitigation: flowspec # default method for all groups (default: blackhole)
flowspec:
action: discard # or rate_limit
rate_mbps: 100 # only used when action: rate_limit (inert under discard)
hostgroups:
- name: web
networks: ["203.0.113.0/26"]
mitigation: blackhole # per-group override
mitigation is overridable per hostgroup, so you can run FlowSpec
globally and fall back to blackhole for a specific prefix set (or vice versa).
Generated rules
On an attack, Kapkan derives a minimal rule set (at most 8) from the attack's classification and flow sample, matching the victim as destination plus the vector:
| Attack | Generated FlowSpec match |
|---|---|
| NTP / DNS / CLDAP / memcached / SSDP / chargen amplification | dst=victim, proto=udp, src-port=<reflected port> |
| SYN flood | dst=victim, proto=tcp, tcp-flags=SYN |
| Fragment flood | dst=victim, fragment |
| ICMP / UDP / TCP flood | dst=victim, proto=<icmp/udp/tcp> |
| mixed / unknown | dst=victim (plus a rule per dominant reflected source port in the sample) |
The victim is always matched as a /32 (IPv4) or /128 (IPv6). IPv6 FlowSpec works
identically to IPv4 — the same rules are generated, with the victim matched as a /128.
Outgoing attacks
For an outgoing attack — a compromised host flooding outward — the rule matches the host as source (the RFC 8955/8956 source-prefix), so it actually drops the outbound flood. This is unlike a destination-based RTBH blackhole, which only kills traffic to the host.
Source anchoring
By default every generated rule matches the victim as destination, dropping the attack vector
from all sources — including legitimate clients sending the same protocol. With
flowspec.source_anchored: true, when the attack sample shows a concentrated set of attacker
sources, Kapkan instead emits composite rules pinning both the victim (destination) and each
dominant attacker (source), so only the attackers are dropped and the victim's legitimate traffic is
spared.
flowspec:
action: discard
source_anchored: true # drop the attackers, not the protocol from everyone
min_source_concentration: 0.8 # ...only when the top sources cover >= this share (default 0.8)
It engages only when the dominant sources cover at least min_source_concentration of the sampled
attack within the 8-rule budget. A diffuse attack — reflection or spoofing spread across many
sources — never reaches that gate and falls back to the victim-anchored rule. Selected sources are
matched as host prefixes (/32, /128) only: there is no widening into larger prefixes, so a rule
can never spill onto an innocent neighbor of an attacker.
Caveats
-
The
tcp-flagsmatch for SYN floods is a bitmask that also matches SYN-ACK, so adiscardaction drops the victim's outbound-initiated connections too — preferrate_limitfor TCP vectors. To use it, setaction: rate_limitand a ceiling inrate_mbps(the examples above usediscard):flowspec: action: rate_limit # rate-cap the vector instead of dropping it rate_mbps: 100 # ceiling, megabits/s -
max_active_banscaps bans, not rules: a FlowSpec ban can carry up to 8 rules, so N bans can mean up to 8N rules in your upstream's RIB. Watch thekapkan_mitigate_flowspec_rulesmetric against your routers' FlowSpec route limit.
Rule action and lifecycle
Each rule carries a traffic-rate extended community: discard (rate 0) or a rate_limit
ceiling. FlowSpec bans share the same TTL, unban hysteresis, and max_active_bans lifecycle
as blackhole bans — see RTBH mitigation.
FlowSpec rides the same BGP neighbors as RTBH: it is negotiated as an additional
capability over the same BGP sessions (the FlowSpec AFI/SAFI), and a peer that does not
support it simply will not enable it. FlowSpec is not valid for calculation: total
hostgroups — there is no single victim prefix to match.
To confirm your upstream actually accepts the rules: in dry-run, check that the flowspec
field is populated in /api/v1/attacks. After going live, the kapkan_mitigate_flowspec_rules
metric with mode="real" should be non-zero. If a peer rejects FlowSpec,
Kapkan falls the ban back to blackhole and surfaces it in /api/v1/bans (the fell_back_from
and fell_back_reason fields) and in notifications — so a silent unsupported upstream stays
visible.
Related
- RTBH mitigation — the blackhole method and shared ban lifecycle.
- Escalation ladders — step up from alert to FlowSpec to blackhole over time.
- Configuration reference · Metrics · REST API