panda-rpki-oss/docs/trust-anchors.md
Panda RPKI OSS Local 277cbca878
Some checks failed
ci / rust (push) Has been cancelled
ci / docker (push) Has been cancelled
初始化 Panda RPKI v0.1.0 开源候选版本
2026-09-09 18:01:15 +08:00

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.