使用 Krill 部署 RPKI CA 和发布点

概述

由于测量研究需求,我们配置了一个 RPKI 节点,用于观测全球 RP 使用情况。Krill 是一个开源的工具,可以用于部署 RPKI CA 和发布点。以下内容参考 Krill 官方文档 进行梳理配置。

With Krill there are two fundamental pieces at play. The first part is the Certificate Authority (CA), which takes care of all the cryptographic operations involved in RPKI. Secondly, there is the publication server which makes your certificate and ROAs available to the world.

在几乎所有情况下,您都需要在父CA(通常是您的地区互联网注册中心(RIR)或国家互联网注册中心(NIR))下运行Krill提供的CA。
父CA和子CA之间的通信是通过交换两个XML文件来启动的,您需要手动处理这两个文件:子请求XML和父响应XML。这包括生成请求文件,将其提供给您的父级,并将响应文件返回给您的CA。

在完成此初始交换之后,所有后续请求和响应都由父CA和子CA本身处理。这包括确定您在证书上接收哪些资源的权利请求和响应、证书请求和响应以及吊销请求和响应。

配置流程

如果您可以使用父级提供的发布服务器,Krill的安装和配置就变得非常容易。安装完成后,您执行两次XML交换,就完成了。

Untitled

注意,APNIC, ARIN 和 Brazilian NIR NIC.br 会为其成员提供发布点服务器,但是 其它 RIR 仍未提供该功能。

如果您的父CA不提供发布即服务,那么您将需要运行自己的服务器。您可能希望运行自己的发布服务器的另一个原因是,它将允许您将CA的资源委托给您自己的子CA(例如业务部门),并允许您的子CA也在您的中央存储库中发布。

Untitled

安装

ubuntu 安装

1
2
3
4
5
6
7
8
9
10
11
12
sudo apt update
sudo apt install \
ca-certificates \
curl \
gnupg \
lsb-release
curl -fsSL https://packages.nlnetlabs.nl/aptkey.asc | sudo gpg --dearmor -o /usr/share/keyrings/nlnetlabs-archive-keyring.gpg
echo \
"deb [arch=$(dpkg --print-architecture) signed-by=/usr/share/keyrings/nlnetlabs-archive-keyring.gpg] https://packages.nlnetlabs.nl/linux/ubuntu \
$(lsb_release -cs) main" | sudo tee /etc/apt/sources.list.d/nlnetlabs.list > /dev/null
sudo apt update
sudo apt install krill

