369 lines
13 KiB
Markdown
369 lines
13 KiB
Markdown
# RPKI RTR Server
|
||
|
||
默认运行平台:Ubuntu/Linux。
|
||
|
||
## 目录
|
||
|
||
- [协议与规范](#协议与规范)
|
||
- [RTR](#rtr)
|
||
- [SLURM](#slurm)
|
||
- [CCR](#ccr)
|
||
- [RTR Server](#rtr-server)
|
||
- [环境变量](#环境变量)
|
||
- [说明](#说明)
|
||
- [快速启动](#快速启动)
|
||
- [Docker 启动](#docker-启动)
|
||
- [本地运行(推荐先用脚本)](#本地运行推荐先用脚本)
|
||
- [本地手动运行(最小示例)](#本地手动运行最小示例)
|
||
- [CCR 输入说明](#ccr-输入说明)
|
||
- [Client 使用](#client-使用)
|
||
- [作用与选择](#作用与选择)
|
||
- [rtr_debug_client(本地)](#rtr_debug_client本地)
|
||
- [rtr_debug_client(Docker)](#rtr_debug_clientdocker)
|
||
- [rpki-rs-test-client(Docker)](#rpki-rs-test-clientdocker)
|
||
- [FRR(Docker,黑盒客户端)](#frrdocker黑盒客户端)
|
||
- [RTR Debug Client](#rtr-debug-client)
|
||
- [Client 启动示例](#client-启动示例)
|
||
- [存储模型与边界约束(多视图)](#存储模型与边界约束多视图)
|
||
- [唯一写入口](#唯一写入口)
|
||
- [恢复约束](#恢复约束)
|
||
- [边界防回归测试](#边界防回归测试)
|
||
- [Deploy Layout](#deploy-layout)
|
||
- [Quick Start](#quick-start)
|
||
- [Compose 入口](#compose-入口)
|
||
- [角色附加命令](#角色附加命令)
|
||
|
||
## 协议与规范
|
||
|
||
### RTR
|
||
|
||
- [RFC 6810: The Resource Public Key Infrastructure (RPKI) to Router Protocol](https://www.rfc-editor.org/rfc/rfc6810.html)
|
||
- [RFC 8210: The Resource Public Key Infrastructure (RPKI) to Router Protocol, Version 1](https://www.rfc-editor.org/rfc/rfc8210.html)
|
||
- [Draft: The Resource Public Key Infrastructure (RPKI) to Router Protocol, Version 2](https://www.ietf.org/archive/id/draft-ietf-sidrops-8210bis-25.html)
|
||
|
||
### SLURM
|
||
|
||
- [RFC 8416: Simplified Local Internet Number Resource Management with the RPKI (SLURM)](https://www.rfc-editor.org/rfc/rfc8416.html)
|
||
- [Draft: ASPA extensions for SLURM](https://www.ietf.org/archive/id/draft-ietf-sidrops-aspa-slurm-04.html)
|
||
|
||
### CCR
|
||
|
||
- [Draft: A Concise Cryptographic Representation of RPKI Signed Objects (CCR)](https://www.ietf.org/archive/id/draft-ietf-sidrops-rpki-ccr-02.html)
|
||
|
||
## RTR Server
|
||
|
||
RTR Server 运行时从 `CCR` 目录中扫描最新的 `.ccr` 文件作为输入源:
|
||
|
||
- `VRP`
|
||
- `VAP (Validated ASPA Payload) / ASPA`
|
||
|
||
相关实现位置:
|
||
|
||
- [`src/main.rs`](src/main.rs)
|
||
- [`src/source/ccr.rs`](src/source/ccr.rs)
|
||
|
||
### 环境变量
|
||
|
||
| 变量名 | 说明 | 默认值 | 示例 |
|
||
| --- | --- | --- | --- |
|
||
| `RPKI_RTR_ENABLE_TLS` | 是否额外启用 TLS 监听。支持 `true/false`、`1/0`、`yes/no`、`on/off`。 | `false` | `true` |
|
||
| `RPKI_RTR_TCP_ADDR` | TCP 监听地址。 | `0.0.0.0:323` | `0.0.0.0:323` |
|
||
| `RPKI_RTR_TLS_ADDR` | TLS 监听地址。 | `0.0.0.0:324` | `0.0.0.0:324` |
|
||
| `RPKI_RTR_DB_PATH` | RocksDB 路径。 | `./rtr-db` | `./rtr-db` |
|
||
| `RPKI_RTR_CCR_DIR` | CCR 目录路径;程序会扫描其中最新的 `.ccr` 文件。 | `./data` | `./data` |
|
||
| `RPKI_RTR_SLURM_DIR` | SLURM 目录路径;为空或未设置表示禁用 SLURM。 | `未设置(禁用)` | `./slurm` |
|
||
| `RPKI_RTR_TLS_CERT_PATH` | TLS 服务端证书路径。 | `./certs/server.crt` | `./certs/server-dns.crt` |
|
||
| `RPKI_RTR_TLS_KEY_PATH` | TLS 服务端私钥路径。 | `./certs/server.key` | `./certs/server-dns.key` |
|
||
| `RPKI_RTR_TLS_CLIENT_CA_PATH` | 用于校验 router 客户端证书的 CA 证书路径。 | `./certs/client-ca.crt` | `./certs/client-ca.crt` |
|
||
| `RPKI_RTR_MAX_DELTA` | 最多保留多少条 delta。 | `100` | `100` |
|
||
| `RPKI_RTR_PRUNE_DELTA_BY_SNAPSHOT_SIZE` | 是否启用“累计 delta 估算 wire size 不小于 snapshot 时,继续裁剪最老 delta”的策略。 | `false` | `false` |
|
||
| `RPKI_RTR_STRICT_CCR_VALIDATION` | 是否对 CCR 中的非法 VRP / VAP 采用严格模式;`true` 表示整份 CCR 拒绝,`false` 表示跳过非法项并告警。 | `false` | `false` |
|
||
| `RPKI_RTR_REFRESH_INTERVAL_SECS` | 刷新 CCR 目录并重新加载最新 `.ccr` 的间隔,单位秒,必须 `>= 1`。 | `300` | `300` |
|
||
| `RPKI_RTR_MAX_CONNECTIONS` | 最大并发 RTR 客户端连接数。 | `512` | `512` |
|
||
| `RPKI_RTR_NOTIFY_QUEUE_SIZE` | Serial Notify 广播队列大小。 | `1024` | `1024` |
|
||
| `RPKI_RTR_TCP_KEEPALIVE_SECS` | TCP keepalive 时间,单位秒;设为 `0` 表示禁用。 | `60` | `60` |
|
||
| `RPKI_RTR_WARN_INSECURE_TCP` | 纯 TCP 模式下是否输出不安全警告。 | `true` | `true` |
|
||
| `RPKI_RTR_REQUIRE_TLS_SERVER_DNS_NAME_SAN` | 严格模式:TLS 服务端证书不包含 `subjectAltName dNSName` 时拒绝启动。 | `false` | `false` |
|
||
|
||
### 说明
|
||
|
||
- 纯 TCP 模式只应部署在受信任、可控网络中。
|
||
- TLS 模式要求客户端证书认证。
|
||
- 当前输入源是 `CCR` 目录,不再是单独的文本 VRP / ASPA / Router Key 文件。
|
||
- 刷新时会重新扫描 `RPKI_RTR_CCR_DIR`,并选取文件名排序最新的 `.ccr` 文件。
|
||
- `RPKI_RTR_STRICT_CCR_VALIDATION=false` 时,CCR 中的非法 VRP / VAP 会被跳过并输出 warning;`true` 时整份 CCR 更新失败。
|
||
- `RPKI_RTR_TCP_KEEPALIVE_SECS=0` 表示关闭 keepalive;非零值表示在整个连接生命周期内启用 keepalive。
|
||
- `RPKI_RTR_PRUNE_DELTA_BY_SNAPSHOT_SIZE=true` 时,除了 `RPKI_RTR_MAX_DELTA` 的固定条数裁剪外,还会在累计 delta 估算 wire size 不小于 snapshot 时继续删除最老 delta。
|
||
|
||
## 快速启动
|
||
|
||
### Docker 启动
|
||
|
||
```bash
|
||
docker compose -f deploy/server/docker-compose.yml up -d --build
|
||
docker compose -f deploy/server/docker-compose.yml logs -f rpki-rtr
|
||
docker compose -f deploy/server/docker-compose.yml down
|
||
```
|
||
|
||
### 本地运行(推荐先用脚本)
|
||
|
||
```sh
|
||
sh ./scripts/start-rtr-server-tcp.sh
|
||
sh ./scripts/start-rtr-server-tls.sh
|
||
```
|
||
|
||
脚本入口:
|
||
|
||
- [`scripts/start-rtr-server-tcp.sh`](scripts/start-rtr-server-tcp.sh)
|
||
- [`scripts/start-rtr-server-tls.sh`](scripts/start-rtr-server-tls.sh)
|
||
- [`scripts/start-rtr-server.sh`](scripts/start-rtr-server.sh)
|
||
|
||
### 本地手动运行(最小示例)
|
||
|
||
纯 TCP:
|
||
|
||
```sh
|
||
export RPKI_RTR_ENABLE_TLS=false
|
||
export RPKI_RTR_CCR_DIR=./data
|
||
cargo run --bin rpki
|
||
```
|
||
|
||
TLS / mutual TLS:
|
||
|
||
```sh
|
||
export RPKI_RTR_ENABLE_TLS=true
|
||
export RPKI_RTR_CCR_DIR=./data
|
||
export RPKI_RTR_TLS_CERT_PATH=./certs/server-dns.crt
|
||
export RPKI_RTR_TLS_KEY_PATH=./certs/server-dns.key
|
||
export RPKI_RTR_TLS_CLIENT_CA_PATH=./certs/client-ca.crt
|
||
cargo run --bin rpki
|
||
```
|
||
|
||
## CCR 输入说明
|
||
|
||
当前会从 `RPKI_RTR_CCR_DIR` 指向的目录中扫描最新 `.ccr` 文件,并从中提取:
|
||
|
||
- `VRP`
|
||
- `VAP (Validated ASPA Payload) / ASPA`
|
||
|
||
测试样例可参考:
|
||
|
||
- [`data/20260324T000037Z-sng1.ccr`](data/20260324T000037Z-sng1.ccr)
|
||
|
||
## Client 使用
|
||
|
||
客户端的作用是从不同角度验证 RTR 服务端行为,覆盖“协议调试、自动化测试、黑盒互通”三类需求。
|
||
|
||
### 作用与选择
|
||
|
||
| Client | 主要作用 | 适用场景 |
|
||
| --- | --- | --- |
|
||
| `rtr_debug_client` | 面向协议交互调试,便于手动发起 `reset/serial` 并观察响应 | 开发联调、定位会话/报文问题、快速复现 |
|
||
| `rpki-rs-test-client` | 基于 `rpki-rs` 客户端 API 做自动化验证 | CI/CD、回归测试、批量步骤校验 |
|
||
| `FRR` | 真实路由软件黑盒接入,验证与生产侧客户端互通 | 互操作验证、运维演练、端到端验证 |
|
||
|
||
建议使用顺序:
|
||
|
||
1. 先用 `rtr_debug_client` 快速确认服务可连通、协议版本和基础响应正常。
|
||
2. 再用 `rpki-rs-test-client` 做可重复的自动化步骤校验。
|
||
3. 最后用 `FRR` 做黑盒互通验证,确认真实客户端接入行为。
|
||
|
||
### rtr_debug_client(本地)
|
||
|
||
```sh
|
||
cargo run --bin rtr_debug_client -- 127.0.0.1:323 1 reset
|
||
```
|
||
|
||
说明:
|
||
- 适合手工排查:你可以快速切换 TCP/TLS、版本号、请求类型来观察响应差异。
|
||
- 适合问题定位:当服务端日志出现异常时,可用最小参数复现问题流量。
|
||
|
||
### rtr_debug_client(Docker)
|
||
|
||
```bash
|
||
docker compose -f deploy/client/docker-compose.yml up --build
|
||
docker compose -f deploy/client/docker-compose.yml logs -f rtr-debug-client
|
||
docker compose -f deploy/client/docker-compose.yml down
|
||
```
|
||
|
||
多实例压测/联调:
|
||
|
||
```bash
|
||
docker compose -f deploy/client/docker-compose.clients.yml up -d
|
||
docker compose -f deploy/client/docker-compose.clients.yml logs -f
|
||
docker compose -f deploy/client/docker-compose.clients.yml down
|
||
```
|
||
|
||
### rpki-rs-test-client(Docker)
|
||
|
||
```bash
|
||
docker compose -f deploy/rpki-rs-client/docker-compose.yml up --build
|
||
docker compose -f deploy/rpki-rs-client/docker-compose.yml run --rm \
|
||
rpki-rs-test-client 127.0.0.1:323 2 reset --steps 1 --assert-min-records 1
|
||
docker compose -f deploy/rpki-rs-client/docker-compose.yml down
|
||
```
|
||
|
||
说明:
|
||
- 适合自动化场景:可作为流水线中的协议检查器。
|
||
- 适合回归校验:通过参数化步骤(`--steps`)和断言(如 `--assert-min-records`)稳定验证行为。
|
||
|
||
### FRR(Docker,黑盒客户端)
|
||
|
||
```bash
|
||
docker compose -f deploy/frr/docker-compose.yml up -d
|
||
docker exec -it frr-rpki-client vtysh -c "show rpki cache-connection"
|
||
docker exec -it frr-rpki-client vtysh -c "show rpki prefix-table"
|
||
docker compose -f deploy/frr/docker-compose.yml down
|
||
```
|
||
|
||
说明:
|
||
- 适合真实互通验证:FRR 更接近生产客户端行为。
|
||
- 适合观察业务结果:可直接查看缓存连接状态和前缀表结果。
|
||
|
||
## RTR Debug Client
|
||
|
||
调试用 RTR client 位于:
|
||
|
||
- [`src/bin/rtr_debug_client/main.rs`](src/bin/rtr_debug_client/main.rs)
|
||
|
||
说明文档位于:
|
||
|
||
- [`src/bin/rtr_debug_client/README.md`](src/bin/rtr_debug_client/README.md)
|
||
|
||
### Client 启动示例
|
||
|
||
连接纯 TCP RTR server:
|
||
|
||
```sh
|
||
cargo run --bin rtr_debug_client -- 127.0.0.1:323 1 reset
|
||
```
|
||
|
||
连接 TLS RTR server:
|
||
|
||
```sh
|
||
cargo run --bin rtr_debug_client -- \
|
||
127.0.0.1:324 1 reset \
|
||
--tls \
|
||
--ca-cert ./certs/client-ca.crt \
|
||
--server-name localhost \
|
||
--client-cert ./certs/client-good.crt \
|
||
--client-key ./certs/client-good.key
|
||
```
|
||
|
||
如果要在收到错误后继续自动轮询,可以加:
|
||
|
||
```sh
|
||
--keep-after-error
|
||
```
|
||
|
||
## 存储模型与边界约束(多视图)
|
||
|
||
当前 RTR cache 持久化采用三视图模型(按协议版本拆分):
|
||
|
||
- v0:仅 `RouteOrigin`
|
||
- v1:`RouteOrigin + RouterKey`
|
||
- v2:`RouteOrigin + RouterKey + Aspa`
|
||
|
||
RocksDB 中的核心状态按版本独立保存:
|
||
|
||
- `session_id_v0/v1/v2`
|
||
- `serial_v0/v1/v2`
|
||
- `current_v0/v1/v2`(snapshot)
|
||
- `delta_min_v0/v1/v2`、`delta_max_v0/v1/v2`
|
||
- delta key 采用 `D + version + serial_be`
|
||
|
||
### 唯一写入口
|
||
|
||
为保证 `session_id/serial/snapshot/delta_window` 的一致性,生产代码只允许通过:
|
||
|
||
- `RtrStore::save_cache_state_versioned(...)`
|
||
|
||
且该入口应仅由:
|
||
|
||
- `src/rtr/cache/store.rs`
|
||
|
||
发起调用(即由 cache 层统一批量原子写入)。
|
||
|
||
### 恢复约束
|
||
|
||
重启恢复时,按版本读取并校验:
|
||
|
||
- `availability`
|
||
- `snapshot_for_version(version)`
|
||
- `session_id_for_version(version)`
|
||
- `serial_for_version(version)`
|
||
- `delta_window_for_version(version)` 与 `load_delta_window_for_version(...)`
|
||
|
||
只有三视图状态完整且自洽时才走 store 恢复;否则回退到输入源加载流程。
|
||
|
||
### 边界防回归测试
|
||
|
||
新增边界测试用于限制写调用点,防止后续出现绕写路径:
|
||
|
||
- `tests/test_store_boundary.rs`
|
||
|
||
可单独执行:
|
||
|
||
```sh
|
||
cargo test --test test_store_boundary -- --nocapture
|
||
```
|
||
|
||
## Deploy Layout
|
||
|
||
`deploy/` 目录按角色拆分为四套部署与测试入口:
|
||
|
||
- `server/`: 本仓库 RTR Server(`src/main.rs`)容器化部署
|
||
- `client/`: 本仓库 `rtr_debug_client` 容器化部署
|
||
- `rpki-rs-client/`: 基于外部 `rpki-rs` client API 的测试客户端容器化部署
|
||
- `frr/`: FRR 作为黑盒 RTR Client 的配置与 compose
|
||
|
||
### Quick Start
|
||
|
||
最短路径(本地容器环境):
|
||
|
||
```bash
|
||
docker compose -f deploy/server/docker-compose.yml up -d --build
|
||
docker compose -f deploy/server/docker-compose.yml logs -f rpki-rtr
|
||
docker compose -f deploy/server/docker-compose.yml down
|
||
```
|
||
|
||
### Compose 入口
|
||
|
||
| 角色 | Compose 文件 |
|
||
| --- | --- |
|
||
| Server | `deploy/server/docker-compose.yml` |
|
||
| Debug Client(单实例) | `deploy/client/docker-compose.yml` |
|
||
| Debug Client(多实例) | `deploy/client/docker-compose.clients.yml` |
|
||
| rpki-rs Client | `deploy/rpki-rs-client/docker-compose.yml` |
|
||
| FRR Client | `deploy/frr/docker-compose.yml` |
|
||
|
||
通用操作模板:
|
||
|
||
```bash
|
||
docker compose -f <compose-file> up -d --build
|
||
docker compose -f <compose-file> logs -f
|
||
docker compose -f <compose-file> down
|
||
```
|
||
|
||
### 角色附加命令
|
||
|
||
rpki-rs Client(覆盖默认参数运行):
|
||
|
||
```bash
|
||
docker compose -f deploy/rpki-rs-client/docker-compose.yml run --rm \
|
||
rpki-rs-test-client 127.0.0.1:323 2 reset --steps 1 --assert-min-records 1
|
||
```
|
||
|
||
FRR Client(检查连接与前缀):
|
||
|
||
```bash
|
||
docker exec -it frr-rpki-client vtysh -c "show rpki cache-connection"
|
||
docker exec -it frr-rpki-client vtysh -c "show rpki prefix-table"
|
||
```
|
||
|
||
更多部署细节:
|
||
|
||
- `deploy/server/DEPLOYMENT.md`
|
||
- `deploy/frr/README.md`
|
||
- `deploy/frr/README.zh.md`
|