RPKI RTR Server
这是一个用 Rust 实现的 RPKI-to-Router (RTR) cache server。服务端从 CCR 文件中读取 RPKI 数据,生成 RTR cache snapshot 和 delta,并通过 RTR 协议提供给路由器或调试客户端。
当前代码重点覆盖:
- RTR server:TCP 默认启用,可选启用 TLS/mTLS 和进程内 SSH transport。
- 数据输入:从 CCR 目录选择最新
.ccr文件,解析 VRP 和 VAP/ASPA。 - 本地策略:可选加载 SLURM 文件,对 CCR 解析出的 payload 做过滤和本地断言。
- 持久化:使用 RocksDB 保存 RTR cache 状态。
- 运行报告:输出 source、client、runtime 三类 JSON report。
- 运行期管理:可选启用 HTTP Admin API,修改部分 runtime config、触发 source reload、管理 SLURM 文件。
- 调试工具:
rtr_debug_client支持 TCP、TLS 和 SSH 连接 RTR server。
目录
协议参考
- RTR: RFC 6810, RFC 8210
- SLURM: RFC 8416
- CCR: draft-ietf-sidrops-rpki-ccr
项目结构
| 路径 | 说明 |
|---|---|
src/main_rtr.rs |
RTR server 入口 |
src/rtr/ |
RTR 协议、cache、store、server transport、admin、report |
src/source/ |
CCR/SLURM source 加载流程 |
src/slurm/ |
SLURM 文件解析、合并和策略应用 |
src/data_model/ |
RPKI 相关数据结构 |
src/bin/rtr_debug_client/ |
RTR 调试客户端 |
deploy/server/ |
server Docker 镜像和 compose |
deploy/client/ |
debug client Docker 镜像和 compose |
deploy/frr/, deploy/bird/ |
FRR/BIRD 作为 RTR client 的测试部署 |
tests/ |
单元和集成测试 |
构建与测试
cargo build --bin rpki_rtr
cargo build --bin rtr_debug_client
cargo test
服务端 binary 名称是 rpki_rtr:
cargo run --bin rpki_rtr
默认配置会监听 0.0.0.0:323,从 ./data 查找 CCR 文件,并使用 ./rtr-db 保存 RocksDB 数据。启动前需要确保 CCR 目录里存在可解析的 .ccr 文件。
数据输入
服务端启动和刷新时会读取 RPKI_RTR_CCR_DIR 指向的目录:
- 如果该目录下存在包含
.ccr文件的子目录,先按子目录名排序选择最新子目录。 - 在选中的目录中按文件名排序选择最新
.ccr文件。 - 从 CCR 中解析 VRP 和 VAP/ASPA。
- 如果配置了
RPKI_RTR_SLURM_DIR,加载其中启用的*.slurm文件并应用本地策略。
快速启动
Docker 运行
推荐使用 deploy/server/build-run.sh 和 deploy/client/build-run.sh 分别管理 server 与 debug client:
以下命令默认从仓库根目录执行。
chmod +x deploy/server/build-run.sh deploy/client/build-run.sh
./deploy/server/build-run.sh up --mode tcp
./deploy/client/build-run.sh up --mode tcp
./deploy/client/build-run.sh down
./deploy/server/build-run.sh down
脚本常用参数:
| 参数/变量 | server | client | 说明 |
|---|---|---|---|
| `--mode base | tcp | tls | ssh, MODE` |
| `--clients single | multi, CLIENTS` |
no | yes |
--no-build, BUILD=0 |
yes | yes | 只运行已有镜像,不执行 compose build。 |
--server-image TAG, SERVER_IMAGE |
yes | no | server 镜像名;会传给 compose 的 RPKI_RTR_SERVER_IMAGE。 |
--client-image TAG, CLIENT_IMAGE |
no | yes | client 镜像名;会传给 compose 的 RPKI_RTR_CLIENT_IMAGE。 |
--platform VALUE, TARGET_PLATFORM |
yes | yes | buildx 目标平台,默认 linux/arm64。 |
--push, BUILDX_PUSH=1 |
yes | yes | buildx 构建后推送到 registry;不设置时加载到本地 Docker。 |
--skip-base-pull, SKIP_BASE_IMAGE_PULL=1 |
yes | yes | 跳过 buildx 前的基础镜像预拉取。 |
支持的 action 包括 up、build、buildx、rebuild、down/stop、restart、logs、ps。完整帮助见:
./deploy/server/build-run.sh --help
./deploy/client/build-run.sh --help
跨架构构建
示例:x86 开发机本地构建 ARM 镜像,打包后传到 ARM 部署机。
./deploy/server/build-run.sh buildx \
--platform linux/arm64 \
--server-image rpki-rtr:arm64
./deploy/client/build-run.sh buildx \
--platform linux/arm64 \
--client-image rpki-rtr-debug-client:arm64
mkdir -p dist/images
docker save rpki-rtr:arm64 -o dist/images/rpki-rtr-arm64.tar
docker save rpki-rtr-debug-client:arm64 -o dist/images/rpki-rtr-debug-client-arm64.tar
scp dist/images/*.tar user@arm-host:/tmp/
ARM 部署机加载镜像并运行:
docker load -i /tmp/rpki-rtr-arm64.tar
docker load -i /tmp/rpki-rtr-debug-client-arm64.tar
SERVER_IMAGE=rpki-rtr:arm64 \
BUILD=0 ./deploy/server/build-run.sh up --mode tcp
CLIENT_IMAGE=rpki-rtr-debug-client:arm64 \
BUILD=0 ./deploy/client/build-run.sh up --mode tcp
docker compose -f deploy/server/docker-compose.yml up -d --build
docker compose -f deploy/server/docker-compose.yml down
TLS/mTLS 示例:
docker compose -f deploy/server/docker-compose.tls.yml up -d --build
docker compose -f deploy/server/docker-compose.tls.yml down
传输模式
TCP 默认启用。TLS 和 SSH 是附加监听,不会替代 TCP。
| 模式 | 默认地址 | 启用方式 |
|---|---|---|
| TCP | 0.0.0.0:323 |
默认启用 |
| TLS/mTLS | 0.0.0.0:324 |
RPKI_RTR_ENABLE_TLS=true |
| SSH | 0.0.0.0:22 |
RPKI_RTR_ENABLE_SSH=true |
TLS server 会加载服务端证书、私钥和 client CA。SSH server 使用 OpenSSH host key 和 authorized_keys 文件;RPKI_RTR_SSH_AUTH_MODE 支持 key、password、both。
主要环境变量
布尔值支持 true/false、1/0、yes/no、on/off。
| 变量 | 默认值 | 说明 |
|---|---|---|
RPKI_RTR_ENABLE_TLS |
false |
是否启用 TLS/mTLS 监听 |
RPKI_RTR_ENABLE_SSH |
false |
是否启用 SSH 监听 |
RPKI_RTR_TCP_ADDR |
0.0.0.0:323 |
TCP 监听地址 |
RPKI_RTR_TLS_ADDR |
0.0.0.0:324 |
TLS 监听地址 |
RPKI_RTR_SSH_ADDR |
0.0.0.0:22 |
SSH 监听地址 |
RPKI_RTR_SSH_PORT |
未设置 | 仅覆盖 RPKI_RTR_SSH_ADDR 中的端口 |
RPKI_RTR_DB_PATH |
./rtr-db |
RocksDB 路径 |
RPKI_RTR_CCR_DIR |
./data |
CCR 输入目录 |
RPKI_RTR_SLURM_DIR |
未设置 | SLURM 目录;空值表示禁用 |
RPKI_RTR_REPORT_DIR |
./report |
JSON report 输出目录 |
RPKI_RTR_MAX_DELTA |
100 |
每个 RTR 版本保留的最大 delta 数,必须大于 0 |
RPKI_RTR_PRUNE_DELTA_BY_SNAPSHOT_SIZE |
false |
是否按 snapshot wire size 继续裁剪 delta window |
RPKI_RTR_SOURCE_REFRESH_INTERVAL_SECS |
300 |
source 刷新间隔,单位秒 |
RPKI_RTR_REFRESH_INTERVAL_SECS |
未设置 | 旧变量名,仍兼容;建议使用 RPKI_RTR_SOURCE_REFRESH_INTERVAL_SECS |
RPKI_RTR_TIMING_REFRESH_SECS |
3600 |
RTR EndOfData refresh 字段 |
RPKI_RTR_TIMING_RETRY_SECS |
600 |
RTR EndOfData retry 字段 |
RPKI_RTR_TIMING_EXPIRE_SECS |
7200 |
RTR EndOfData expire 字段,必须大于 refresh 和 retry |
RPKI_RTR_MAX_CONNECTIONS |
512 |
最大并发 RTR 连接数 |
RPKI_RTR_MAX_CONCURRENT_HANDSHAKES |
128 |
最大并发握手数,不能大于最大连接数 |
RPKI_RTR_NOTIFY_QUEUE_SIZE |
1024 |
Serial Notify 广播队列大小 |
RPKI_RTR_TCP_KEEPALIVE_SECS |
60 |
TCP keepalive;设为 0 表示禁用 |
RPKI_RTR_WARN_INSECURE_TCP |
true |
TCP 模式是否输出安全提示 |
RPKI_RTR_REQUIRE_TLS_SERVER_DNS_NAME_SAN |
false |
是否要求 TLS 服务端证书包含 dNSName SAN |
RPKI_RTR_ENFORCE_TLS_CLIENT_SAN_IP_MATCH |
true |
是否校验 TLS client 证书 SAN IP 与 peer IP 匹配 |
RPKI_RTR_RUNTIME_REPORT_INTERVAL_SECS |
300 |
runtime report 周期 |
RPKI_RTR_REPORT_HISTORY_LIMIT |
10 |
每类 report 滚动保留数量 |
RPKI_RTR_TIMEZONE |
Asia/Shanghai |
日志和 report 使用的时区 |
RPKI_RTR_ADMIN_ADDR |
未设置 | Admin API 监听地址;未设置时关闭 |
RPKI_RTR_ADMIN_TOKEN |
未设置 | Admin API Bearer token;非 loopback 监听时必须设置 |
TLS 相关路径:
| 变量 | 默认值 |
|---|---|
RPKI_RTR_TLS_CERT_PATH |
./certs/tls/server-dns.crt |
RPKI_RTR_TLS_KEY_PATH |
./certs/tls/server-dns.key |
RPKI_RTR_TLS_CLIENT_CA_PATH |
./certs/tls/client-ca.crt |
SSH 相关配置:
| 变量 | 默认值 |
|---|---|
RPKI_RTR_SSH_HOST_KEY_PATH |
./certs/ssh/ssh_host_rsa_key |
RPKI_RTR_SSH_AUTHORIZED_KEYS_PATH |
./certs/ssh/rtr-authorized_keys |
RPKI_RTR_SSH_USERNAME |
rpki-rtr |
RPKI_RTR_SSH_SUBSYSTEM_NAME |
rpki-rtr |
RPKI_RTR_SSH_AUTH_MODE |
key |
RPKI_RTR_SSH_PASSWORD |
未设置 |
运行报告
服务会在 RPKI_RTR_REPORT_DIR 下写入 JSON report,并按 RPKI_RTR_REPORT_HISTORY_LIMIT 滚动保留:
rtr-source-*.json:CCR/SLURM source、fingerprint、刷新状态、数据质量、cache 统计。rtr-clients-*.json:client 连接数和连接方式统计。rtr-runtime-*.json:进程状态、服务状态和当前生效的 runtime config。
Admin API
Admin API 默认关闭。设置 RPKI_RTR_ADMIN_ADDR 后启用:
export RPKI_RTR_ADMIN_ADDR=127.0.0.1:8323
export RPKI_RTR_ADMIN_TOKEN=change-me
如果监听非 loopback 地址,例如 0.0.0.0:8323,必须设置 RPKI_RTR_ADMIN_TOKEN。设置 token 后,请求需要携带:
Authorization: Bearer change-me
当前实现的主要接口:
| 方法 | 路径 | 说明 |
|---|---|---|
GET |
/admin/rtr/health |
健康检查和能力开关 |
GET |
/admin/rtr/config |
查看 runtime config |
POST |
/admin/rtr/config |
修改部分 runtime config |
GET |
/admin/rtr/logs/tail |
读取 stdout/stderr 日志 tail |
POST |
/admin/rtr/slurm/reload |
触发 source reload |
GET |
/admin/rtr/slurm/files |
列出 SLURM 文件 |
POST |
/admin/rtr/slurm/files |
新增或覆盖 SLURM 文件 |
GET |
/admin/rtr/slurm/files/{name} |
读取 SLURM 文件 |
PUT |
/admin/rtr/slurm/files/{name} |
新增或覆盖指定 SLURM 文件 |
DELETE |
/admin/rtr/slurm/files/{name} |
删除 SLURM 文件 |
POST |
/admin/rtr/slurm/files/{name}/enable |
启用 .slurm.disabled 文件 |
POST |
/admin/rtr/slurm/files/{name}/disable |
禁用 .slurm 文件 |
示例:
curl http://127.0.0.1:8323/admin/rtr/config \
-H "Authorization: Bearer change-me"
curl -X POST http://127.0.0.1:8323/admin/rtr/config \
-H "Content-Type: application/json" \
-H "Authorization: Bearer change-me" \
-d '{"max_delta": 6, "source_refresh_interval_seconds": 60}'
调试客户端
rtr_debug_client 用于手动发起 Reset Query 或 Serial Query,并观察服务端返回的 PDU。
RTR Client 的 Docker 调试、FRR/BIRD 互通验证和常用排障步骤见 README.client.md。
TCP:
cargo run --bin rtr_debug_client -- 127.0.0.1:323 1 reset
cargo run --bin rtr_debug_client -- 127.0.0.1:323 1 serial 42 100
TLS:
cargo run --bin rtr_debug_client -- \
127.0.0.1:324 1 reset \
--tls \
--ca-cert certs/tls/client-ca.crt \
--server-name localhost \
--client-cert certs/tls/client-good.crt \
--client-key certs/tls/client-good.key
SSH:
cargo run --bin rtr_debug_client -- \
127.0.0.1:22 1 reset \
--ssh \
--ssh-user rpki-rtr \
--ssh-key certs/ssh/rtr-client.key \
--ssh-server-key certs/ssh/ssh_host_rsa_key.pub
SSH password auth 也已实现;SSH 模式下 --ssh-key 和 --ssh-password 二选一,同时必须通过 --ssh-known-hosts 或 --ssh-server-key 做 host key 校验。
更多参数见 src/bin/rtr_debug_client/README.md。
部署入口
| 用途 | Compose 文件 |
|---|---|
| Server | deploy/server/docker-compose.yml |
| Server TCP 示例 | deploy/server/docker-compose.tcp.yml |
| Server TLS 示例 | deploy/server/docker-compose.tls.yml |
| Server SSH 示例 | deploy/server/docker-compose.ssh.yml |
| Debug client | deploy/client/docker-compose.yml |
| Debug client 多实例 | deploy/client/docker-compose.clients.yml |
| FRR client | deploy/frr/docker-compose.yml |
| BIRD client | deploy/bird/docker-compose.yml |
RTR Client 统一使用说明见 README.client.md。
通用操作:
COMPOSE_FILE=deploy/server/docker-compose.yml
docker compose -f "${COMPOSE_FILE}" up -d --build
docker compose -f "${COMPOSE_FILE}" ps
docker compose -f "${COMPOSE_FILE}" down
开发说明
- 代码中的 RTR cache 按协议版本维护状态;v0 只包含 Route Origin,v1 包含 Route Origin 和 Router Key,v2 包含 Route Origin、Router Key 和 ASPA。
- 当前 source pipeline 从 CCR 生成 Route Origin 和 ASPA,再可选应用 SLURM。
RtrStore::save_cache_state_versioned(...)是 cache 状态写入 RocksDB 的核心入口,相关边界测试在tests/test_store_boundary.rs。- Admin API 的日志 tail 依赖部署入口写出的 stdout/stderr 日志文件;容器入口脚本会把日志写到
/app/logs。