Chapter 11 · Part III · BGP & the internet

Securing routing: RPKI, ROV & ASPA

BGP believes what it is told. Any network can announce any block of addresses, and its neighbors will pass the news on unless something stops them. This chapter is about the somethings: the filters operators have written by hand for thirty years, the signed certificates that now say who may originate which prefix, and the newer records that say who may carry a route to whom.

3 statesfor every route under origin validation: Valid, Invalid or NotFound (RFC 6811, January 2013)
2 h 14 minfrom the first hijacking announcement of a YouTube /24 on 24 February 2008 to its withdrawal (18:47 to 21:01 UTC, RIPE NCC)
1 ASper ROA: each Route Origin Authorization names exactly one origin AS for its list of prefixes (RFC 9582)

Common mix-up: a route that RPKI marks Valid has not had its path checked. Route origin validation answers one narrow question: may the AS at the far end of this path originate this prefix? It cannot tell whether the path is real, because anyone can write the right AS number at the end. Checking the path is a separate job, done by ASPA or BGPsec, and both are much younger.

What goes wrong

Hijacks, leaks and fat fingers

If the idea of a route leak or a hijack is new, start with the short section on leaks, hijacks and RPKI in dynamic routing on networks.jelia.nyc. This chapter assumes it and goes into the mechanics, one incident type and one defence at a time.

Every BGP route is a claim with two parts: a prefix, and an AS path that ends in the AS that originated it. Nothing in the base protocol checks either part. A router accepts what its neighbor sends, applies its local policy, and passes on what it prefers (Chapter 09 covers those export rules). So the failures fall into a few families, depending on which part of the claim is false.

  • Origin hijack. An AS announces a prefix that belongs to someone else, exactly as the owner does. Now there are two origins for the same prefix. Each network that hears both picks one by its usual rules, which mostly means the shorter AS path, so the internet splits: networks closer to the hijacker send their traffic to the hijacker.
  • Sub-prefix hijack. The announcement is more specific than the owner's: a /25 inside the owner's /24. Now the two routes do not compete at all. Forwarding always uses the longest matching prefix (Chapter 02), so every router that hears the /25 sends traffic for that half of the block to the hijacker, however long its path. This is why more-specific hijacks travel so far.
  • Route leak. The prefix and origin are honest, but a network passes a route on to a neighbor it should never have gone to: typically a customer that learns routes from one provider and re-announces them to its other provider. Traffic then squeezes through a network that never meant to carry it. RFC 7908 sorts leaks into six types, listed below.
  • Fat-finger deaggregation. A network splits its own or its customers' prefixes into many more-specifics, often inside a traffic-engineering box, and they escape. More-specifics win everywhere, so a configuration mistake behaves exactly like a sub-prefix hijack.

Two real incidents show the families at work. On 24 February 2008, Pakistan Telecom began announcing a /24 that sat inside YouTube's /22. According to the RIPE NCC's case study, one of its upstream providers passed the announcement on to the rest of the internet, and YouTube traffic worldwide went to Pakistan. YouTube answered by announcing the same /24 itself, which only won back the networks that preferred its path. The hijack ended when the upstream withdrew the routes, 2 hours and 14 minutes after it began. That was a sub-prefix hijack, and its reach came from longest-prefix match.

On 24 June 2019, Cloudflare described a leak. A network used a BGP optimizer, a box that generates more-specific routes for internal traffic engineering. Those more-specifics went to a customer, the customer re-announced them to its other provider, and that large provider accepted and propagated them. Cloudflare reported losing about 15% of its global traffic at the worst of the incident. That was a leak and a deaggregation at once, and the post points out that customer prefix filtering would have stopped it at the large provider's edge.

RFC 7908 typeWhat leaks, and to whom
Type 1Hairpin turn with full prefix: a multihomed customer learns a route from one provider and announces it to another provider.
Type 2Lateral ISP-ISP-ISP: a network learns a route from one peer and announces it to another peer.
Type 3A network announces routes learned from its transit provider to a peer.
Type 4A network announces routes learned from a peer to its transit provider.
Type 5Prefix re-origination with a data path to the legitimate origin: routes are re-announced as if the leaker originated them, but traffic still eventually reaches the real owner.
Type 6Accidental leak of internal prefixes and more-specifics meant only for use inside a network.
Go deeper: why a shorter path or a longer prefix decides who gets hijacked

