VyOSXXXI · BGP TroubleshootingTroubleshooting
BGP blackhole — route leak, prefix hijack, RPKI invalid, BGP dampening
What you'll learn
- Distinguish the four causes of BGP blackhole — route leak, prefix hijack, RPKI invalid, dampening suppression
- Configure RPKI validation with set protocols rpki and enforce it with a route-map
- Apply prefix-list, filter-list and maximum-prefix to prevent inbound leaks and hijacks
- Use the RFC 7999 blackhole community to discard traffic to a known-bad prefix
- Recognise the production failure modes — leak from upstream, hijack from peer, RPKI misconfiguration, dampening of legitimate routes
Prerequisites
Verified against VyOS 1.5.x LTS (circinus) · VyOS 1.4.x (sagitta) — legacy · FRRouting 10.x (VyOS 1.5) · Linux kernel 6.6 LTS (VyOS 1.5 base) · strongSwan 5.9.x (IPsec) · WireGuard 1.0.x (kernel module + userspace tooling)
A BGP blackhole — traffic destined for a prefix is discarded or routed into the void — has four operational causes: a route leak (an AS advertises a prefix it does not own), a prefix hijack (an AS advertises a more-specific prefix to attract traffic to itself or to drop it), an RPKI-invalid route (the route’s origin AS does not match the Route Origin Authorisation), or a dampened legitimate prefix (the prefix is suppressed by route-flap damping). Each cause leaves different evidence and has a different production-grade prevention.
This lesson walks the four causes, the operational evidence that distinguishes them, and the VyOS 1.5 configuration that prevents them.
The four causes and their evidence
flowchart TD
BH[Traffic blackholed] --> Q1{Is the route in BGP?}
Q1 -->|"no advertisement at all"| LE[Route leak upstream — they never sent it]
Q1 -->|"yes, multiple paths"| Q2{Which path won?}
Q2 -->|"an AS that does not own it"| HJ[Prefix hijack]
Q2 -->|"the legitimate origin"| RPKI{RPKI state?}
RPKI -->|"invalid"| RI[RPKI invalid — origin does not match the ROA]
RPKI -->|"valid or notfound"| Q3{Suppressed by damping?}
Q3 -->|"yes"| DM[Dampening suppression]
Q3 -->|"no"| OK[BGP is fine — investigate the FIB and downstream]
LE --> FIX1[Contact upstream NOC]
HJ --> FIX2[RPKI, prefix-list, contact peer NOC]
RI --> FIX3[Contact the ROA holder]
DM --> FIX4[Remove the damping configuration or wait for decay]
The first decision is whether the route is in BGP at all. If it is, the second is which path won — a path whose origin AS does not own the prefix indicates a hijack. The third is the RPKI state. The fourth is whether damping has suppressed a route that is otherwise fine.
Cause 1 — Route leak
An AS advertises a prefix it does not own. The canonical scenario: AS 64512 leaks a prefix owned by AS 65001 to its upstream, the upstream accepts the leak, and the rest of the Internet routes the prefix via the leaking AS. Traffic destined for the prefix arrives at AS 64512, which has no route to the actual owner, and the traffic is dropped.
Route leaks are typically caused by a missing or wrong outbound filter on the leaking AS. The leaking AS operator believes they own the prefix — incorrect internal documentation, a stale IRR object — and advertises it.
Diagnosis for route leak
show bgp ipv4 198.51.100.0/24
show bgp ipv4 regexp _64512_
show configuration commands | match "policy prefix-list"
The first command shows the candidate paths and their origin AS. The second finds everything transiting the suspect AS. The third shows the filters you actually have, which is often the real answer.
The canonical evidence is an origin AS that does not own the prefix per the IRR. Validate from the shell:
whois -h whois.radb.net 198.51.100.0/24
Prevention
Option 1 — strict inbound prefix-list. Permit only the prefixes the peer is contracted to advertise; reject the rest.
set policy prefix-list UPSTREAM-IN rule 10 action 'permit'
set policy prefix-list UPSTREAM-IN rule 10 prefix '198.51.100.0/24'
set policy prefix-list UPSTREAM-IN rule 20 action 'permit'
set policy prefix-list UPSTREAM-IN rule 20 prefix '203.0.113.0/24'
set protocols bgp system-as '64500'
set protocols bgp neighbor 192.0.2.2 address-family ipv4-unicast prefix-list import 'UPSTREAM-IN'
VyOS 1.4 moved this attachment point. The 1.3 form was a prefix-list ... in leaf directly under the neighbour; from 1.4 onward the filter lives under an explicit address-family, and the direction word is import / export rather than in / out.
Option 2 — maximum-prefix. Cap how many prefixes the peer may send.
set protocols bgp neighbor 192.0.2.2 address-family ipv4-unicast maximum-prefix '100'
Cause 2 — Prefix hijack
An AS advertises a prefix — or a more-specific of one — that it does not own, in order to attract traffic. The traffic arrives at the hijacker’s AS and is inspected, modified, or dropped.
The canonical scenario: AS 65001 owns 198.51.100.0/24. AS 64512 advertises 198.51.100.0/25. Forwarding is longest-prefix-match, so the /25 wins for the addresses it covers regardless of any BGP attribute — this is why a more-specific hijack works even against a peer whose policy prefers the legitimate origin.
Diagnosis for prefix hijack
show bgp ipv4 198.51.100.0/25
show bgp ipv4 198.51.100.0/24
show bgp ipv4 regexp _64512_
Compare the origin AS on the more-specific with the origin AS on the covering prefix. If they differ and the more-specific is new, you are looking at a hijack or at a customer who forgot to tell anyone.
Prevention
Option 1 — RPKI origin validation. Covered in full below.
Option 2 — inbound AS-path filter. Permit only paths that originate in the contracted AS.
set policy as-path-list UPSTREAM-AS rule 10 action 'permit'
set policy as-path-list UPSTREAM-AS rule 10 regex '^64512_'
set protocols bgp neighbor 192.0.2.2 address-family ipv4-unicast filter-list import 'UPSTREAM-AS'
The regex ^64512_ anchors 64512 at the left-hand end of the AS path — the neighbouring AS — and the trailing underscore matches a separator so it does not also match 645120.
Cause 3 — RPKI invalid
RPKI associates a prefix with the ASN authorised to originate it, in a signed Route Origin Authorisation. The router learns the validated set from an RPKI validator over the RTR protocol and can then classify every received route as valid, invalid, or notfound.
Enforcement is a route-map, applied on import:
set policy route-map ROUTES-IN rule 10 action 'permit'
set policy route-map ROUTES-IN rule 10 match rpki 'valid'
set policy route-map ROUTES-IN rule 10 set local-preference '300'
set policy route-map ROUTES-IN rule 20 action 'permit'
set policy route-map ROUTES-IN rule 20 match rpki 'notfound'
set policy route-map ROUTES-IN rule 20 set local-preference '125'
set policy route-map ROUTES-IN rule 30 action 'deny'
set policy route-map ROUTES-IN rule 30 match rpki 'invalid'
set protocols bgp neighbor 192.0.2.2 address-family ipv4-unicast route-map import 'ROUTES-IN'
set protocols bgp neighbor 192.0.2.2 address-family ipv4-unicast soft-reconfiguration inbound
That is the whole enforcement mechanism: valid is preferred, notfound is accepted but demoted, invalid is denied.
Cause 4 — Dampening suppression
Route-flap damping assigns a penalty each time a route withdraws and returns. When the accumulated penalty passes the suppress threshold the route stops being advertised; the penalty halves every half-life until it falls below the re-use threshold, at which point the route comes back.
set protocols bgp parameters dampening half-life '15'
set protocols bgp parameters dampening re-use '750'
set protocols bgp parameters dampening start-suppress-time '2000'
set protocols bgp parameters dampening max-suppress-time '60'
Dampening is a global BGP parameter on VyOS — protocols bgp parameters dampening — not a per-neighbour knob. There is no way to damp one peer and not another from this tree.
The canonical failure: a planned maintenance flaps a peer’s prefixes for half an hour, the penalties cross the suppress threshold, and prefixes stay suppressed long after the maintenance ends.
Diagnosis
show bgp ipv4 dampening dampened-paths
show bgp ipv4 dampening flap-statistics
show bgp ipv4 neighbors 192.0.2.2 dampened-routes
The first lists what is currently suppressed, the second the flap history that got it there, and the third narrows it to one peer.
Blackhole communities
The other half of blackhole work is the deliberate kind: asking an upstream to discard traffic to one of your addresses because it is under attack.
RFC 7999 reserves the well-known community 65535:666 — BLACKHOLE — for exactly this. Tag a host route with it on the way out and a provider that honours it drops the traffic at their edge, well upstream of your congested link.
set protocols static route 198.51.100.42/32 blackhole
set policy prefix-list RTBH-OUT rule 10 action 'permit'
set policy prefix-list RTBH-OUT rule 10 prefix '198.51.100.42/32'
set policy route-map UPSTREAM-OUT rule 10 action 'permit'
set policy route-map UPSTREAM-OUT rule 10 match ip address prefix-list 'RTBH-OUT'
set policy route-map UPSTREAM-OUT rule 10 set community add '65535:666'
set protocols bgp neighbor 192.0.2.2 address-family ipv4-unicast route-map export 'UPSTREAM-OUT'
On the receiving side — if you are the one honouring a customer’s blackhole request — the classic design points the route at an address you have already discarded locally:
set protocols static route 192.0.2.254/32 blackhole
set policy community-list BLACKHOLE rule 10 action 'permit'
set policy community-list BLACKHOLE rule 10 regex '65535:666'
set policy route-map CUSTOMER-IN rule 10 action 'permit'
set policy route-map CUSTOMER-IN rule 10 match community community-list 'BLACKHOLE'
set policy route-map CUSTOMER-IN rule 10 set ip-next-hop '192.0.2.254'
How the result is validated
show bgp ipv4
show bgp ipv4 198.51.100.0/24
show bgp ipv4 regexp _65001$
show bgp ipv4 community 65535:666
show bgp ipv4 dampening dampened-paths
show ip route 198.51.100.0/24
The last one matters most and is the one people skip: BGP holding the route you expect proves nothing about the FIB. show ip route is where you find out whether the kernel actually forwards it — including whether one of your own blackhole statics is winning on administrative distance.
How it fails
The production failure modes the engineer must recognise:
- Route leak from upstream. The upstream advertises a prefix they do not own. Fix: contact their NOC; add an import prefix-list on your side.
- Prefix hijack by an AS not in the IRR. Fix: RPKI enforcement, an import filter-list anchored at the correct end of the path, and both NOCs.
- RPKI invalid from a wrong or expired ROA. Fix: coordinate with the prefix owner. Do not assume malice.
- Your own prefix invalid because the ROA
maxLengthis too short. Fix: republish the ROA. Until you do, every RPKI-enforcing network drops you. - Validator down, validation silently off. The router keeps forwarding without origin validation and retries in the background. Nothing in the BGP table says so. Fix: monitor the validator.
maximum-prefixtripped by a legitimate growth in the peer’s table. The session is destroyed, not warned about. Fix: raise the limit; there is no gentler mode to fall back to.- Dampening suppression after planned maintenance. Fix: wait for the half-life, or remove
protocols bgp parameters dampeningand accept the global effect. - BGP looks right, traffic still black-holes. A static blackhole route with a better administrative distance is beating the BGP path. Fix:
show ip route, then fix the static.
Rollback
Blackhole-mitigation fixes are configuration changes, so the rollback is a configuration rollback:
deletethe specific node you added andcommit— the surgical option, and the only one that does not interrupt service.rollback Nreturns the whole configuration to a revision, but it reboots the router. On a box that is currently absorbing an attack, that is a decision to make deliberately.reset bgp ipv4 192.0.2.2 soft inre-runs import policy against the stored updates after you change a route-map — which needssoft-reconfiguration inboundon that neighbour to work.
If a blackhole route-map was added during an incident, remove the community-tagging rule rather than the whole route-map, or you will drop the rest of the export policy with it.
Production discipline
Cross-course references
The Linux course’s XIX-Linux-NetFoundations covers the kernel FIB that show ip route reflects. The OPNsense course’s XXX-OPNsense-DynamicRouting covers the equivalent FRR behaviour on the firewall side. The BGP lessons vyos-xxv-01-bgp-network-statement, vyos-xxviii-05-maximum-prefix, and vyos-xxix-05-community-routing cover the underlying mechanisms. The lesson vyos-liii-04-rpki covers RPKI deployment in detail.
Quiz
Knowledge check · 4 questions
Q1. RPKI is configured with `set protocols rpki cache 192.0.2.1 port '3323'` and a preference, and the cache is connected. How does the operator tell, from operational mode, that a particular received prefix is RPKI-invalid?
Q2. Once `set protocols rpki cache ...` is configured and connected, RPKI-invalid routes are rejected without any further configuration.
Q3. An operator's upstream AS 64512 is advertising 198.51.100.0/24, but the IRR shows the legitimate owner is AS 65001. What is the most likely cause and fix?
The upstream AS 64512 is advertising a prefix they do not own — a route leak. The legitimate owner per the IRR is AS 65001. The upstream most likely has a missing or wrong outbound filter.
Q4. An AS is advertising 198.51.100.0/25, a more-specific of a /24 it does not own. Traffic for those addresses is being drawn to the hijacker. Why does the hijack work even on routers whose policy prefers the legitimate origin, and what is the response?
AS 65001 owns and announces 198.51.100.0/24. AS 64512 announces 198.51.100.0/25. Downstream operators have local-preference policy that favours AS 65001's paths, and the hijack still succeeds for every address inside the /25.
Passing score: 75%. Answers are checked in this browser.