docker 安装(需要从Docker日志中获取令牌,以便通过API或krillc(CLI工具)管理Krill

1
2
3
4
5
6
7
8
9
10
$ docker run -d --name krill -p 127.0.0.1:3000:3000 \
-e KRILL_LOG_LEVEL=debug \
-e KRILL_FQDN=rpki.example.net \
-e KRILL_AUTH_TOKEN=correct-horse-battery-staple \
-e TZ=Europe/Amsterdam \
-v krill_data:/var/krill/data/ \
-v /tmp/krill_rsync/:/var/krill/data/repo/rsync/ \
nlnetlabs/krill
$ docker logs krill 2>&1 | fgrep token
docker-krill: Securing Krill daemon with token <SOME_TOKEN>

快速开始

在开始管理签发 ROA 前,需要完成以下设置:

  • create your CA
  • connect to Publication Server
  • connect to Parent CA (typically a Regional or National Internet Registry)

⭐ 模拟实验环境 Krill-RPKI 可以提供测试 TAL 和父证书

下载 testbed 的 TAL 文件,然后配置到 Relying Party 里

用 krill 在该锚点下配置自己的 CA 和发布点,RP 就可以访问到其签发\发布的 ROA

⭐Krill 可以通过 https://localhost:3000 提供的用户接口进行操作(注意这里的 HTTPS 使用的是自签名的 TLS 证书,浏览器会告警)

输入密钥 correct-horse-battery-staple (通过环境变量 KRILL_AUTH_TOKEN 设置的)

创建 CA (选择的句柄不会在RPKI中发布,而是用作与您交互的父CA和子CA的标识)

添加仓库(复制 publisher request 到 krill 仓库服务器,拿到响应的 XML 填入 Repository Response)

设置父 CA(复制 child request 到父 CA,拿到响应的 XML 填入 Parent Response)

⭐也可以通过 krillc 命令完成上述操作

krillc add 添加 CA

krillc repo request 请求仓库的响应XML

krillc repo configure 根据响应的XML完成仓库配置

krillc parents request 请求父CA的响应XML

krillc parents add 根据响应的XML完成父CA配置

签发 ROA

配置 Routinator 只访问 testbed 的信任锚点 TAL(提前把 testbed 的 TAL 文件下到对应目录下)

1
routinator --no-rir-tals --extra-tals-dir="/home/routinator/tals" -vv vrps > vrps.csv

签发 roa 之前,Routinator 的拉取结果为空

Untitled

krill 执行如下命令签发 roa, krillc roas update --add "10.0.0.1/16 => 666”

Untitled

签发之后,Routinator 再拉取就可以获取到签发的信息了

Untitled

需要注意的是,此时由于目标配置的是自签名证书,所以基于 RRDP 的请求失败,fall back 到 rsync 方式进行连接

检查 rsync 连接记录 cat /etc/log/rsync.log ,可以看到从 Routinator(172.17.0.5) 请求的连接,分别从 ta 和 repo 请求了数据

Untitled

如果配置了可信的 HTTPS 连接,则 RRDP 成功,不会回退到 rsync 请求,还可以从 nginx 代理的连接记录中观察到 HTTPS 请求。

Untitled

发布服务简单配置

以下说明了发布服务需要设置代理(nginx)、HTTPS证书(certbot)、和发布服务(krill)

Install a Proxy Server

1
2
3
apt install nginx
cd /etc/nginx/sites-enabled
rm default

created a configuration file /etc/nginx/sites-enabled/krill.example.org (proxy all traffic to our Krill server)

1
2
3
4
5
6
7
8
9
10
server {
server_name krill.example.org;
client_max_body_size 100M;

location / {
proxy_pass https://localhost:3000/;
}

listen 80;
}

Restart nginx and we have our proxy server set up:

1
systemctl restart nginx

Set up Letsencrypt

certbot 用于在真实环境下配置一个可用的网站证书

1
2
3
apt install certbot
apt install python3-certbot-nginx
certbot --nginx

若在虚拟环境下,发布点/根锚点可以只配置一个自签名证书,然后配置让请求端接受即可

https://www.liaoxuefeng.com/article/990311924891552 (注意脚本中密钥大小 1024 太小要改 2048)

注意,在 Relying Party 的请求过程中,会验证 https 证书是否合法,自签名证书是无法通过验证的,最好还是得用合法证书。

Install Krill

1
2
3
4
5
6
7
8
apt-get update
apt install gnupg curl ca-certificates lsb-release
curl -fsSL https://packages.nlnetlabs.nl/aptkey.asc | gpg --dearmor -o /usr/share/keyrings/nlnetlabs-archive-keyring.gpg
echo \
"deb [arch=$(dpkg --print-architecture) signed-by=/usr/share/keyrings/nlnetlabs-archive-keyring.gpg] https://packages.nlnetlabs.nl/linux/ubuntu \
$(lsb_release -cs) main" | tee /etc/apt/sources.list.d/nlnetlabs.list > /dev/null
apt-get update
apt-get install krill

Configure Testbed

编辑 /etc/krill.conf 配置文件,修改 auth_token **和 service_uri="https://krill.example.org/" ,并添加以下内容

1
2
3
4
5
[testbed]
rrdp_base_uri = "https://krill.example.org/rrdp/"
rsync_jail = "rsync://krill.example.org/repo/"
ta_aia = "rsync://krill.example.org/ta/ta.cer"
ta_uri = "https://krill.example.org/ta/ta.cer"

Start / Enable krill

1
systemctl start krill

如果使用的是 docker 内的 systemctl,可以将 /usr/lib/systemd/system/krill.service 中的 type=exec 改为 type=simple。(仍旧无法启动的话就直接执行 /usr/bin/krill --config=/etc/krill.conf

TAL 文件可以通过 https://krill.example.org/ta/ta.tal 获取

发布点仓库详细配置

在几乎所有情况下,AS都会在设置hosted RPKI时与一个或多个区域互联网注册管理机构(RIR)或国家互联网注册管理机构(NIR)进行交互。它们每一个的基本原则都是相同的:RIR或NIR需要确定您是谁、您有权获得哪些资源以及您的RPKI证书和ROA将在哪里发布。

您的身份、权限和权利都由注册表管理,并通过各自的member portals公开。其余信息在两个XML文件中交换。您需要提供由Krill生成的子请求,作为回复,您将收到需要回馈给Krill的父响应。您的RIR或NIR也可能提供RPKI发布服务器。您可以在任何您喜欢的地方发布您的证书和ROA,因此第三方也可能提供RPKI发布服务器。要使用此服务,您需要进行额外的交换。您需要生成并提供发布者请求文件,作为回复,您将收到存储库响应。(详见 配置流程)

如果您需要自己发布您的证书和ROA,可以按如下所述进行操作:

https://krill.docs.nlnetlabs.nl/en/stable/publication-server.html#doc-krill-publication-server

Krill 带有一个嵌入式发布服务器,您可以使用它为您自己的CA以及远程CA提供发布协议服务。原则上,您可以在用于操作CA的同一个Krill实例上启用发布服务器。但是,为此目的使用单独的实例可能更好,这将允许对任一实例进行更细粒度的权限改造,并且在出现问题时更容易解析日志文件。

We use the term Publication Server to describe the (Krill) server that CAs will connect to over the RFC 8181 protocol in order to publish their content. We use the term Repository Server to describe a server which makes this content available to RPKI Validators.

Configure Publication Server

Krill运行RFC8181发布服务器。使用您的发布服务器的远程发布者CA需要在您在服务器中指定的service_uri下的 /rfc8181路径下连接到此服务器。您得确保您设置了一个代理服务器,如NGINX、Apache等,它使用有效的HTTPS证书,并且为 Krill 代理 /rfc8181。

如果您可以仅在运行发布服务器的计算机上使用krillc CLI,那么最安全的选择是不代理对API的访问;但是,如果您需要使用来自其他机器的CLI或API,那么您应该将对路径“/api”的访问代理给Krill。以下为 nginx 配置示例 /etc/nginx/sites-enabled/krill.example.org

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
server {
listen 443 ssl http2;
listen [::]:443 ssl http2;
server_name $hostname;
charset UTF-8;

access_log "/var/log/nginx/[hostname]-access.log";
error_log "/var/log/nginx/[hostname]-error.log";

# SSL setup is missing - for recommended settings see https://ssl-config.mozilla.org

client_max_body_size 128m;

#
# The paths are split:
# * /rfc8181 should be open to all child CAs
# * /api has an allow-list of origins that can access it.
#
location /rfc8181 {
proxy_pass https://127.0.0.1:3000/rfc8181;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;

# krill does not use a valid certificate/tls is handled by nginx
proxy_ssl_verify off;
}

location /api {
proxy_pass https://127.0.0.1:3000/api;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;

# allow IPv4 and IPv6 documentation ranges
allow 192.0.2.0/24;
allow 2001:0db8::/32;
deny all;

# krill does not use a valid certificate/tls is handled by nginx
proxy_ssl_verify off;
}
}

Configure Repository Server

要实际向Rsync和RRDP客户端提供已发布的内容,您需要使用Rsyncd和NGINX等工具运行自己的存储库服务器。Krill Publation Server会将存储库文件写入其配置文件中指定的数据目录下:

  • $DATA_DIR/repo/rsync/current/ Contains the files for Rsync
  • $DATA_DIR/repo/rrdp/ Contains the files for HTTPS (RRDP)

如果 Publication Server 和 Repository Server 位于不同的机器上,还要考虑数据同步的问题。An option is to use some kind of shared file system (NFS, clustered filesystem, network storage) where the Krill Publication Server can write, and your Repository Servers can read.

下一步是配置您的rsync守护进程,为您的文件公开一个“模块”,确保包含“模块”的Rsync URI与Krill配置文件中的rsync_base匹配。

基本配置可以简单如下:

1
2
3
4
5
6
7
8
9
10
11
12
$ apt install rsync
$ cat /etc/rsyncd.conf
uid = nobody
gid = nogroup
max connections = 50
socket options = SO_KEEPALIVE

[repo]
path = /var/lib/krill/data/repo/rsync/current/
comment = RPKI repository
read only = yes
$ systemctl start rsync

对于RRDP,您需要设置您选择的Web服务器并确保它具有有效的TLS证书。接下来,您可以在 ngnix 配置对 $DATA_DIR/repo/rrdp下的文件提供访问:

1
2
3
4
5
6
7
# */etc/nginx/sites-enabled/krill.example.org*
...

# Maps to the directory where krill stores RRDP file
location /rrdp {
alias /var/lib/krill/data/repo/rrdp/;
}

Initialize Publication Server

1
krillc pubserver server init --rrdp https://krillrepo.example.com/rrdp/ --rsync rsync://krillrepo.example.com/repo/

验证 RRDP 设置是否有效。尝试获取基本URI下的“notification. xml”文件,例如https://krillrepo.example.com/rrdp/notification.xml。

通过以下操作验证对rsync服务器的访问是否有效: rsync --list-only rsync://krillrepo.example.com/repo/

配置成功生效后,便可以为你的 CA 添加 publishers 了。如果需要重新配置,则输入 krillc pubserver server clear 后重复以上操作即可。

注意 rsync server 监听的默认端口是 873,记得防火墙开放此端口

Key Rollover

  1. 初始化新密钥:使用命令 krillc keyroll init 生成一个新的密钥对,并发送证书签名请求(CSR)给父CA。使用命令 krillc show 可以查看当前父 CA 密钥更新状态(pending and active key/new and active key/active and old key)
  2. 等待并激活新密钥:等待24小时后,使用命令 krillc keyroll activate 激活新密钥。所有对象(如ROA)将在新密钥下重新发布,旧密钥将被撤销。

配置信任锚点

Making a Krill Sanctuary (nlnetlabs.nl)

原理

krill TA 在逻辑上被分离为相互关联的“Proxy”和“Signer”组件

  • TA Signer 负责生成和使用 TA RPKI 密钥。它被设计为使用自己的独立命令行工具 krillta 进行操作。为了提高安全性,该工具可用于不使用时保持与网络断开和离线的系统,并且可选地可以使用 HSM 来处理密钥
  • TA Proxy 始终位于krill内部,负责所有在线操作,例如处理与子 CA 的RFC 6492通信,以及发布由 TA Signer 使用 RFC 8181通信协议与发布服务器签名的材料。TA Proxy 对这些协议使用自己的“身份”密钥和证书。

命令

Run Krill with TA Support

在 /etc/krill.conf 文件里添加 ta_support_enabled = true

Initialize TA Proxy

输入命令 krillta proxy init,这将创建一个空的TA代理,它有一个用于通信的身份密钥,几乎没有其他东西。

Initialize Publication Server

按照前述所完成的,初始化一个发布点

TA Proxy Publisher Request

获取TA Proxy 的 Publisher Request XML文件并将其保存,以便将其上传到发布服务器:krillta proxy repo request > ./pub-req.xml

Add TA Proxy as Publisher

将TA代理添加为发布者并捕获存储库响应XML:krillc pubserver publishers add --request ./pub-req.xml >./repo-res.xml

Configure Repository for TA Proxy

现在将发布服务器(及其关联的存储库)添加到TA代理:krillta proxy repo configure --response ./repo-res.xml

Configure the TA Signer

创建一个工作目录,您的TA签名者可以在其中保存其状态和日志文件。然后创建一个配置文件,如果您使用 /etc/krillta.conf作为配置文件,那么krillta将能够自动找到它,否则使用-c /path/to/krillta.conf覆盖此默认值。

配置文件必须至少包含数据目录的设置。其他设置是可选的-您只需要在要更改默认日志记录和/或使用HSM时更改它们。

Initialize the TA Signer

TA签名者总是与单个TA代理相关联。我们在前面的步骤中初始化了TA代理并为其配置了一个存储库。我们现在需要导出一些信息,以便我们可以为该代理初始化一个TA签名者。

获取代理ID krillta proxy id --format json > ./proxy-id.json

获取代理存储库联系 krillta proxy repo contact --format json >./proxy-repo.json

初始化 (需要指定应该在信任锚定位器TAL上使用的URI)

1
2
3
4
krillta signer init --proxy_id ./proxy-id.json \
--proxy_repository_contact ./proxy-repo.json\
--tal_https <HTTPS URIfor TA cert on TAL>\
--tal_rsync <RSYNC URIfor TA cert on TAL>

Associate the TA Signer with the Proxy

获取TA Signer’info’JSON文件并保存:krillta signer show > ./signer-info.json

然后“初始化”与TA代理关联的签名者:krillta proxy signer init --info ./signer-info.json

此时,您应该看到TAL在 /ta/ta.tal端点下可用。它将包括初始化签名者时指定的HTTPS和rsync URI。您可以在 /ta/ta.cer端点下下载TA证书的副本。复制它,并将其放在Web服务器和rsync守护程序可以提供服务的位置。

krill 常用命令

设置环境变量 export KRILL_CLI_TOKEN=correct-horse-battery-staple 避免每次命令都要输入 TOKEN

Certificate Authority

krillc list 查看当前 CA

krillc add --ca newca 创建新的CA

krillc delete --ca newca 删除CA

krillc repo request --ca newca 为CA生成一个repo request XML(RFC8183)

krillc repo configure --ca newca --response ./new-ca-repository-response.xml 用repo response 为CA配置发布服务

krillc repo status/show --ca newca 查看CA对应的发布点状态

krillc parents request --ca newca 为CA生成一个child request XML(RFC8183)

krillc parents add --ca newca --parent my_parent --response ./data/new-ca-parent-response.xml 用parent-response 为CA配置父节点

krillc parents statuses --ca newca 查看CA的父节点状态

krillc parents remove --ca newca --parent my_parent 删除CA的父节点

ROAs

krillc roas list 查看当前签发的 roa 列表

krillc roas update --add '2a04:b900::/29 => 65503 # my v6 router' 添加 roa 对象

krillc roas update --remove '2a04:b900::/29 => 65503' 删除 roa 对象

从文件中批量添加删除 roa 对象

1
2
3
4
5
6
$ cat ./data/roa-delta.txt
# Some comment
A: 10.0.0.0/24 => 64496 # Add prefix
A: 10.1.0.0/16-20 => 64496 # Add prefix with max length
R: 10.0.3.0/24 => 64496 # Remove existing authorization
$ krillc roas update --delta ./data/roa-delta.txt --ca newca

Publication Server / Repository Server

krillc pubserver server init —rrdp https://xxx.xxx.xxx/ —rsync rsync://xxx.xxx.xxx/ 初始化发布点

krillc pubserver server stats 发布点状态(添加参数 —format json,可以看到每个发布者详细状态

krillc pubserver publishers add --publisher localname --request ./data/new-ca-publisher-request.xml 根据发布者提供的 request.xml 添加相关配置,并返回 response.xml 信息

krillc pubserver publishers list 列出所有发布者

krillc pubserver publishers show --publisher testbed 展示发布者详细信息,查看其所发布对象

krillc pubserver publishers remove --publisher publisher 删除发布者

krillc pubserver server clear 清除发布实例以便重新初始化

Trust Anchor

krillta proxy init

krillta proxy repo request > ./pub-req.xml

krillta proxy repo configure --response ./repo-res.xml

krill 配置文件

data_dir = "/var/lib/krill/data/" where the publication server will store its data.

admin_token = "a8f39b03a4e57ad5ded653a3de185faf” admin token that can be used to interact with the API

service_uri = "https://krill.example.org/" If you want to support remote delegated CAs to be children under a CA and/or publish their content, then you should set the “service uri”

krill 数据存储目录的结构

Untitled

https_mode = "disable"

更改配置文件后,需要重新执行krill命令 /usr/bin/krill --config=/etc/krill.conf


使用 Krill 部署 RPKI CA 和发布点
https://xxyyue.pages.dev/2024/03/15/KrillDeployment/
作者
xxyyue
发布于
2024年3月15日
许可协议