For an exact-prefix hijack, the outcome at each network depends on its own best-path decision (Chapter 03 and Chapter 09): local preference first, which usually favors routes from customers, then AS path length. A hijacker announcing to its own providers therefore wins wherever its path is shorter or its route arrives over a more-preferred relationship. That is why an origin hijack typically captures a region rather than the world.

A sub-prefix hijack skips that contest. The router's forwarding table holds both the /24 and the /25, and the lookup picks the /25 for any address it covers, regardless of the path behind it. The owner's usual counter, announcing the same more-specific, only returns the contest to the path-length rules. If the hijacker announced a /24 and providers commonly filter anything longer than /24 in IPv4, the owner has no more-specific left to announce.

The first line

Filters, limits and default deny

Long before any cryptography, the main defence was the plain discipline described in RFC 7454, the IETF's best current practice for BGP operations and security. It still does most of the work.

  • Customer prefix filters. A provider accepts from each customer only the prefixes that customer and its own customers are entitled to announce. The list is usually built from an Internet Routing Registry (IRR): a database in which networks publish route objects, saying which AS originates which prefix, and AS-sets, naming the ASes behind them. Tools turn those objects into filters automatically. IRR data is self-asserted and some registries check it loosely, so it is only as good as the care of whoever wrote it.
  • Maximum-prefix limits. Each session carries a ceiling on how many prefixes the neighbor may send. A customer that normally sends ten routes and suddenly sends a full table trips the limit, and the session is shut or the excess dropped. RFC 7454 recommends limits on every session, set with headroom above the normal count.
  • Default deny for eBGP. RFC 8212 (July 2017) changed the default: a router must not accept routes from, or send routes to, an external peer until a policy is configured for that peer. Before it, a new session with a missing policy line could accept or leak everything.
  • Bogon and martian filters. Reject routes for address space that should never appear on the internet, such as private and documentation ranges, and AS paths containing private or reserved AS numbers.
  • Protect the session itself. RFC 7454 also recommends TCP authentication and the Generalized TTL Security Mechanism (GTSM, RFC 5082), which accepts packets from a directly connected peer only if they arrive with the maximum TTL, something a distant sender cannot arrange. Chapter 08 covers sessions.

The industry's shared checklist for these norms is MANRS, Mutually Agreed Norms for Routing Security, an initiative whose participating networks commit to filtering, anti-spoofing, coordination contacts and publishing their routing data. Its weakness is the weakness of every hand-built filter: it protects the internet from your customers only if you write the filter, and it depends on registry data that nobody signed.

Signed permission

RPKI: certificates that follow the addresses

The Resource Public Key Infrastructure (RPKI, RFC 6480, February 2012) adds the missing signature. Its insight is that address space is already handed out in a strict hierarchy. IANA allocates to the five Regional Internet Registries; they allocate to national registries, local registries and ISPs; ISPs assign to customers. RPKI issues a certificate along each of those steps, and each certificate lists exactly which addresses and AS numbers its holder controls. A holder can only certify resources that are inside its own certificate, so the chain of signatures mirrors the chain of allocations.

With a certificate in hand, the holder of a prefix signs a Route Origin Authorization (ROA, profiled in RFC 9582, May 2024). A ROA says: these prefixes may be originated by this one AS. Each prefix may carry a maxLength, the longest more-specific of that prefix the AS may also announce. A network that originates from two ASes, or lets a provider originate on its behalf, signs one ROA per AS.

The RPKI chain: trust anchor, registry certificate, holder certificate and ROA, published to repositories, fetched by a relying-party validator and sent to routers over RPKI-to-Router Trust anchoran RIR's root certificate Resource certISP: 203.0.113.0/24 … ROA (signed) prefix 203.0.113.0/24 maxLength 24 origin AS 64500 signssigns Repositoriespublished objects Validatorrelying party fetch + verify RouterVRP table RPKI-to-Router(RFC 8210) VRP = (prefix, length, maxLength, AS)
Signatures run down the allocation tree; data flows right. Routers never touch certificates: a validator does the cryptography and hands them a flat list of Validated ROA Payloads.

Routers do not do the cryptography. A separate program called a relying party, or validator, downloads every published object from the repositories, checks each signature chain up to the trust anchors it is configured with, and boils the survivors down to a flat table of Validated ROA Payloads (VRPs). Each VRP is four values: address, prefix length, maximum length and origin AS. The validator then feeds that table to routers over the RPKI-to-Router protocol (RTR, version 1 in RFC 8210, September 2017), a simple protocol that sends the full table once and then incremental changes, the same style BGP itself uses. The routers only ever see the table.

