VyOSLIII · Security HardeningSecurity
max-prefix as a security control — bounding a peer, and the outage it trades for
What you'll learn
- Place `maximum-prefix` correctly among the other control-plane defences, and state what it does not protect against
- Configure an inbound and outbound prefix limit under the neighbour address family on VyOS 1.5
- Explain why a prefix-limit trip is a latching outage on VyOS, and what compensating control that requires
- State plainly which prefix-limit options VyOS does not expose, for BGP and for the link-state protocols
- Recognise the production failure modes where the limit is too tight, too loose, or on the wrong address family
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) · 2026-08-19
A prefix limit is the operator’s defence against a peer that sends far more routes than the design accounts for. A peer that legitimately advertises 800 prefixes is healthy; the same peer suddenly advertising 800,000 is a leak, a compromise, or a misconfiguration, and unbounded it can exhaust the local router’s memory, stall best-path computation, and turn a single session into a router-wide outage.
The companion lesson vyos-xxviii-05-maximum-prefix covers the
knob itself and how to size it. This lesson asks the security
questions that sit on either side of it: where the limit belongs
among the other control-plane defences, what it deliberately does
not cover, and what it costs you when it fires — because on
VyOS the cost is a latching outage, and an operator who deploys
this control without knowing that has bought an availability
incident they did not budget for.
The threat model
The prefix limit is a bound on volume received from one peer. That is a narrow claim, and being precise about it is what stops it from being treated as general-purpose protection:
- A peer with a configuration error that starts re-advertising its other upstream’s full table instead of the agreed customer cone. This is the classic route leak and it is what the control was designed for.
- A compromised or hijacked peer injecting bulk prefixes to destabilise the local table.
- An internal session — a new iBGP peer, or a router-reflector client — that turns out to be carrying the full table into a part of the AS designed for a few thousand routes.
Where it sits among the other controls
flowchart TD
P["Peer UPDATE"] --> A["TCP transport controls<br/>MD5 / TCP-AO, TTL security, ACL"]
A --> B["Inbound prefix-list<br/>and AS-path filter"]
B --> C["RPKI origin validation"]
C --> D["maximum-prefix counter"]
D -->|under the limit| E["Loc-RIB"]
D -->|over the limit| F["CEASE notification<br/>session down, Idle (PfxCt)"]
Read the order carefully, because it is the source of a common misconception. FRR counts prefixes as they arrive from the peer, before your inbound policy runs. A peer sending 6,000 prefixes of which your prefix-list drops 5,500 still counts as 6,000 against the limit. That is deliberate: the cost the limit bounds is the cost of receiving, parsing and evaluating the prefixes, and you pay that whether or not you keep them.
The practical consequence is that a tight filter does not let you run a tight limit. Size the limit against what the peer sends, not against what you expect to keep.
The configuration
VyOS 1.5 places the limit under the neighbour’s address family, because a prefix limit is per address family — an IPv4 limit says nothing about how many IPv6 prefixes the same peer may send:
set protocols bgp system-as 64512
set protocols bgp neighbor 192.0.2.2 remote-as 65001
set protocols bgp neighbor 192.0.2.2 address-family ipv4-unicast maximum-prefix '5000'
set protocols bgp neighbor 192.0.2.2 address-family ipv4-unicast maximum-prefix-out '2000'
set protocols bgp neighbor 2001:db8::2 remote-as 65001
set protocols bgp neighbor 2001:db8::2 address-family ipv6-unicast maximum-prefix '1000'
Two settings, two directions:
maximum-prefixbounds what the peer may send you. This is the defensive half, and the one everybody configures.maximum-prefix-outbounds what you will advertise to the peer. This is the half that stops you being the incident: when an internal mistake suddenly makes 900,000 prefixes eligible for export to a customer contracted for 2,000, the export is capped rather than delivered. Upstreams increasingly require it in the peering agreement, and it is the half operators skip.
The trade this control makes
Two events, and conflating them is how operators end up surprised.
At 75% of the limit, FRR logs. The session stays up, prefixes keep being accepted, nothing else happens. 75% is FRR’s compiled-in default and, since VyOS does not expose the threshold node, it is the only value you get.
At the limit, FRR sends a CEASE notification carrying the
“Maximum Number of Prefixes Reached” subcode and drops the
session. The peer goes to Idle and stays there. There is no
automatic retry, because the retry is the restart option VyOS
does not expose.
That is the trade, stated plainly: the prefix limit converts an integrity-and-capacity risk (a peer floods your table) into a deliberate availability loss (that session is down until a human acts). For a customer session that is almost always the right trade. For your only transit session it may not be, and the decision belongs to whoever owns the availability target — not to whoever happened to be editing the BGP configuration.
Reading the down session
In show ip bgp summary, the State/PfxRcd column carries the
prefix count while the session is up and the reason while it is
down. This distinction is the entire diagnosis:
State/PfxRcd | What it means |
|---|---|
| a number | Established; that many prefixes received from this peer |
Idle (PfxCt) | Dropped by the prefix limit |
Idle (Admin) | Administratively shut down |
Active / Connect | Trying to establish — transport, not this mechanism |
“The session is down and I have a prefix limit configured” is not
evidence that the prefix limit dropped it. Idle (PfxCt) is.
vyos@r1:~$ show ip bgp summaryOnce identified, there are exactly three decisions, and resetting the session is none of them:
- Raise the limit, if the count that tripped it is legitimate and the number was wrong.
- Leave it down and go and talk to the peer, if the count is not legitimate. This is the correct answer more often than operators like — the control did its job and the incident belongs to the peer.
- Remove the limit, if it should never have been on this session at all.
Recovery, once one of those has been done, is manual:
reset bgp 192.0.2.2
The prefix count starts again from zero on the new session. Reset without fixing anything first and the count climbs back through 75%, past the limit, and the session drops again — a few minutes of table churn bought for nothing.
OSPF and IS-IS have no equivalent — say so rather than inventing one
BGP is the protocol you take routes from strangers over, and it
is the one with a prefix limit. The link-state protocols have
nothing comparable: neither FRR’s ospfd nor its isisd
implements a prefix or LSA count limit, and the VyOS
configuration tree exposes no node for one. There is no
set protocols ospf max-prefix and no per-interface IS-IS
equivalent; if you have seen one in a runbook, it came from
another vendor’s grammar.
Confirm it on your own box rather than taking this on trust — the tree is the authority:
set protocols ospf ?
set protocols isis ?
That is not a gap you can close with a knob, and pretending otherwise is worse than admitting it. The defence for a link-state protocol is structural, and it is the area design:
- Keep external LSAs out of the areas that do not need them.
set protocols ospf area 10 area-type stubbars Type-5 externals from the area entirely; addingno-summaryon the ABR bars the Type-3 inter-area summaries as well. An area that cannot receive an external LSA cannot be flooded with a million of them. - Bound what you inject. A route-map on redistribution —
set protocols ospf redistribute bgp route-map RM-OSPF-OUT— is what stops a large BGP table becoming a large LSDB. Most OSPF flooding incidents are self-inflicted through an unfilteredredistribute. - Summarise at the boundary.
set protocols ospf area 10 range 10.10.0.0/16collapses the area’s internal prefixes into one Type-3 rather than hundreds. - Authenticate the adjacency. An unauthenticated OSPF adjacency
is the mechanism by which a stranger gets to flood you at all;
vyos-liii-01-routing-protocol-authenticationcovers it. - Monitor the LSDB size. Since nothing will stop growth for
you,
show ip ospf databasecounts are what you alert on.
The honest summary for a design review: BGP sessions have a volume bound; OSPF and IS-IS adjacencies do not, and are kept safe by not extending them to parties you would need one for.
Failure modes
The limit is too tight — the session never stabilises
A limit sized for a customer cone applied to a full-table upstream. The session comes up, converges toward a million prefixes, trips, and latches. It looks like a flap but it is not: each cycle needs a human reset in between.
Diagnostic:
show ip bgp summary
show ip bgp neighbors 192.0.2.2
State/PfxRcd reads Idle (PfxCt), and Up/Down resets to
minutes each time somebody clears it. Fix by sizing the limit
from the peer’s real count with headroom — and by asking where
the number came from, because it is nearly always a template
written for a different kind of session.
The limit is too loose — the control is decoration
A limit of one million on a peer contracted for 2,000 prefixes. The peer leaks 850,000 routes, the local table grows by an order of magnitude, best-path computation slows, memory pressure climbs — and the limit never fires, because 850,000 is under the bound. The audit shows a prefix limit configured on every session and the incident happened anyway.
Diagnostic:
show ip route summary
show ip bgp summary
The route-summary total is far above the design figure and
State/PfxRcd for that peer is a number three orders of
magnitude larger than the agreement. Fix by sizing from the
relationship: a customer cone gives a limit in the low thousands,
a full-table transit session gives a limit in the low millions,
and using the same number for both means one of them is wrong.
The limit is on the wrong address family
A generous IPv4 limit and no IPv6 limit at all — the common shape, because IPv6 is configured later and the limit is not copied across. The IPv6 table is smaller, so an IPv6 leak is a smaller number of prefixes and completely unbounded. Set a limit for every address family the peer carries.
The 75% warning goes nowhere
The mechanism warned, on time, and the warning landed in a log
file nobody reads. The first human signal was the session
dropping. This is the most common failure of the lot and it is not
a failure on the router: the fix is in the monitoring pipeline,
alerting on MAXPFX.
Somebody automated the reset
A cron job or a monitoring “self-heal” action reproduces the
missing restart option. The session now flaps for as long as the
peer misbehaves, and the evidence is destroyed on each cycle.
Delete the job; the Idle (PfxCt) state is the point.
Rollback
A prefix-limit change is a configuration change and takes the standard path:
comparebeforecommit, so you see exactly what you are arming.commit-confirm 10for any change made over a session that traverses the peer you are about to bound. If the limit is wrong, the router reverts it without you.rollback 1thencommitandsaveto return to the previous configuration.delete protocols bgp neighbor 192.0.2.2 address-family ipv4-unicast maximum-prefixthencommitto remove the bound entirely. Note what this actually does: the peer is now unprotected. It is a legitimate emergency step when a session must stay up while sizing is worked out, and it must come with a note in the change record and a date to put it back.
VyOS does not check that every BGP peer has a limit. There is no
validator for “unprotected peer”, and a missing limit is
invisible in show ip bgp summary. The audit is
show configuration commands | match maximum-prefix compared
against the peer list — by hand, or by whatever configuration
review you already run.
Production discipline
Cross-course references
XXVIII-VyOS-BGPPrefixFilter(vyos-xxviii-05-maximum-prefix) covers the knob itself, the sizing procedure, and the soft-launch that replaces the warning-only mode VyOS does not have.vyos-liii-03-prefix-filteringandvyos-liii-04-rpkicover the controls that catch the small, targeted event a counter cannot.vyos-liii-01-routing-protocol-authenticationcovers who is allowed to form an adjacency in the first place.vyos-liii-05-control-plane-protectioncovers the TCP 179 listener and the CPU budget the limit is protecting.XXIII-VyOS-BGPFundamentalscovers the Adj-RIBs-In / Loc-RIB distinction the counting order depends on.- The Linux course’s
XXII-Linux-NetTroubleshootcovers the table-exhaustion diagnostic on the host side.
Quiz
Knowledge check · 4 questions
Q1. What does the BGP `maximum-prefix` configuration protect against?
Q2. On VyOS 1.5, a BGP session is torn down as soon as the received prefix count reaches 75% of the configured `maximum-prefix`.
Q3. A customer session on R1 shows `Idle (PfxCt)`. The operator expects it to re-establish by itself after a few minutes and it does not. Explain what the router is doing and what the operator should actually do.
R1 peers with a customer at 10.0.0.1 (AS 65001), contracted for roughly 2,000 prefixes, configured with `set protocols bgp neighbor 10.0.0.1 address-family ipv4-unicast maximum-prefix 5000`. The session was Established for months. It is now `Idle (PfxCt)` in `show ip bgp summary` and has stayed that way for an hour.
Q4. R1 peers with a customer expected to send about 2,000 prefixes. The operator set the limit to one million. The customer starts re-announcing a full table, R1 accepts 850,000 routes, and bgpd pins a core. Why did the control not fire, and what is the fix?
R1 carries `set protocols bgp neighbor 10.0.0.1 address-family ipv4-unicast maximum-prefix 1000000` on a customer session designed for a 2,000-prefix cone. The customer's router is misconfigured and is re-advertising its other upstream's full table. An hour later R1's BGP process is at 95% of a core and `show ip route summary` reports 850,000 more IPv4 routes than the design figure.
Passing score: 75%. Answers are checked in this browser.