Download raw body.
rpki-client: detect & reject "AS0 TALs"
Some well-meaning folks in the RIR policy development community paved
the road to hell with RPKI ROAs. Despite appeals & protests, APNIC &
LACNIC were forced to offer an extra TAL, called an 'AS0 TAL'. AFRINIC
is in the process of making one.
The idea of AS0 TALs that the RIR issues a ROA for all unassigned and
unallocated IP space with the asID set to 0. This way ISPs can more
easily filter out bogon BGP announcements. Sounds nice & simple? Wrong!
Unfortunately, such AS0 TALs represent unmitigated operational risks:
what if the RIR by accident marks some IP space as 'unassigned'? What if
the RIR attempts to use this mechanism to force payment disputes? What
if there is a bug in the pipeline somewhere? These AS0 TALs are like
Chekhov's gun.
RIR mistakes *have* happened in the past, for example: RIPE NCC briefly
mistakenly changed the contractual status for a number of resources,
resulting in deletion of legitimate ROAs. If RIPE NCC also had operated
an AS0 TAL, those resources likely would've appeared on the AS0 ROA.
https://www.ripe.net/ripe/mail/archives/routing-wg/2020-December/004210.html
In the above situation, without an AS0 TAL, the affected routes just
temporarily flipped from 'valid' to 'not-found', which is safe. What AS0
TALs introduce is a risk that routes flip from 'valid' to 'invalid' and
end up getting rejected in large parts of the global Internet routing
system.
Of note is that APNIC has plastered a big fat warning over their AS0 TAL:
https://www.apnic.net/community/security/resource-certification/apnic-limitations-of-liability-for-rpki-2/
"""
Depending on router configuration, errors in the AS0 ROA could
cause unintended interruption to routing with other networks.
For this reason, it is strongly recommended that the AS0 ROA is
used for advisory and/ or alerting purposes only, and not for
automatic filtering of BGP routes.
"""
Following the above advice, the below diff makes it so that, by default,
rpki-client will omit AS0 TAL information from its validated ROA payload
outputs. Operators who believe they truly need AS0 TAL output will have
to use the '-x' (experimental) option.
OK?
Kind regards,
Job
Index: output.c
===================================================================
RCS file: /cvs/src/usr.sbin/rpki-client/output.c,v
diff -u -p -r1.33 output.c
--- output.c 22 Feb 2024 12:49:42 -0000 1.33
+++ output.c 29 Nov 2024 14:57:07 -0000
@@ -82,6 +82,46 @@ static int output_finish(FILE *);
static void sig_handler(int);
static void set_signal_handler(void);
+/*
+ * Detect & reject so-called "AS0 TALs".
+ * AS0 TALs are TALs where for each and every subordinate ROA the asID field
+ * set to 0. Such TALs introduce operational risk, as they change the fail-safe
+ * from 'fail-open' to 'fail-closed'. Some context:
+ * https://lists.afrinic.net/pipermail/rpd/2021/013312.html
+ * https://lists.afrinic.net/pipermail/rpd/2021/013314.html
+ */
+static void
+prune_as0_tals(struct vrp_tree *vrps)
+{
+ struct vrp *v, *tv;
+ int talid;
+ int is_as0_tal[TALSZ_MAX] = { 0 };
+
+ for (talid = 0; talid < talsz; talid++)
+ is_as0_tal[talid] = 1;
+
+ RB_FOREACH(v, vrp_tree, vrps) {
+ if (v->asid != 0)
+ is_as0_tal[v->talid] = 0;
+ }
+
+ for (talid = 0; talid < talsz; talid++) {
+ if (is_as0_tal[talid]) {
+ warnx("%s: Detected AS0 TAL, pruning associated VRPs",
+ taldescs[talid]);
+ }
+ }
+
+ RB_FOREACH_SAFE(v, vrp_tree, vrps, tv) {
+ if (is_as0_tal[v->talid]) {
+ RB_REMOVE(vrp_tree, vrps, v);
+ free(v);
+ }
+ }
+
+ /* XXX: update talstats? */
+}
+
int
outputfiles(struct vrp_tree *v, struct brk_tree *b, struct vap_tree *a,
struct vsp_tree *p, struct stats *st)
@@ -90,6 +130,12 @@ outputfiles(struct vrp_tree *v, struct b
atexit(output_cleantmp);
set_signal_handler();
+
+ /*
+ * By default prune AS0 TALs
+ */
+ if (!experimental)
+ prune_as0_tals(v);
for (i = 0; outputs[i].name; i++) {
FILE *fout;
rpki-client: detect & reject "AS0 TALs"