Go deeper: what happens when the RPKI is unreachable

The design fails open. If a router loses its validator, or a validator cannot fetch fresh data, routes fall back toward NotFound rather than Invalid, and NotFound routes are still used under the common policy. That choice is deliberate: an outage in the security system should not take down the routes it protects. It also means operators run more than one validator, from more than one implementation, so that a single bug or stale cache does not quietly switch protection off.

RFC 6811 is explicit that validation state is a local property of the route, and that an implementation must not drop a route because of it unless configured to. What a network does with Invalid is policy.

The algorithm

Route origin validation

RFC 6811 (January 2013) defines route origin validation (ROV) precisely enough to implement in a few lines, and Instrument 1 below implements it exactly. For a route, take its prefix and its origin AS: the rightmost AS in the AS path. Then compare it with every VRP.

  • A VRP covers the route if the VRP's prefix contains the route's prefix: the same prefix, or a less specific one.
  • A VRP matches the route if it covers it, and the route's prefix length is no longer than the VRP's maxLength, and the route's origin AS equals the VRP's AS.
Valid ⇔ ∃ VRP: covers ∧ len ≤ maxLength ∧ origin = AS
Invalid ⇔ ∃ covering VRP ∧ no VRP matches
NotFound ⇔ no VRP covers the prefix
One matching VRP is enough to make a route Valid, however many other VRPs disagree. A route is Invalid only when somebody has made a statement about that address space and no statement allows this origin at this length. With no statement at all, the answer is NotFound: RPKI has nothing to say.

Two edge cases matter. A ROA naming AS 0 can never be matched, because no route can have origin AS 0. Publishing one is how a holder says "nobody should originate this space." And a route whose path ends in an AS_SET has no single origin, so it can never be matched either; RFC 9774 has since deprecated AS_SET altogether.

Here is the arithmetic for one ROA, 203.0.113.0/24 with maxLength 24 for AS 64500, against four routes.

RouteOriginCovered?Length ≤ 24?AS matches?Result
203.0.113.0/2464500yesyesyes✓ Valid
203.0.113.0/2464510yesyesno✕ Invalid: wrong origin (origin hijack)
203.0.113.128/2564510yesnono✕ Invalid: too long and wrong origin (sub-prefix hijack)
198.51.100.0/2464510no––? NotFound: no ROA covers it

Validation produces a label. The protection comes from the policy that uses it, and the policy that works is drop invalid: routes that are Invalid are discarded on import, and Valid and NotFound routes are treated normally. NotFound must stay usable, because a large share of address space has no ROA at all, and dropping it would cut those networks off. Merely preferring Valid over Invalid does not help against a sub-prefix hijack, since the hijacker's /25 is the only route for that /25 and wins on longest match anyway.

The maxLength trap

maxLength looks like convenience. An operator who sometimes announces the two halves of a /24 might write one ROA for the /24 with maxLength 25, or even 32, instead of listing each prefix. RFC 9319 (October 2022) explains why that is dangerous, and recommends that operators use minimal ROAs, authorizing only the prefixes they actually announce, and in general avoid maxLength.

The reason is the forged-origin hijack. A hijacker does not have to put its own AS at the end of the path. It can announce 203.0.113.128/25 with the path "64510 64500", inventing a link to the real origin. Route origin validation sees origin 64500 and a /25. With a loose ROA allowing up to /25, that route is Valid, and as the only /25 around, it captures half the traffic by longest match. With a minimal ROA, maxLength 24, the same route is Invalid and dropped, because the owner never announces a /25. Instrument 1's second and third presets show both.

Instrument 1

Run route origin validation

Edit the ROA table (prefix, maxLength, origin AS) and the incoming routes (prefix and AS path, newest AS first, origin last). Each route is labelled exactly as RFC 6811 would label it, with the reason from every covering ROA. Select a route to see it on the prefix map: each row is one prefix length, each ROA is a band from its own length down to its maxLength, and a route is allowed only where it sits inside a band of its own origin. IPv6 works too.

ROAs (validated payloads)

PrefixmaxLenAS

Routes received

