GitHub

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:

AttackGenerated FlowSpec match
NTP / DNS / CLDAP / memcached / SSDP / chargen amplificationdst=victim, proto=udp, src-port=<reflected port>
SYN flooddst=victim, proto=tcp, tcp-flags=SYN
Fragment flooddst=victim, fragment
ICMP / UDP / TCP flooddst=victim, proto=<icmp/udp/tcp>
mixed / unknowndst=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-flags match for SYN floods is a bitmask that also matches SYN-ACK, so a discard action drops the victim's outbound-initiated connections too — prefer rate_limit for TCP vectors. To use it, set action: rate_limit and a ceiling in rate_mbps (the examples above use discard):

    flowspec:
      action: rate_limit            # rate-cap the vector instead of dropping it
      rate_mbps: 100                # ceiling, megabits/s
    
  • max_active_bans caps 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 the kapkan_mitigate_flowspec_rules metric 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.