149 lines
7.0 KiB
Markdown
149 lines
7.0 KiB
Markdown
# Prepare all five RIR trust anchors
|
|
|
|
Panda RPKI requires a TAL and a matching DER-encoded TA certificate for each
|
|
anchor. The TAL supplies the trusted public key; the certificate supplies the
|
|
current trust-anchor certificate. A certificate alone is not a substitute for
|
|
an independently obtained TAL. No RIR inputs are bundled with this project.
|
|
|
|
## 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
|
|
```
|
|
|
|
## Download the TA certificates
|
|
|
|
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.
|
|
|
|
## Check the pairs and run
|
|
|
|
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 ten files in `input/`, named exactly as expected by the
|
|
[all-five Compose example](docker.md#all-five-regional-anchors). For the
|
|
single-anchor README example only, copy a chosen pair to `input/anchor.tal`
|
|
and `input/anchor.cer`, or change the CLI arguments to use its RIR filenames.
|
|
|
|
Keep inputs out of version control. Monitor certificate validity and RIR
|
|
announcements; Panda RPKI does not refresh supplied TA files automatically.
|
|
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.
|