PrefixAS path
✓ Valid✕ Invalid? NotFoundTeal band = what a ROA allows
Valid–
Invalid (dropped)–
NotFound–

    Origin AS is the last AS in the path. Write an AS_SET as {64501 64502}: a path ending in one has no single origin and can never be matched. A ROA with AS 0 can never be matched either.

    Where origin checks stop

    Checking the path: roles and ASPA

    ROV is valuable and narrow. It stops origin hijacks, sub-prefix hijacks and most deaggregation accidents against prefixes with good ROAs. It cannot see two things: a forged-origin path that ends in the right AS, and route leaks, where every origin is honest and the problem is where the route went. For those, a router needs to know something about the relationships between the ASes in the path. Two complementary tools supply it.

    BGP roles and Only to Customer

    RFC 9234 (May 2022) lets two routers state their relationship in the OPEN message: Provider, Customer, Route Server, Route Server Client or Peer. If the roles do not fit together, a provider facing a provider for example, the session does not come up, which catches a whole class of misconfiguration. It also adds a path attribute, Only to Customer (OTC, attribute type 35). A route that is sent down to a customer, or across to a peer, is marked with OTC, and a route carrying OTC must never again be sent up to a provider or across to a peer. If one arrives from a customer anyway, the receiver knows it is a leak and treats the route as ineligible. OTC works best at the leaker's own edge: it is how a correctly configured router refuses to start a leak.

    ASPA: who are your providers?

    Autonomous System Provider Authorization (ASPA) is a newer RPKI object. A customer AS signs a list of its providers. That is all. But with those lists, a router can check the shape of any AS path. A legitimate path is valley-free: it climbs from the origin through customer-to-provider hops, crosses at most one peering link at the top, and descends through provider-to-customer hops to the receiver. A leak puts a valley in the path, a place where the route went down to a customer and then came back up.

    The verification algorithm, in the IETF SIDROPS working group's draft draft-ietf-sidrops-aspa-verification, works from both ends. From the origin it measures the up-ramp: how many hops in a row are attested customer-to-provider. From the receiver it measures the down-ramp the same way in reverse. If the two ramps together cannot cover the whole path, there is a hop that is neither going up nor going down where it should, and the path is Invalid. If missing records leave the answer open, the result is Unknown, which the draft treats like Valid.

    ASPA is still work in progress. As of 22 October 2026 the verification document is an Internet-Draft (revision 29, updated 16 October 2026), not an RFC, and so is the companion draft that defines the ASPA object itself. Router and validator support exists in some implementations, and details may still change.

    Invalid ⇔ max_up_ramp + max_down_ramp < N
    Unknown ⇔ otherwise, min_up_ramp + min_down_ramp < N
    N is the number of distinct ASes in the path. The "max" ramps stop only at a hop proven wrong (the customer has an ASPA and it does not list that provider). The "min" ramps also stop at a hop nobody attested. For a route from a customer or peer, the path must be all up-ramp, so the down-ramps are set to zero.
    Go deeper: ASPA catches forged origins too

    The forged path "64510 64500" claims that 64510 is a provider of 64500. If AS 64500 has published an ASPA listing its real providers, and 64510 is not among them, the first hop of the up-ramp fails, and so does the whole path. The ASPA draft makes this point itself: ROAs and ASPAs used together detect accidental leaks and malicious AS path manipulation. Neither helps a network that has not published its own records, which is why adoption by the origin matters as much as validation by everyone else.

    Before ASPA, large carriers protected each other from leaks with Peerlock: hand-maintained filters that reject a big network's AS appearing behind anyone who is not authorized to carry it. The ASPA draft describes Peerlock as laborious and manual, and positions ASPA as its automated replacement.

    Instrument 2

    Find the leak

    Enter an AS path as your router receives it (neighbor first, origin last), say what the neighbor is to you, and edit each AS's ASPA: the providers it has signed for, or no record at all. The detector computes the four ramp lengths exactly as the draft's sections 5.4 to 5.6 define them, and points at the hop that breaks the path. It is simplified: it leaves out route servers, the neighbor-AS check and AS_SETs.

    ASASPA?Providers it lists
    ✓ attested provider✕ not a listed provider? no ASPA recordabove a hop: going up toward the left; below: going up toward the right
    N (distinct ASes)–
    Up-ramp max / min–
    Down-ramp max / min
    HopIs the left AS a provider of the right? (up-ramp)Is the right AS a provider of the left? (down-ramp)
    The heavy option

    BGPsec: signing every hop

    BGPsec (RFC 8205, September 2017) is the complete answer to path forgery. It replaces the AS_PATH attribute with a BGPsec_PATH attribute, and every AS that forwards a route adds a digital signature covering the path so far and the AS it is sending to next. A receiver checks every signature against router keys published in the RPKI. Nobody can insert, remove or invent a hop without a key they do not have.

    The cost is in the same design. Signatures are made and checked per route, per hop, on every update. RFC 8205 requires a separate UPDATE for each prefix, where plain BGP can share one UPDATE among many prefixes with the same attributes. Every router needs its own keys. And protection only exists across an unbroken run of BGPsec speakers: the RFC's own section on partial deployment says that when a route reaches an AS that does not support BGPsec, it is converted back to an ordinary unsigned update, and the assurance is lost from that point on. Early adopters protect only routes that stay inside their group.

    BGPsec also does not detect route leaks. A leaked route carries perfectly good signatures; it has simply been sent somewhere it should not go. The ASPA draft calls the two technologies complementary for exactly this reason. In practice, operators have put their effort into ROV first and ASPA next, and BGPsec remains rare.

    Instrument 3

    Defence in depth

    No single mechanism stops every incident. Tick the defences a network deploys and the last column computes, for each incident type, the strongest protection left standing. Select any cell for the reasoning. "Stops" assumes the defence is deployed where the incident enters and the needed records exist; "Helps" means it stops some cases or limits the damage.

    Incident types stopped–
    Only helped–
    Unprotected–
    Select a cell to see why.
    In practice

    Is BGP safe yet?

    Not entirely, and the honest answer changes month by month, so this chapter describes it rather than quoting numbers that will age. Signing ROAs has become a routine service: the regional registries offer hosted RPKI, where the registry keeps the keys and the holder fills in a web form (the RIPE NCC's RPKI pages describe how its members do it). Many large transit networks and cloud providers now drop Invalid routes. Cloudflare runs Is BGP safe yet?, which tests whether your own connection's provider filters RPKI-invalid routes and keeps a list of operators' status.

    The incentive problem is that a ROA protects your prefixes only in networks that validate, and validating protects you only from prefixes that have ROAs. Each side's value grows with the other's adoption. ASPA has the same structure, one layer up. A checklist for one network, in roughly the order the work pays off:

    1. Default-deny eBGP, max-prefix limits on every session, bogon filters.
    2. IRR-built prefix filters on every customer session, regenerated automatically.
    3. Sign minimal ROAs for every prefix you originate; no loose maxLength.
    4. Run at least two validators and drop Invalid on every eBGP import.
    5. Configure BGP roles, which brings OTC with it, wherever your routers support RFC 9234.
    6. Publish an ASPA once your registry supports it, and validate ASPA when your routers do.

    How to watch for incidents as they happen, with route collectors and looking glasses, is the subject of Chapter 15. Who connects to whom, and why paths look the way they do, is Chapter 10.

    Cheat sheet

    Terms from this chapter

    Origin hijack
    An AS announcing a prefix it does not hold, exactly as the holder does, so the two compete on path selection.
    Sub-prefix hijack
    An announcement more specific than the holder's, which wins everywhere it is heard because forwarding uses the longest match.
    Route leak
    A route announced beyond its intended scope, such as a customer passing one provider's routes to another provider (RFC 7908).
    RPKI
    Resource Public Key Infrastructure: certificates that follow the address and AS allocation hierarchy, so holders can sign statements about their resources.
    ROA
    Route Origin Authorization: a signed object saying which single AS may originate a list of prefixes, each with an optional maxLength.
    maxLength
    The longest more-specific of a ROA's prefix that the named AS may announce; RFC 9319 advises avoiding it.
    Route origin validation
    Comparing a route's prefix and origin AS with validated ROAs to label it Valid, Invalid or NotFound (RFC 6811).
    Relying party
    The validator that downloads and checks RPKI objects and gives routers a flat table of validated payloads over RTR.
    Forged-origin hijack
    A hijack whose AS path ends in the real owner's AS, so origin validation passes it; stopped by minimal ROAs for more-specifics, and by ASPA or BGPsec.
    ASPA
    Autonomous System Provider Authorization: a signed list of an AS's providers, used to check that an AS path is valley-free. Still an Internet-Draft.
    OTC
    Only to Customer, the BGP attribute from RFC 9234 that marks a route as allowed to travel only downward to customers from here on.
    BGPsec
    BGP with a signature from every AS on the path (RFC 8205); strong against forgery, rarely deployed, and blind to leaks.
    Where this comes from

    Sources