aspa¶
Validate AS paths using RPKI ASPA.
Synopsis¶
Description¶
The aspa stage performs ASPA verification (draft-ietf-sidrops-aspa-verification, as of revision -29, tested against its published examples) of BGP UPDATE messages: it detects route leaks by verifying that the AS_PATH is valley-free, using ASPA records that attest provider-customer relationships between ASes. Each path is assigned one of three states:
- VALID -- the path is valley-free with full cryptographic attestation
- UNKNOWN -- the path appears valley-free but some ASes lack ASPA records (insufficient attestation, not evidence of a leak)
- INVALID -- the path provably violates valley-free routing (route leak)
ASPA records come from the shared RPKI cache, maintained by the bgpipe core
and configured with the global --rpki options -- see
RPKI Data Source for details. Note that ASPA
records require an RTR v2 server
(draft-ietf-sidrops-8210bis)
or a JSON file with ASPA data.
ASPA verification also requires knowledge of the peer's BGP role, so
--role is required. Set it explicitly to the role you configured for the
peer on your router. With --role auto, the role is taken from the
RFC 9234 BGP Role capability
in the peer's OPEN message, and if the peer does not send it, ASPA validation
is skipped for the session (with a warning).
--role auto trusts the peer being validated
With auto, the peer itself chooses how it is validated: it can omit the
Role capability (ASPA is skipped), claim provider (the lenient downstream
procedure, which lets route leaks through), or claim rs (the first-hop
check is skipped). bgpipe does not compare the peer's role with the role in
the other side's OPEN. For security use, always set an explicit role;
auto is meant for trusted peers, labs, and -LR monitoring.
ASPA applies to eBGP sessions: an announcement with an empty AS_PATH, or with an AS_SET, is INVALID. Withdrawals are not checked.
The stage also verifies that the first AS in the path matches the neighbor's
ASN (per draft-ietf-sidrops-aspa-verification, Section 5). This check is
skipped for Route Server peers (--role rs), as RSes do not prepend their ASN
(RFC 7947), and can be
disabled entirely with --first-hop=false -- see
Multi-peer feeds.
Actions for INVALID paths¶
ASPA validates the entire AS_PATH (one per UPDATE), so the --invalid action
applies to the whole message:
| Action | Behavior |
|---|---|
withdraw |
Move all reachable prefixes to withdrawn |
drop |
Drop the entire UPDATE message |
keep |
Keep unchanged (tag only) |
Tags¶
When --tag is enabled (default), the message gets an aspa/status tag.
For INVALID paths, the failing hop is reported in aspa/invalid-hop as
"<customer-asn> <provider-asn>". These can be used in downstream
filters.
Options¶
| Option | Type | Default | Description |
|---|---|---|---|
--invalid |
string | withdraw |
Action for INVALID paths: withdraw, drop, keep |
--tag |
bool | true |
Add aspa/status and aspa/invalid-hop tags |
--event |
string | Emit named event on INVALID paths | |
--role |
string | (required) | Peer's BGP role: provider, customer, peer, rs, rs-client, or auto (see above) |
--peer-tag |
string | Read the peer ASN from given message tag (eg. PEER_AS) instead of OPEN |
|
--first-hop |
bool | true |
Check that path[0] equals the neighbor ASN; disable for collector feeds (RFC 7947) |
--no-wait |
bool | false |
Start before the RPKI cache is ready |
Multi-peer feeds¶
Route collector feeds like ris-live and rv-live
aggregate sessions from many different peers in a single message stream, so
there is no single OPEN message to take the neighbor ASN (or BGP role) from.
Use --peer-tag PEER_AS to read the neighbor ASN per-message from the tag
that these stages attach, which enables the first-hop check for every peer
individually. --peer-tag requires an explicit --role, which then applies
to all peers in the stream. If a message lacks the tag, the first-hop check
is skipped for that message.
On a collector feed the first-hop check is often more noise than signal: the
collector's PEER_AS is not a real routing adjacency, and IXP route servers
in the feed do not prepend their ASN (RFC 7947),
so a legitimate path whose path[0] is the route server's client is flagged
INVALID. Pass --first-hop=false to drop the check entirely and validate paths
only on their merits (the valley-free / attestation checks), which is the
appropriate posture for passive monitoring of a multiplexed collector feed.
The --role option specifies the peer's BGP role (from the peer's
perspective, per RFC 9234):
--role value |
Meaning | ASPA direction |
|---|---|---|
provider |
Peer is our provider | Downstream (route came from above) |
rs |
Peer is a Route Server | Upstream (first-hop ASN check is skipped) |
customer |
Peer is our customer | Upstream (route came from below) |
rs-client |
Peer is an RS client | Upstream |
peer |
Peer is a lateral peer | Upstream |
auto |
Take from the peer's BGP Role capability (trusts the peer) | Depends on the claimed role |
In bidirectional (-LR) mode only --role auto is allowed: a single explicit
role cannot describe two different peers.
Prometheus Metrics¶
| Metric | Type | Description |
|---|---|---|
bgpipe_aspa_messages_total |
counter | UPDATE messages processed |
bgpipe_aspa_valid_total |
counter | Paths with ASPA state VALID |
bgpipe_aspa_unknown_total |
counter | Paths with ASPA state UNKNOWN |
bgpipe_aspa_invalid_total |
counter | Paths with ASPA state INVALID |
bgpipe_rpki_aspa_entries |
gauge | ASPA records loaded in the shared cache |
Examples¶
ROV + ASPA with explicit peer role:
Note that messages dropped by an earlier stage never reach later stages: with
rov --invalid drop placed before aspa, dropped messages are not ASPA
validated at all. Put aspa first if you want its tags and metrics to cover
every UPDATE.
ASPA route-leak monitoring on a live route collector feed, with current RPKI data fetched from the rpki-client console (tag everything, enforce nothing):
bgpipe -g --rpki https://console.rpki-client.org/vrps.json \
-- ris-live \
-- aspa --role provider --peer-tag PEER_AS --invalid keep \
-- grep 'tag[aspa/status] == INVALID' \
-- write invalid-paths.json
Use a local JSON file with ASPA records:
bgpipe --rpki /var/lib/rpki/export.json \
-- listen :179 \
-- aspa --role customer --invalid drop \
-- connect 192.0.2.1
Emit an event for detected route leaks:
bgpipe --events aspa/leak \
-- listen :179 \
-- aspa --role customer --invalid keep --event leak \
-- connect 192.0.2.1
See Also¶
rov, grep, update, Stages overview
References¶
- draft-ietf-sidrops-aspa-verification -- Verification of AS_PATH Using ASPA Objects
- draft-ietf-sidrops-8210bis -- RTR v2 (adds ASPA support)
- RFC 9234 -- Route Leak Prevention and Detection Using Roles in UPDATE and OPEN Messages
- RFC 7947 -- Internet Exchange BGP Route Server