183 lines
8.6 KiB
Markdown
183 lines
8.6 KiB
Markdown
# Prepare all five RIR trust anchors
|
|
|
|
For every field, default, constraint and complete example, see the [TOML configuration reference](configuration.md)。
|
|
|
|
Panda RPKI requires a TAL for each configured anchor. The TAL supplies the
|
|
trusted public key and its certificate URI. You may pin a matching DER-encoded
|
|
TA certificate in TOML, or omit `ta` and let Panda fetch, validate and cache the
|
|
current certificate on each run. A certificate alone is not a substitute for an
|
|
independently obtained TAL. The repository includes a pinned OpenBSD snapshot of all five TALs and resource
|
|
constraints in [`tals/`](../tals/README.md); TA certificates are not bundled.
|
|
The all5 Compose examples use these policies by default. Copy the ten files
|
|
to your managed input directory, inspect their provenance, and follow the
|
|
[Docker instructions](docker.md#all-five-rirs).
|
|
|
|
## Automatic and fixed certificate modes
|
|
|
|
Automatic mode requires only an independently obtained TAL:
|
|
|
|
```toml
|
|
# Top-level setting, before any [[anchors]] table:
|
|
ta-refresh-policy = "allow-valid-cache"
|
|
|
|
[[anchors]]
|
|
id = "ripe"
|
|
tal = "input/ripe.tal"
|
|
# No ta field: refresh the TA certificate at each validate run / daemon cycle.
|
|
```
|
|
|
|
Add `ta = "input/ripe.cer"` inside that anchor to select fixed mode. Anchors can
|
|
mix modes. Fixed files are never replaced by the automatic cache. The TAL itself
|
|
is never automatically updated: operators maintain its URIs and trusted key.
|
|
All download candidates and cached fallback certificates must pass TA validation,
|
|
TAL key binding and validity checks. A valid-cache fallback yields partial;
|
|
`require-fresh` disallows it. Check-config does not test download reachability.
|
|
|
|
The download/pair-check sections below are optional for fixed mode. Automatic
|
|
mode follows the URIs actually present in the TAL; it does not invent HTTPS
|
|
alternatives for an rsync-only TAL.
|
|
|
|
## Official sources
|
|
|
|
Use the five ordinary production anchors below. Separate AS0 and test anchors
|
|
are not part of this all-five example. Review the applicable RIR terms before
|
|
using their services, including the [ARIN TAL page](https://www.arin.net/resources/manage/rpki/tal/)
|
|
and its linked [Relying Party Agreement](https://www.arin.net/resources/manage/rpki/rpa.pdf).
|
|
The project's BSD license does not replace those terms.
|
|
|
|
| RIR | Official TAL download | TA certificate location | Local files |
|
|
| --- | --- | --- | --- |
|
|
| AFRINIC | [afrinic.tal](https://rpki.afrinic.net/tal/afrinic.tal) | `https://rpki.afrinic.net/repository/AfriNIC.cer` | `afrinic.tal`, `afrinic.cer` |
|
|
| APNIC | [apnic.tal](https://tal.apnic.net/apnic.tal) | `rsync://rpki.apnic.net/repository/apnic-rpki-root-iana-origin.cer` | `apnic.tal`, `apnic.cer` |
|
|
| ARIN | [arin.tal](https://www.arin.net/resources/manage/rpki/arin.tal) | `https://rrdp.arin.net/arin-rpki-ta.cer` | `arin.tal`, `arin.cer` |
|
|
| LACNIC | [lacnic.tal (official file endpoint)](https://www.lacnic.net/innovaportal/file/4983/1/lacnic.tal) | `https://rrdp.lacnic.net/ta/rta-lacnic-rpki.cer` | `lacnic.tal`, `lacnic.cer` |
|
|
| RIPE NCC | [ripe-ncc.tal](https://tal.rpki.ripe.net/ripe-ncc.tal) | `https://rpki.ripe.net/ta/ripe-ncc-ta.cer` | `ripe.tal`, `ripe.cer` |
|
|
|
|
Further official references: [APNIC TAL archive](https://www.apnic.net/community/security/resource-certification/tal-archive/),
|
|
[LACNIC trust anchors](https://www.lacnic.net/4984/2/lacnic/rpki-rpki-trust-anchor),
|
|
and [RIPE NCC trust-anchor structure](https://www.ripe.net/manage-ips-and-asns/resource-management/rpki/ripe-ncc-rpki-trust-anchor-structure/).
|
|
Locations can change: inspect the downloaded TAL before using a certificate URL
|
|
from this table. Do not rewrite TAL public keys or invent certificate URLs.
|
|
|
|
## Download the TAL files
|
|
|
|
Requirements: Bash, curl, OpenSSL, and rsync. On Debian/Ubuntu:
|
|
|
|
```bash
|
|
sudo apt-get install --no-install-recommends ca-certificates curl openssl rsync
|
|
```
|
|
|
|
Run from the project root, in a Bash shell. Use a fresh input directory when
|
|
updating an existing deployment; the commands below overwrite matching filenames.
|
|
|
|
```bash
|
|
set -euo pipefail
|
|
mkdir -p input
|
|
fetch_https() {
|
|
curl --fail --show-error --location \
|
|
--proto '=https' --proto-redir '=https' \
|
|
--connect-timeout 15 --max-time 120 --retry 2 --retry-max-time 300 \
|
|
"$1" --output "$2"
|
|
}
|
|
fetch_https https://rpki.afrinic.net/tal/afrinic.tal input/afrinic.tal
|
|
fetch_https https://tal.apnic.net/apnic.tal input/apnic.tal
|
|
fetch_https https://www.arin.net/resources/manage/rpki/arin.tal input/arin.tal
|
|
fetch_https https://www.lacnic.net/innovaportal/file/4983/1/lacnic.tal input/lacnic.tal
|
|
fetch_https https://tal.rpki.ripe.net/ripe-ncc.tal input/ripe.tal
|
|
```
|
|
|
|
An HTTP 200 response does not prove that a file is a TAL. During a documentation
|
|
check on 2026-09-09, LACNIC's short download URL
|
|
`https://www.lacnic.net/rpki/lacnic.tal` returned an HTML website instead;
|
|
the official file endpoint used above returned a TAL. If either download
|
|
stops working, open the official LACNIC trust-anchor page above and
|
|
save its **ordinary production TAL** text as `input/lacnic.tal`: URI lines,
|
|
one blank line, then the complete Base64 public key. Do not copy the separate
|
|
AS0 TAL, page markup, or a certificate-derived key. If the official TAL text is
|
|
unavailable, stop and obtain it from LACNIC; do not substitute an arbitrary mirror.
|
|
|
|
Check all five TALs before downloading certificates:
|
|
|
|
```bash
|
|
for rir in afrinic apnic arin lacnic ripe; do
|
|
tal="input/$rir.tal"
|
|
if grep -Eiq '<!doctype|<html' "$tal"; then
|
|
echo "HTML received instead of a TAL: $tal" >&2
|
|
exit 1
|
|
fi
|
|
grep -E '^(https|rsync)://' "$tal"
|
|
awk '
|
|
{ sub(/\r$/, "") }
|
|
/^#/ { next }
|
|
/^(https|rsync):\/\// { uri=1; next }
|
|
/^[[:space:]]*$/ { if (uri) key=1; next }
|
|
key { printf "%s", $0 }
|
|
' "$tal" | tr -d '[:space:]' | openssl base64 -d -A \
|
|
| openssl pkey -pubin -inform DER -noout
|
|
done
|
|
```
|
|
|
|
## Optional: download certificates for fixed mode
|
|
|
|
After checking that the URI lines match the table, run in the same Bash shell
|
|
(which defines `fetch_https`):
|
|
|
|
```bash
|
|
fetch_https https://rpki.afrinic.net/repository/AfriNIC.cer input/afrinic.cer
|
|
timeout 120 rsync --timeout=60 --contimeout=15 \
|
|
rsync://rpki.apnic.net/repository/apnic-rpki-root-iana-origin.cer input/apnic.cer
|
|
fetch_https https://rrdp.arin.net/arin-rpki-ta.cer input/arin.cer
|
|
fetch_https https://rrdp.lacnic.net/ta/rta-lacnic-rpki.cer input/lacnic.cer
|
|
fetch_https https://rpki.ripe.net/ta/ripe-ncc-ta.cer input/ripe.cer
|
|
```
|
|
|
|
APNIC's TAL currently lists only rsync, which requires outbound TCP port 873
|
|
for this bootstrap step. This does not change Panda RPKI's HTTPS RRDP sync
|
|
mode. APNIC also serves the certificate at the following HTTPS endpoint,
|
|
which can be used when port 873 is blocked; this is an alternative download
|
|
endpoint, not an HTTPS URI present in the current APNIC TAL:
|
|
|
|
```bash
|
|
fetch_https https://rpki.apnic.net/repository/apnic-rpki-root-iana-origin.cer input/apnic.cer
|
|
```
|
|
|
|
Always verify the downloaded certificate against the independently obtained
|
|
TAL, including when using this alternative endpoint.
|
|
|
|
## Optional: check fixed TAL/TA pairs
|
|
|
|
The following checks DER parsing, expiration, and equality of the certificate's
|
|
SubjectPublicKeyInfo with the TAL key. They are input sanity checks, not a full
|
|
RPKI profile or chain validation; Panda RPKI performs its validation during a run.
|
|
|
|
```bash
|
|
for rir in afrinic apnic arin lacnic ripe; do
|
|
openssl x509 -inform DER -in "input/$rir.cer" -noout -subject -dates
|
|
openssl x509 -inform DER -in "input/$rir.cer" -noout -checkend 0
|
|
tal_key=$(awk '
|
|
{ sub(/\r$/, "") }
|
|
/^#/ { next }
|
|
/^(https|rsync):\/\// { uri=1; next }
|
|
/^[[:space:]]*$/ { if (uri) key=1; next }
|
|
key { printf "%s", $0 }
|
|
' "input/$rir.tal" | tr -d '[:space:]')
|
|
cert_key=$(openssl x509 -inform DER -in "input/$rir.cer" -pubkey -noout \
|
|
| openssl pkey -pubin -outform DER | openssl base64 -A)
|
|
test -n "$tal_key" && test "$tal_key" = "$cert_key"
|
|
echo "$rir: TAL/TA public keys match"
|
|
done
|
|
```
|
|
|
|
You now have five TALs and, if using fixed mode, five matching certificates in
|
|
`input/`. Put those paths in the named `[[anchors]]` tables shown in the
|
|
[usage example](usage.md#multiple-anchors-and-constraints). To use automatic
|
|
refresh, omit the corresponding `ta` line; the first run requires outbound
|
|
HTTPS/rsync access and later runs may use the valid keyed cache when policy is
|
|
`allow-valid-cache`.
|
|
|
|
Keep inputs out of version control. Monitor TAL changes and RIR announcements.
|
|
Panda RPKI never rewrites supplied TA files; automatic mode refreshes a separate
|
|
cache. Stage and check updated pairs before replacing active inputs between runs.
|
|
Never resolve a key mismatch by replacing the TAL key with the downloaded
|
|
certificate's key: retrieve the current TAL from the RIR and investigate first.
|