In this post I outline the installation of the most popular RPKI relying party (RP) software implementations on Debian 10 (Buster). These installation instructions are primarily for my own reference, but others may find this useful. I take inspiration from Tashi Phuntsho’s How to: Installing an RPKI Validator. The primary differences include updated software, an installation tailored for my specific purposes, and some additional configuration detail. Undoubtedly my installation may not be ideal nor necessarily even well suited for general use. For instance, my choice of operating system, package selection, directory layout, or configuration settings may not be optimal generally, nor specifically well suited for anyone else. These are my point-in-time reference notes, not best practices.
RP software implementations typically perform a set of functions including RPKI repository data fetching, validation, caching, and distribution of validated data to local clients (e.g. BGP routers) for policy enforcement. Many RPKI RP implementations simply refer to themselves as a validator and the focus is on this aspect of RP software, but instructions for complimentary software and configurations such as the RPKI to Router protocol and syslog-ng are included for completeness.
It may be tempting to ask which implementation is best? Instead, I’ll offer two suggestions. First, new installations would be ill-advised to use the RIPE NCC Validator-3, because it was recently announced that maintenance will end on July 1, 2021. Second, to mitigate potential bugs and implementation nuances, serious RP deployments should strongly consider running at least two distinct RP validation software packages. Of the remaining implementations, any combination of two would be reasonable.
An additional few words of caution. RPKI RP software is changing rapidly. The software and software versions available are likely to change soon after this article is published. Be sure to check for more recent versions, carefully review change notes, and consider any new implementation that may become available.
Table of Contents
Cloudflare cfrpki
The Cloudflare RPKI Toolkit
includes two distinct packages, both implemented in the Go language.
OctoRPKI is the validator that fetches RPKI repository data and
performs object validation. It supports both rsync
and RRDP for
synchronization. Both protocols perform synchronization at 20
minute intervals by default. An embedded web service can be used to make
validated data, statistics, and other debugging information available
locally or to remote clients. As of this writing 1.2.0 is the latest
version. I used the .deb
package.
WARNING: if you are upgrading from an earlier version and have
non-default settings in /etc/default/octorpki
, they will be
overwritten. There is currently an
issue open, which I
expect will be fixed in the next package version.
Get and install the package:
wget https://github.com/cloudflare/cfrpki/releases/download/v1.2.0/octorpki_1.2.0_amd64.deb
sudo dpkg -i octorpki_1.2.0_amd64.deb
WARNING: by default the octorpki
daemon will listen on TCP port 8081 on all
available interfaces. This may be what you want, but if not, be sure to
restrict access to the port or specify the interface and/or port in the
configuration before starting the daemon.
Fetch and install the ARIN TAL:
sudo wget https://www.arin.net/resources/manage/rpki/arin.tal -O /usr/share/octorpki/tals/arin.tal
Since we are going to have GoRTR serve validated data from OctoRPKI, we
will sign the output with a local certificate and set the configuration
parameters accordingly. In my setup I also enable profiling to aid in
software debugging so I set -pprof
in the configuration, but this is
probably not something most production installations would enable.
sudo su -
cd /etc/ssl
openssl ecparam -genkey -name prime256v1 -noout -outform pem > private/octorpki.pem
openssl ec -in private/octorpki.pem -pubout -outform pem > certs/octorpki.pem
exit
Update/create /etc/default/octorpki
to contain:
OCTORPKI_ARGS=-output.sign.key=/etc/ssl/private/octorpki.pem -pprof
I use syslog-ng and separate OctoRPKI logs out from the normal daemon
logs. Create/update /etc/syslog-ng/conf.d/octorpki.conf
to contain:
filter f_octorpki { facility(daemon) and program("octorpki"); };
destination df_octorpki {
file( "/var/log/octorpki/$YEAR/$MONTH/octorpki.$YEAR$MONTH$DAY"
create_dirs(yes)
dir_perm(0755)
perm(0644)
);
};
log { source(s_src); filter(f_octorpki); destination(df_octorpki); };
Restart syslog-ng
, enable octorpki
to start at boot, and start it now:
sudo systemctl restart syslog-ng
sudo systemctl enable octorpki
sudo systemctl start octorpki
Now that OctoRPKI should be running, we turn our attention to GoRTR, which will use the validated RPKI repository data OctoRPKI produces and make it available to downstream clients.
GoRTR is second half of the
Cloudflare toolkit. GoRTR implements the RPKI to router (rpki-rtr
)
protocol. This is used to serve validated data to downstream clients
such as BGP routers. Often it is used to serve validated data produced
by OctoRPKI and rpki-client (discussed elsewhere in this article). As
of this writing, 0.14.6 is the latest version. I used the .deb
package.
WARNING: if you are upgrading from an earlier version and have
non-default settings in /etc/default/gortr
, they will be overwritten.
This is essentially the same
issue for OctoRPKI,
both of which I expect will fixed in the next package versions.
Get and install the package:
wget https://github.com/cloudflare/gortr/releases/download/v0.14.6/gortr_0.14.6_amd64.deb
sudo dpkg -i gortr_0.14.6_amd64.deb
WARNING: by default the gortr
daemon will listen on TCP ports 8080
(metrics) and 8282 (rpki-rtr
) on all available interfaces. This may
be what you want, but if not, be sure to restrict access to the port or
specify the interface and/or port in the configuration before starting
the daemon.
Update/create /etc/default/gortr
to contain:
GORTR_ARGS=-cache http://127.0.0.1:8081/output.json -verify.key /etc/ssl/certs/octorpki.pem
I use syslog-ng and separate GoRTR logs out from the normal daemon logs.
Create/update /etc/syslog-ng/conf.d/gortr.conf
to contain:
filter f_gortr { facility(daemon) and program("gortr"); };
destination df_gortr {
file( "/var/log/gortr/$YEAR/$MONTH/gortr.$YEAR$MONTH$DAY"
create_dirs(yes)
dir_perm(0755)
perm(0644)
);
};
log { source(s_src); filter(f_gortr); destination(df_gortr); };
Restart syslog-ng
, enable gortr
to start at boot, and start it now:
sudo systemctl restart syslog-ng
sudo systemctl enable gortr
sudo systemctl start gortr
FORT Validator
The FORT Validator is a complete
RP software package written in C. It supports both rsync
and RRDP for
synchronization. By default both protocols perform synchronization at
60 minute intervals. As of this writing 1.4.2 is the latest version. I
used the `.deb' package.
Get and install the package:
wget https://github.com/NICMx/FORT-validator/releases/download/v1.4.2/fort_1.4.2-1_amd64.deb
sudo dpkg -i fort_1.4.2-1_amd64.deb
Fetch and install the ARIN TAL:
wget https://raw.githubusercontent.com/NICMx/FORT-validator/v1.4.0/fort_setup.sh
chmod +x fort_setup.sh
sudo ./fort_setup.sh /etc/fort/tal
WARNING: I set and configure the rpki-rtr
port (8323) to listen on
all interfaces by default. This may be what you want, but if not be
sure to set access to the port or specify the interface and/or port in
the configuration before starting the daemon.
Update/create /etc/fort/config.json
to contain:
{
"tal": "/etc/fort/tal",
"local-repository": "/var/lib/fort",
"slurm": "/etc/fort/slurm/",
"server": {
"port": "8323"
},
"log": {
"level": "info",
"output": "syslog"
}
}
I use syslog-ng and separate FORT logs out from the normal daemon logs.
Create/update /etc/syslog-ng/conf.d/fort-validator.conf
to contain:
filter f_fort-validator { facility(daemon) and program("fort"); };
destination df_fort-validator {
file( "/var/log/fort-validator/$YEAR/$MONTH/fort-validator.$YEAR$MONTH$DAY"
create_dirs(yes)
dir_perm(0755)
perm(0644)
);
};
log { source(s_src); filter(f_fort-validator); destination(df_fort-validator); };
Restart syslog-ng
, enable fort
to start at boot, and start it now:
sudo systemctl restart syslog-ng
sudo systemctl enable fort
sudo systemctl start fort
RIPE NCC Validator-3
WARNING: Be sure you are working with Validator-3. There is an older RIPE NCC Validator code base separately maintained. I advise against using the older version even for research purposes. As of this writing, the older version has not been updated in about two years.
The RIPE NCC Validator
includes two distinct packages, both implemented in Java. One component
is the validator that fetches RPKI repository data and performs object
validation. It supports both rsync
and RRDP for synchronization. By
default rsync
will perform synchronization at 10 minute intervals and
RRDP will perform synchronization at 2 minute intervals. The other
component is an implementation of the RPKI to Router protocol. An
embedded web service can be used to make validated data, statistics, and
other debugging information available locally or to remote clients. As
of this writing 3.2-2020.10.28.23.06 is the latest version for both
packages. I used the .deb packages.
WARNING: if you are upgrading from an earlier version and have
non-default settings in /etc/rpki-validator-3/application.properties
or /etc/rpki-rtr-server/application.properties
, they will be
overwritten.
Get and install the packages:
wget https://ftp.ripe.net/tools/rpki/validator3/prod/deb/rpki-validator-3.2-2020.10.28.23.06.deb
wget https://ftp.ripe.net/tools/rpki/validator3/prod/deb/rpki-rtr-server-3.2-2020.10.28.23.06.deb
sudo dpkg -i rpki-validator-3.2-2020.10.28.23.06.deb
sudo dpkg -i rpki-rtr-server-3.2-2020.10.28.23.06.deb
Fetch and install the ARIN TAL:
sudo wget https://www.arin.net/resources/manage/rpki/arin-ripevalidator.tal -O /var/lib/rpki-validator/preconfigured-tals/arin.tal
WARNING: by default the java processes will listen on TCP ports 8080 and 8081 on the loopback interface and 8323 on all available interfaces. However, below I change the configuration so they all listen on all available interfaces by default. This may be what you want, but if not be sure to set access to the port or specify the interface and/or port in the configuration before starting the daemon.
To allow the API to listen on all interfaces for the validator and RTR services, perform the following configuration adjustments:
sudo sed -i 's/\(server.address\)=localhost/\1=0.0.0.0/g' /etc/rpki-validator-3/application.properties
sudo sed -i 's/\(.*\)\.address=localhost/\1.address=0.0.0.0/g' /etc/rpki-rtr-server/application.properties
I change the RTR service logging severity level from WARN to INFO with the following command:
sudo sed -i 's/\(.*\)\.rpki\.rtr=WARN/\1.rpki.rtr=INFO/g' /etc/rpki-rtr-server/application.properties
I use syslog-ng and separate out logs from the normal daemon logs.
Create /etc/syslog-ng/conf.d/ripencc-rpki.conf
to contain:
filter f_validator { facility(daemon) and program("rpki-validator-3.sh"); };
filter f_rtr { facility(daemon) and program("rpki-rtr-server.sh"); };
destination df_validator {
file( "/var/log/validator/$YEAR/$MONTH/validator.$YEAR$MONTH$DAY"
create_dirs(yes)
dir_perm(0755)
perm(0644)
);
};
destination df_rtr {
file( "/var/log/rtr/$YEAR/$MONTH/rtr.$YEAR$MONTH$DAY"
create_dirs(yes)
dir_perm(0755)
perm(0644)
);
};
log { source(s_src); filter(f_validator); destination(df_validator); };
log { source(s_src); filter(f_rtr); destination(df_rtr); };
Restart syslog-ng
, enable the validator and RTR services to start at
boot, and start both of them now:
sudo systemctl restart syslog-ng
sudo systemctl enable rpki-validator-3
sudo systemctl enable rpki-rtr-server
sudo systemctl start rpki-validator-3
sudo systemctl start rpki-rtr-server
Routinator
Routinator is a complete RP
software package written in Rust. It supports both rsync
and RRDP for
synchronization. By default both protocols perform synchronization at
10 minute intervals. An embedded web service can be used to make
validation data, statistics, and other debugging information available
locally or to remote clients. As of this writing 0.8.0 is the latest
version. I used Rust and Cargo to prepare the installation.
NOTE: You may prefer to use the NLnet Labs software package repository.
Setup a dedicated user environment that will run the daemon:
sudo useradd -r routinator
sudo mkdir -p /usr/local/routinator
sudo chown -R routinator:routinator /usr/local/routinator
Retrieve and install the software:
sudo apt-get install curl rsync build-essential
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh
source ~/.cargo/env
cargo install --locked routinator
sudo cp ~/.cargo/bin/routinator /usr/local/bin
sudo mkdir -p /var/lib/routinator
sudo chown routinator:routinator /var/lib/routinator
Initialize the cache directories and accept the ARIN TAL:
sudo -u routinator /usr/local/bin/routinator -b /var/lib/routinator init --accept-arin-rpa
Update/create /etc/default/routinator
to contain:
ROUTINATOR_CONF=/usr/local/etc/routinator.conf
DAEMON_OPTS=
DAEMON_ARGS="server"
Update/create /usr/local/etc/routinator.conf
to contain (replace the
example IP addresses with the IP addresses you want to be listeners for
the respective service interfaces):
dirty = false
disable-rrdp = false
exceptions = []
expire = 7200
history-size = 10
http-listen = ["192.0.2.1:8323", "[2001:db8::1]:8323"]
log = "default"
log-level = "info"
refresh = 600
repository-dir = "/var/lib/routinator/repository"
retry = 600
rrdp-proxies = []
rrdp-root-certs = []
rsync-command = "rsync"
rsync-timeout = 300
rtr-listen = ["192.0.2.1:3323", "[2001:db8::1]:3323"]
strict = false
syslog-facility = "daemon"
systemd-listen = false
tal-dir = "/var/lib/routinator/tals"
validation-threads = 2
Update/create /etc/systemd/system/routinator.service
and in it put:
[Unit]
Description=Routinator RPKI Validator
After=network.target
[Service]
User=routinator
Group=routinator
type=simple
EnvironmentFile=-/etc/default/routinator
ExecStart=/usr/local/bin/routinator -c ${ROUTINATOR_CONF} ${DAEMON_OPTS} ${DAEMON_ARGS}
Restart=on-failure
RestartSec=5s
[Install]
WantedBy=multi-user.target
I use syslog-ng and separate out logs from the normal daemon logs. Create /etc/syslog-ng/conf.d/routinator.conf to contain:
filter f_routinator { facility(daemon) and program("routinator"); };
destination df_routinator {
file( "/var/log/routinator/$YEAR/$MONTH/routinator.$YEAR$MONTH$DAY"
create_dirs(yes)
dir_perm(0755)
perm(0644)
);
};
log { source(s_src); filter(f_routinator); destination(df_routinator); };
Reload the systemd service files, restart syslog-ng
, enable the
Routinator daemon to start at boot, and start it now:
sudo systemctl daemon-reload
sudo systemctl restart syslog-ng
sudo systemctl enable routinator
sudo systemctl start routinator
rpki-client
rpki-client is a validator implemented
in C. It fetches RPKI repository data and performs object validation.
As of this writing it only supports rsync
, but RRDP support is
planned. rpki-client is a relatively minimal stand-alone binary and
must be called periodically by an automated process such as cron
using
whatever synchronization interval the installer chooses. I setup
rpki-client
to run at 20 minute intervals. I configure the software
to output validated data to a local CSV file and any messages from the
program are captured and relayed to syslog. As of this writing 6.8p1
(portable) is the latest version. I used a source tarball.
NOTE: You may prefer to configure your system to use the Debian maintainer’s package from bullseye (testing).
Retrieve and install the software:
wget https://ftp.openbsd.org/pub/OpenBSD/rpki-client/rpki-client-6.8p1.tar.gz
tar xvf rpki-client-6.8p1.tar.gz
cd rpki-client-6.8p1
make
sudo make install
sudo mkdir -p /usr/local/var/{cache,db}/rpki-client
Install the ARIN TAL:
sudo wget https://www.arin.net/resources/manage/rpki/arin.tal -O /usr/local/etc/rpki/arin.tal
I use syslog-ng to capture messages from rpki-client
’s STDOUT and
STDERR using the logger
utility. Create
/etc/syslog-ng/conf.d/rpki-client.conf
to contain:
filter f_rpki-client { facility(local0) and program("rpki-client"); };
destination df_rpki-client {
file( "/var/log/rpki-client/$YEAR/$MONTH/rpki-client.$YEAR$MONTH$DAY"
create_dirs(yes)
dir_perm(0755)
perm(0644)
);
};
log { source(s_src); filter(f_rpki-client); destination(df_rpki-client); };
Create a root crontab to contain:
*/20 * * * * /usr/local/bin/rpki-client -c 2>&1 | logger -p local0.info -t rpki-client
/usr/local/var/db/rpki-client/csv
will be updated every 20 minutes
with validated data.
NOTE: use -cj
options to produce both a CSV and JSON formatted
output. The latter can then be used as input to a RPKI to RTR process
such as GoRTR.
Conclusion
I perform some additional configuration that I did not outline here, because it is of little use outside of my environment. I also setup IP Tables filter rules to allow a select set of remote clients to periodically fetch data, statistics, and debugging information. I also perform some additional archiving of the rpki-client’s CSV output, saving each synchronization interval’s output for historical purposes.
Not only do I have network operational interest in RP software setup and
maintenance, but I am also interested in RP software behavior in the
wild as part of ongoing RPKI research work. If you are operating an RP
and can make the rpki-rtr
service interface available to me to
periodically collect validation information I’d like to hear from you.
This will help inform and ongoing research project. Lastly, any and all
comments about this article will be welcome. I am happy to make minor
updates or editorial comments acknowledging any notable contributions as
warranted.
[Update: 2020-11-23]: Added notes about availability of packages for
Routinator and rpki-client - hat tips to NLnet Labs and Job Snijders.
Added note about using the -j
option for rpki-client to feed GoRTR -
hat tip to Job Snijders. Fixed the end of maintenance date for RIPE NCC
Validator-3.