Installing RPKI Relying Party Software

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

  1. Cloudflare cfrpki
  2. FORT Validator
  3. RIPE NCC Validator-3
  4. Routinator
  5. rpki-client
  6. Conclusion

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.