Autonomous System Provider Authorization (ASPA) is a recently proposed solution designed to detect and mitigate route leaks and improbable AS paths. ASPA utilizes the existing RPKI infrastructure to allow storing and verifying cryptographically protected AS-level relationship information. In this article, we will zoom into the AS path verification process of ASPA.
Route leak
In overview, the definition of route leak considered in ASPA is based on RFC 7908: Problem Definition and Classification of BGP Route Leaks. The route leaks defined in this RFC is mostly based on the "valley-free" principle.
In our blog post on how we detect route leaks at Cloudflare, I roughly summarized the common four types of route leaks in the following table:
Routes from | To provider | To peer | To customer |
From provider | Type 1 | Type 3 | Normal |
From peer | Type 4 | Type 2 | Normal |
From customer | Normal | Normal | Normal |
In essence, route leaks defined in RFC 7908 can be summarized into one principle: routes obtained from a non-customer (peer, customer, route-server) AS can only be propagated to customers.
In ASPA, the authors inherited the definition of BGP roles (e.g. customer, provider) from RFC 9234. Read my previous blog post for more on the RFC9234 and the OTC BGP attribute.
ASPA TL;DR
The ASPA mechanism can be very roughly summarized into the following key points:
ASPA stores
customer-to-provider
information in RPKI- One customer AS (CAS) associated with a set of provider ASes (SPAS)
ASPA is useful for verifying BGP
AS_PATH
attribute contentAS_PATH
that violates the "valley-free" routing principle can be detected with ASPA objects information
ASPA is incrementally deployable, benefiting early adopters
ASPA Verification Explained
Before we dive into how ASPA detects route leaks, we will first take a quick look at what a normal route looks like.
A typical long BGP route that travels from one edge network to a different edge network would look like this:
The route travels three different phases:
upward: a consecutive
customer-to-provider
segmentspeering: a single
peer-to-peer
segmentdownward: a consecutive
provider-to-customer
segments
Note that in many cases, the routes may only have one or two phases, but they must be in this order. For example, one legit route could have an upward
then downward
phase, without a peering
phase. A route leak route could be any route with reverse order of the phases, e.g. downward
then upward
.
In ASPA, the phases are defined into two categories:
upstream
: path received from a customer or a peer or a route serverdownstream
: path received from a provider or sibling
The ASPA verification has different processes for upstream
paths and downstream
paths, we will explain each category in the rest of the section.
Upstream paths
ASPA verification for upstream paths (received from a customer or peer or route server) is relatively simple. The key principle is that a normal upstream path should only contain customer-to-provider
relationships for the consecutive AS path hops.
A path is
Valid
: if all hops in the AS paths are verifiablecustomer-to-provider
, i.e. every hop on the path registers their providers on ASPA and the providers match the next hop on the path;Unknown
: one of the hops is missing ASPA information;Invalid
: one of AS has a set of provider AS (SPAS) but the next hop is not in it.
Downstream paths
The downstream paths are considerably more complex as it may have legit paths segments that travel all three phases (up, peer, down) before reaching the receiving AS. Interested readers should refer to the original IETF draft document's section on downstream path verification for a more definitive definition. Here in this article, I will try to grossly simplify the wording to provide a rough high-level verification process for easier understanding and remembrance.
Based on the original documentation, a downstream
path is Invalid
if there exist hops indexed as u
and v
such that
u<=v
hop(AS(u-1), AS(u))="Not Provider+"
hop(AS(v+1),AS(v))="Not Provider+"
So, what does this mean? Here is my attempt on point-to-point translation:
two hops at the location
u
andv
andu
is beforev
hop
u
is verified to be NOT a customer-to-provider hop, i.e.peer-to-peer
orprovider-to-customer
, i.e. apeering
ordownward
phasehop v is verified to be NOT a provider-to-customer hop, i.e.
peer-to-peer
orcustomer-to-provider
, i.e. apeering
orupward
phase
In summary, the path would be ASPA Invalid
, if it contains a downward
or peering
then later a upward
or peering
. The AS relationship would look like the following figure, where u
and v
could be the same ASN. As long as this pattern appears somewhere in the path, it violates the "valley-free" routing and thus is considered as route leak.
The Unknown
and Valid
definition would be simple as
Unknown
: the path is NOTInvalid
and there are hops that miss ASPA informationValid
: the path is NOTInvalid
and NOTUnknown
ASPA vs RFC9234
ASPA and RFC 9234 both target to prevent/mitigate route leaks, but they diverge in their approach. The table below summarizes my understanding of the main differences.
ASPA | RFC9234 | |
By whom | Customer AS (owner) only | BGP sessions, providers |
Content security | Cryptographically signed | Secured by BGP session; OTC attributes can be forged |
Where to detect/filter | Any AS | Neighbors or ASes that receive OTC attribute |
Prevent forged path? | Yes | No |
Deployment when | Initial objects appeared already (see next section); general deployment will be 2025 or later (from Job Snijders) | The initial deployment appeared; the general deployment unclear |
How to view ASPA objects on RPKI today?
Although still in the draft phase, ASPA support has already been added to popular routing software like routinator and OpenBGPd. I've also added support for reading ASPA objects on RPKI to my tool BGPKIT monocle. Curious readers can already see what ASPA objects that are already on RPKI and view the content with monocle
. Here is a quick tutorial on how to do so.
Install BGPKIT monocle
BGPKIT monocle is a Rust-based BGP data processing command-line tool. Currently, to install monocle
, you will need to have Rust toolchain installed following the one-step command described in https://rustup.rs/
Then you can install monocle
by simply doing
cargo install monocle
Download the recent RPKI archive
To get the data archive of RPKI repositories, we use the RPKIViews project by Job Snijders. Take Job's own repo as an example, we first navigate the repo's main page at http://josephine.sobornost.net/josephine.sobornost.net/. Then go to a recent date directory and download one archive (about 260MB in size).
cd /tmp
wget http://josephine.sobornost.net/josephine.sobornost.net/rpkidata/2023/06/25/rpki-20230625T173535Z.tgz
tar xzf rpki-20230625T173535Z.tgz
Find and view ASPA objects
The ASPA objects are stored as files with the suffix .asa
in the RPKI repository. You can use find
command to search across the untarred repo file from the previous step:
➜ rpki-20230625T173535Z find . -name "*.asa"
./data/rpki.sub.apnic.net/repository/A914BC7A0000/0/AS148808.asa
./data/rpki.sub.apnic.net/repository/A914BC7A0000/0/AS148809.asa
./data/rpki.sub.apnic.net/repository/A914BC7A0000/0/AS148810.asa
./data/rpki.sub.apnic.net/repository/A914BC7A0000/0/AS148804.asa
./data/rpki.sub.apnic.net/repository/A914BC7A0000/0/AS148805.asa
./data/rpki.sub.apnic.net/repository/A914BC7A0000/0/AS148807.asa
./data/rpki.sub.apnic.net/repository/A914BC7A0000/0/AS148806.asa
./data/rpki.sub.apnic.net/repository/A914BC7A0000/0/AS148802.asa
./data/rpki.sub.apnic.net/repository/A914BC7A0000/0/AS148803.asa
./data/rpki.sub.apnic.net/repository/A914BC7A0000/0/AS148801.asa
./data/rpki.sub.apnic.net/repository/A914BC7A0000/0/AS148800.asa
./data/rpki.cc/repo/MythicalKitten/9/AS60310.asa
./data/rpki.cc/repo/MythicalKitten/0/AS203635.asa
...
You can view the content of any one of the ASPA objects with monocle rpki read-aspa
subcommand. Here are a couple of examples:
➜ rpki-20230625T173535Z monocle rpki read-aspa ./data/rpki.cc/repo/MythicalKitten/9/AS60310.asa
| asn | afi_limit | allowed_upstream |
|-------|-----------|------------------|
| 60310 | none | 924 |
| | | 6939 |
| | | 48581 |
| | | 50224 |
| | | 52210 |
| | | 204857 |
➜ rpki-20230625T173535Z monocle rpki read-aspa ./data/rpki.co/repo/Mlgt/0/AS204508.asa
| asn | afi_limit | allowed_upstream |
|--------|-----------|------------------|
| 204508 | none | 6939 |
| | | 7721 |
| | | 29632 |
| | | 34872 |
| | | 34927 |
| | | 38230 |
| | | 41051 |
| | | 50058 |
| | | 60326 |
| | | 200105 |
| | | 208753 |
| | | 210633 |
| | | 211411 |
| | | 212271 |
| | | 212895 |
We (BGPKIT) are still experimenting with library support for ASPA for simpler measurements and research use cases. If you are interested, please feel free to contact me with your ideas or feature requests at data@bgpkit.com.