Verify AS paths with ASPAs, over RTR version 2
Origin validation says who may originate a prefix and nothing about the
rest of the path: it does not catch a route leak, nor a hijack that keeps
the right origin at the end of a made-up path. ASPAs, in which a network
lists its providers, do.
bgp-rpki:
- aspa: the ASPAs and the upstream and downstream verification procedures
of draft-ietf-sidrops-aspa-verification-24, tested against the draft's
wording as written.
- rtr: protocol version 2 (draft-ietf-sidrops-8210bis-23) with the ASPA
PDU and the new error codes.
- client: asks for version 2 and falls back to whatever older version the
cache speaks; keeps ASPAs with the VRPs, applied whole or not at all;
publishes which customers' ASPAs changed; tells the cache why it is
being left (Error Report); does not ask one version's serial of another.
Server:
- A peer has a role (provider, customer, peer, route server, route server
client), which decides how its paths are verified. Without one they are
not.
- A route whose path is invalid is refused ("ASPA invalid") and held, like
one with an invalid origin; accept_aspa_invalid exempts a peer.
- When ASPAs change, routes in the table whose path has a changed customer
on it are verified again, and held routes are released when they pass
both checks.
- The revalidator finds a route's peer by index instead of searching a
list for every route.
The status page and API show each peer's role, each route's path validity,
the number of ASPAs and the RTR version in use; bgp_rpki_aspas is on
/metricz.
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
This commit is contained in:
1 parent
bdaf226a16
commit
8086aa994f
35 files changed
+2484
-359
No files matched your search
+51
-3
@@ -23,7 +23,7 @@ When `http_endpoint` is set the binary also serves:
|
||||
| `GET /api/routes/local` | Originated routes |
|
||||
| `GET /api/routes/received` | Routes learned from peers; see "Finding a route" |
|
||||
| `GET /api/routes/rejected` | Routes peers announced that were refused, by peer |
|
||||
| `GET /api/rpki` | Route origin validation: the cache, the data and its age |
|
||||
| `GET /api/rpki` | Validation with the RPKI: the cache, the data and its age |
|
||||
| `GET /api/events` | Server-sent events for session and route changes |
|
||||
| `GET /metricz` | Prometheus metrics |
|
||||
|
||||
@@ -87,12 +87,60 @@ nothing is invalid any more.
|
||||
|
||||
The status page shows the cache, how fresh the data is, each route's
|
||||
validity, and how many of each peer's routes are held. `/api/rpki` has the
|
||||
same as JSON; `bgp_rpki_vrps{family}` and `bgp_rpki_updates_total` are on
|
||||
`/metricz`. Refused routes are counted under the reason `RPKI invalid`.
|
||||
same as JSON; `bgp_rpki_vrps{family}`, `bgp_rpki_aspas` and
|
||||
`bgp_rpki_updates_total` are on `/metricz`. Refused routes are counted under
|
||||
the reasons `RPKI invalid` and `ASPA invalid`.
|
||||
|
||||
The connection to the cache is plain TCP, without authentication: run the
|
||||
validator on the same host or on a network you trust.
|
||||
|
||||
## AS path verification (ASPA)
|
||||
|
||||
Origin validation says who may originate a prefix. It says nothing about the
|
||||
rest of the path, so it does not catch a route leak (a network passing its
|
||||
provider's or peer's routes on to another provider or peer), nor a hijack
|
||||
that keeps the right origin at the end of a made-up path. ASPAs do: in one,
|
||||
a network lists its providers, and a path that goes from that network to
|
||||
anyone else, where only a provider could come next, is invalid
|
||||
(draft-ietf-sidrops-aspa-verification).
|
||||
|
||||
Two things are needed for paths to be verified:
|
||||
|
||||
- a validator that hands out ASPAs, which takes version 2 of the
|
||||
RPKI-to-Router protocol (draft-ietf-sidrops-8210bis). The daemon asks for
|
||||
version 2 and falls back to 1 or 0 if that is what the validator speaks;
|
||||
the status page says which is in use, and warns when it is one without
|
||||
ASPAs;
|
||||
- `role` on the peer, saying what the peer is to us, because what a path may
|
||||
look like depends on who hands it over:
|
||||
|
||||
| `role` | The peer | Its paths |
|
||||
|--------|----------|-----------|
|
||||
| `CUSTOMER` | buys transit from us | must lead up through providers all the way |
|
||||
| `PEER` | exchanges its own and its customers' routes with us | the same |
|
||||
| `ROUTE_SERVER` | is an exchange's route server | the same; the path need not begin with the route server's AS |
|
||||
| `ROUTE_SERVER_CLIENT` | is a client of ours, where we are the route server | the same |
|
||||
| `PROVIDER` | sells us transit | may lead up, across one peering, and down |
|
||||
|
||||
A peer without a role has its origins validated and its paths not.
|
||||
|
||||
A path is **invalid** (refused, unless the peer has
|
||||
`accept_aspa_invalid: true`), **valid**, or **unknown**, which is what most
|
||||
paths are while few networks have an ASPA; unknown ones are taken. A path
|
||||
with an AS_SET in it is invalid, and so is one that does not begin with the
|
||||
peer's AS (other than from a route server). As with origins, routes follow
|
||||
the data: held while invalid, taken when they no longer are.
|
||||
|
||||
```
|
||||
rpki { caches { address: "127.0.0.1" port: 3323 } }
|
||||
peers {
|
||||
name: "transit"
|
||||
endpoint { address: "192.0.2.1" }
|
||||
remote_asn: 64496
|
||||
role: PROVIDER
|
||||
}
|
||||
```
|
||||
|
||||
## Finding a route
|
||||
|
||||
The status page has a look-up box over the received routes, and
|
||||
|
||||
Reference in new issue
Block a user