1
0
mirror of https://github.com/NLnetLabs/routinator.git synced 2024-05-19 06:50:04 +00:00

Restructure TAL configuration and remove init command. (#796)

This commit restructures the TAL configuration in response to the dropped
requirement to opt into the ARIN TAL.

Routinator will now use the bundled RIR TALs directly unless told otherwise
by the new --no-rir-tals command line and config option. The additional
bundled TALs can be added via the new --tal command line and config option.
Additionally, the TAL directory can still be used via the --extra-tals-dir
option. The tal-dir option has been removed but will still be accepted – and
ignored – in the config file only.

The init command has been removed.

Co-authored-by: Alex Band <alex@nlnetlabs.nl>
Co-authored-by: ximon18 <3304436+ximon18@users.noreply.github.com>
Co-authored-by: Luuk Hendriks <mail@luukhendriks.eu>
This commit is contained in:
Martin Hoffmann
2022-11-02 11:44:16 +01:00
committed by GitHub
parent 20739c369d
commit 22de300fa8
21 changed files with 654 additions and 1075 deletions

View File

@ -85,15 +85,13 @@ assets = [
["target/release/routinator", "usr/bin/", "755"],
["README.md", "usr/share/doc/routinator/", "644"],
["doc/routinator.1", "usr/share/man/man1/routinator.1", "644"],
["etc/routinator.conf.system-service", "etc/routinator/routinator.conf", "644"],
["pkg/common/service.preset", "/lib/systemd/system-preset/50-routinator.preset", "644"],
["pkg/common/routinator-init", "usr/bin/", "755"]
["etc/routinator.conf.system-service", "etc/routinator/routinator.conf", "644"]
]
maintainer-scripts = "pkg/debian"
changelog = "target/debian/changelog" # this will be generated by the pkg workflow
copyright = "Copyright (c) 2020, NLnet Labs. All rights reserved."
conf-files = ["/etc/routinator/routinator.conf"]
systemd-units = { unit-name = "routinator", unit-scripts = "pkg/common", enable = false }
systemd-units = { unit-name = "routinator", unit-scripts = "pkg/common", enable = true }
[package.metadata.deb.variants.minimal]
@ -113,9 +111,7 @@ assets = [
{ source = "target/release/routinator", dest = "/usr/bin/routinator", mode = "755" },
{ source = "target/rpm/routinator.service", dest = "/lib/systemd/system/routinator.service", mode = "644" },
{ source = "doc/routinator.1", dest = "/usr/share/man/man1/routinator.1", mode = "644", doc = true },
{ source = "etc/routinator.conf.system-service", dest = "/etc/routinator/routinator.conf", mode = "644", config = true },
{ source = "pkg/common/routinator-init", dest = "/usr/bin/routinator-init", mode = "755" },
{ source = "pkg/common/service.preset", dest = "/lib/systemd/system-preset/50-routinator.preset", mode = "644" },
{ source = "etc/routinator.conf.system-service", dest = "/etc/routinator/routinator.conf", mode = "644", config = true }
]
# These get set using cargo-generate-rpm --set-metadata at package build time.
#post_install_script = ...

View File

@ -152,16 +152,10 @@ RUN apk add --no-cache libgcc rsync tini
RUN addgroup -g ${RUN_USER_GID} ${RUN_USER} && \
adduser -D -u ${RUN_USER_UID} -G ${RUN_USER} ${RUN_USER}
# Create the repository and TAL directories
RUN mkdir -p /home/${RUN_USER}/.rpki-cache/repository /home/${RUN_USER}/.rpki-cache/tals && \
# Create the repository directory
RUN mkdir -p /home/${RUN_USER}/.rpki-cache/repository && \
chown -R ${RUN_USER_UID}:${RUN_USER_GID} /usr/local/bin/routinator /home/${RUN_USER}/.rpki-cache
# Due to ARIN TAL distribution terms, we can't do this here.
# An individual user, however, might want to anyway - after reviewing
# https://www.arin.net/resources/rpki/tal.html.
#
#COPY --from=build /tmp/routinator/tals/*.tal /home/${RUN_USER}/.rpki-cache/tals/
# Switch to our applications user
USER $RUN_USER_UID
@ -175,4 +169,3 @@ EXPOSE 9556/tcp
# way of activating Tini, but cannot be enabled from inside the Docker image).
ENTRYPOINT ["/sbin/tini", "--", "routinator"]
CMD ["server", "--rtr", "0.0.0.0:3323", "--http", "0.0.0.0:9556"]

View File

@ -89,9 +89,6 @@ The command will build Routinator and install it in the same directory that
Cargo itself lives in, likely ``$HOME/.cargo/bin``. This means Routinator
will be in your path, too.
.. Note:: Before you can use Routinator, you must first
:doc:`initialise<initialisation>` the application.
Updating
""""""""
@ -348,15 +345,7 @@ run Routinator on Security Enhanced Linux (SELinux) using CentOS 7.
Edit the PATH line to include "/home/routinator/.cargo/bin"
PATH=$PATH:$HOME/.local/bin:$HOME/bin:/home/routinator/.cargo/bin
14. Initialise Routinator, accept the ARIN TAL and exit back to the user with
:command:`sudo`:
.. code-block:: bash
/home/routinator/.cargo/bin/routinator -b /opt/routinator init -f --accept-arin-rpa
exit
15. Create a routinator systemd script using the template below:
14. Create a routinator systemd script using the template below:
.. code-block:: bash
@ -384,7 +373,7 @@ run Routinator on Security Enhanced Linux (SELinux) using CentOS 7.
/home/routinator/.cargo/bin/routinator -v -b /opt/routinator server \
--http 127.0.0.1:8080 --rtr 172.16.47.235:8323 --rtr [2001:db8::43]:8323
16. Configure SELinux to allow connections to localhost and to allow
15. Configure SELinux to allow connections to localhost and to allow
:program:`rsync` to write to the ``/opt/routinator`` directory:
.. code-block:: bash
@ -392,7 +381,7 @@ run Routinator on Security Enhanced Linux (SELinux) using CentOS 7.
sudo setsebool -P httpd_can_network_connect 1
sudo semanage permissive -a rsync_t
17. Reload the systemd daemon and set the routinator service to start at
16. Reload the systemd daemon and set the routinator service to start at
boot:
.. code-block:: bash
@ -401,7 +390,7 @@ run Routinator on Security Enhanced Linux (SELinux) using CentOS 7.
sudo systemctl enable routinator.service
sudo systemctl start routinator.service
18. Set up the firewall to permit :program:`ssh`, HTTPS and port 8323 for the
17. Set up the firewall to permit :program:`ssh`, HTTPS and port 8323 for the
RTR protocol:
.. code-block:: bash
@ -421,6 +410,6 @@ run Routinator on Security Enhanced Linux (SELinux) using CentOS 7.
source address="<peering router IPv6 loopback subnet>" port port=8323 protocol=tcp accept'
sudo firewall-cmd --reload
19. Navigate to :samp:`https://{<IP-address>}/metrics` to see if it's
18. Navigate to :samp:`https://{<IP-address>}/metrics` to see if it's
working. You should authenticate with the username and password that you
provided in step 10 of setting up the RPKI Validation Server.

View File

@ -1,3 +1,11 @@
.. Important:: **With Routinator 0.12.0 and newer, initialisation to accept
the ARIN Relying Party Agreement (RPA) is no longer
required.** The RPA `has been updated
<https://www.arin.net/announcements/20220929/>`_ to allow the
ARIN TAL to be embedded in Relying Party software. By
default, Routinator is now set up to fetch and validate all
RPKI data needed for production environments.
Configuration
=============
@ -13,22 +21,20 @@ the default values can be found in the `repository
<https://github.com/NLnetLabs/routinator/blob/master/etc/routinator.conf.example>`_.
Routinator can run as a daemon but you can also use it interactively from the
command line. However, there are several considerations with regards to how
you've installed and how you intend to use Routinator, which we'll cover
below.
command line. There are several considerations with regards to how you've
installed and how you intend to use Routinator, which we'll cover below.
Routinator Installed From a Package
Setup When Installed From a Package
-----------------------------------
As explained in the :doc:`initialisation` section, the installation script
will run as the user *routinator* and refer to the configuration file
:file:`/etc/routinator/routinator.conf` which contains the following
pre-configured options:
The installation script will set up Routinator to run as the user
*routinator* and be configured to start at boot. Routinator will use the
configuration file :file:`/etc/routinator/routinator.conf` which contains the
following pre-configured options:
.. code-block:: toml
repository-dir = "/var/lib/routinator/rpki-cache"
tal-dir = "/var/lib/routinator/tals"
rtr-listen = ["127.0.0.1:3323"]
http-listen = ["127.0.0.1:8323"]
@ -57,7 +63,7 @@ make changes.
:doc:`user interface<user-interface>` or one of the
:doc:`HTTP endpoints<http-service>`.
Routinator Built with Cargo
Setup When Built with Cargo
---------------------------
If you have built Routinator using Cargo, you have made your own decisions
@ -65,9 +71,16 @@ with regards to the user that it runs as and the privileges it has. There is
no default configuration file, as it is your choice if you want to use one.
If you run Routinator without referring to a configuration file it will check
if there is a :file:`$HOME/.routinator.conf` file and if it exists, use it.
if the file :file:`$HOME/.routinator.conf` exists and if it does, use it.
If no configuration file is available, the default values are used.
You can specify the location of the RPKI cache directory using the
:option:`--repository-dir` option. If you don't, one will be created in the
default location :file:`$HOME/.rpki-cache/repository`. The :doc:`HTTP
service<http-service>` and :doc:`RTR service<rtr-service>` must be started
explicitly using the command line options :option:`--http` and
:option:`--rtr`, respectively, or via the configuration file.
You can view the default settings Routinator runs with using:
.. code-block:: text
@ -81,37 +94,124 @@ own:
.. code-block:: toml
allow-dubious-hosts = false
dirty = false
disable-rrdp = false
disable-rsync = false
exceptions = []
expire = 7200
history-size = 10
http-listen = []
log = "default"
log-level = "WARN"
max-object-size = 20000000
refresh = 600
repository-dir = "/Users/routinator/.rpki-cache/repository"
retry = 600
rrdp-fallback-time = 3600
rrdp-proxies = []
rrdp-root-certs = []
rsync-command = "rsync"
rsync-timeout = 300
rtr-client-metrics = false
rtr-listen = []
rtr-tcp-keepalive = 60
stale = "reject"
strict = false
syslog-facility = "daemon"
systemd-listen = false
tal-dir = "/Users/routinator/.rpki-cache/tals"
unknown-objects = "warn"
unsafe-vrps = "warn"
validation-threads = 4
allow-dubious-hosts = false
dirty = false
disable-rrdp = false
disable-rsync = false
enable-bgpsec = false
exceptions = []
expire = 7200
history-size = 10
http-listen = []
http-tls-listen = []
log = "default"
log-level = "WARN"
max-ca-depth = 32
max-object-size = 20000000
refresh = 600
repository-dir = "/Users/routinator/.rpki-cache/repository"
retry = 600
rrdp-fallback-time = 3600
rrdp-max-delta-count = 100
rrdp-proxies = []
rrdp-root-certs = []
rrdp-timeout = 300
rsync-command = "rsync"
rsync-timeout = 300
rtr-client-metrics = false
rtr-listen = []
rtr-tcp-keepalive = 60
rtr-tls-listen = []
stale = "reject"
strict = false
syslog-facility = "daemon"
systemd-listen = false
unknown-objects = "warn"
unsafe-vrps = "accept"
validation-threads = 10
Trust Anchor Locators
---------------------
Fetching data is done by connecting to the :term:`Trust Anchor Locators
(TALs) <Trust Anchor Locator (TAL)>` of the five Regional Internet Registries
(RIRs): AFRINIC, APNIC, ARIN, LACNIC and RIPE NCC. TALs provide hints for
the trust anchor certificates to be used both to discover and validate all
RPKI content. **By default, Routinator will be set up for use in production
environments and run with the production TALs of the five RIRs.**
Some RIRs and third parties also provide separate TALs for testing purposes,
allowing operators to gain experience with using RPKI in a safe environment.
Both the production and testbed TALs are bundled with Routinator and can be
enabled and disabled using command line and configuration file options.
Run the following command to list all available TALs:
.. code-block:: text
routinator --tal=list
This displays the following overview:
.. code-block:: text
.---- RIR TALs
| .- RIR test TALs
V V
X afrinic AFRINIC production TAL
X apnic APNIC production TAL
X arin ARIN production TAL
X lacnic LACNIC production TAL
X ripe RIPE production TAL
X apnic-testbed APNIC RPKI Testbed
X arin-ote ARIN Operational Test and Evaluation Environment
X ripe-pilot RIPE NCC RPKI Test Environment
nlnetlabs-testbed NLnet Labs RPKI Testbed
You can influence which TALs Routinator uses with the :option:`--tal` option,
which can be combined with the :option:`--no-rir-tals` option to leave out
all RIR production TALs, as well as the :option:`--extra-tals-dir` option to
specify a directory containing extra TALs to use.
For example, if you want to add the RIPE NCC RPKI Test Environment to the
default TAL set, run:
.. code-block:: text
routinator --tal=ripe-pilot
If you want to run Routinator without any of the production TALs and only
fetch data from the ARIN Operational Test and Evaluation Environment, run:
.. code-block:: text
routinator --no-rir-tals --tal=arin-ote
Lastly, if you would like to use a TAL that isn't bundled with Routinator you
can place it in a directory of your choice, for example
:file:`/var/lib/routinator/tals`, and refer to it by running:
.. code-block:: text
routinator --extra-tals-dir="/var/lib/routinator/tals"
Routinator will use all files in this directory with an extension of *.tal*
as TALs. These files need to be in the format described by :rfc:`8630`. Note
that Routinator will use all TALs provided. That means that if a TAL in this
directory is one of the bundled TALs, then these resources will be validated
twice.
.. versionadded:: 0.9.0
:option:`--list-tals`, :option:`--rir-tals`, :option:`--rir-test-tals`,
:option:`--tal` and :option:`--skip-tal`
.. deprecated:: 0.9.0
``--decline-arin-rpa``, use :option:`--skip-tal` instead
.. versionadded:: 0.12.0
:option:`--extra-tals-dir`
.. deprecated:: 0.12.0
The ``init`` subcommand, :option:`--list-tals`
Using Tmpfs for the RPKI Cache
------------------------------
@ -121,12 +221,6 @@ undesirable in your setup, you can choose to store the cache in volatile
memory using the `tmpfs file system
<https://www.kernel.org/doc/html/latest/filesystems/tmpfs.html>`_.
When setting this up, you should make sure to only put the directory for the
local RPKI cache in *tmpfs* and not the directory where the Trust Anchor
Locators reside. Both locations are set in the :ref:`configuration file
<manual-page:configuration file>` with the ``repository-dir`` and ``tal-dir``
options, respectively.
If you have installed Routinator using a package, by default the RPKI cache
directory will be :file:`/var/lib/routinator/rpki-cache`, so we'll use that
as an example. Note that the directory you choose must exist before the mount
@ -145,8 +239,99 @@ served to your routers.
Also keep in mind that every time you restart the machine, the contents of
the *tmpfs* file system will be lost. This means that Routinator will have to
rebuild its cache from scratch. This is not a problem, other than it having
to download several gigabytes of data, which usually takes about ten minutes
to complete. During this time all services will be unavailable.
to download several hundred megabytes of data, which usually takes about ten
minutes to complete. During this time all services will be unavailable.
Note that your routers should be configured to have a secondary relying party
instance available at all times.
Verifying Configuration
-----------------------
You should verify if Routinator has been configured correctly and your
firewall allows the required outbound connections on ports 443 and 873. From
a cold start, it will take ten to fifteen minutes to do the first validation
run that builds up the validated cache. Subsequent runs will be much faster,
because only the changes between the repositories and the validated cache
need to be processed.
If you have installed Routinator from a package and run it as a service, you
can check the status using:
.. code-block:: bash
sudo systemctl status routinator
And check the logs using:
.. code-block:: bash
sudo journalctl --unit=routinator
.. Important:: Because it is expected that the state of the entire RPKI is not
perfect at all times, you may see several warnings about objects
that are either stale or failed cryptographic verification, or
repositories that are temporarily unavailable.
If you have built Routinator using Cargo it is recommended to perform an
initial test run. You can do this by having Routinator print a validated ROA
payload (VRP) list with the :subcmd:`vrps` subcommand, and using :option:`-v`
twice to increase the :doc:`log level<logging>` to *debug*:
.. code-block:: bash
routinator -vv vrps
Now, you can see how Routinator connects to the RPKI trust anchors, downloads
the the contents of the repositories to your machine, verifies it and
produces a list of VRPs in the default CSV format to standard output.
.. code-block:: text
[INFO] Using the following TALs:
[INFO] * afrinic
[INFO] * apnic
[INFO] * arin
[INFO] * lacnic
[INFO] * ripe
[DEBUG] Found valid trust anchor https://rpki.ripe.net/ta/ripe-ncc-ta.cer. Processing.
[DEBUG] Found valid trust anchor https://rrdp.lacnic.net/ta/rta-lacnic-rpki.cer. Processing.
[DEBUG] Found valid trust anchor https://rpki.afrinic.net/repository/AfriNIC.cer. Processing.
[DEBUG] Found valid trust anchor https://rpki.apnic.net/repository/apnic-rpki-root-iana-origin.cer. Processing.
[DEBUG] Found valid trust anchor https://rrdp.arin.net/arin-rpki-ta.cer. Processing.
[DEBUG] RRDP https://rrdp.ripe.net/notification.xml: updating from snapshot.
[DEBUG] RRDP https://rrdp.lacnic.net/rrdp/notification.xml: updating from snapshot.
[DEBUG] RRDP https://rrdp.apnic.net/notification.xml: updating from snapshot.
[DEBUG] RRDP https://rrdp.afrinic.net/notification.xml: updating from snapshot.
[DEBUG] RRDP https://rrdp.arin.net/notification.xml: updating from snapshot.
[DEBUG] RRDP https://rrdp.apnic.net/notification.xml: snapshot update completed.
[DEBUG] RRDP https://rpki-rrdp.us-east-2.amazonaws.com/rrdp/08c2f264-23f9-49fb-9d43-f8b50bec9261/notification.xml: updating from snapshot.
[DEBUG] RRDP https://rpki-rrdp.us-east-2.amazonaws.com/rrdp/08c2f264-23f9-49fb-9d43-f8b50bec9261/notification.xml: snapshot update completed.
[DEBUG] RRDP https://rpki.akrn.net/rrdp/notification.xml: updating from snapshot.
[DEBUG] RRDP https://rpki.akrn.net/rrdp/notification.xml: snapshot update completed.
[DEBUG] RRDP https://rpki.admin.freerangecloud.com/rrdp/notification.xml: updating from snapshot.
[DEBUG] RRDP https://rpki.admin.freerangecloud.com/rrdp/notification.xml: snapshot update completed.
[DEBUG] RRDP https://rpki.cnnic.cn/rrdp/notify.xml: updating from snapshot.
[DEBUG] RRDP https://rrdp.ripe.net/notification.xml: snapshot update completed.
[DEBUG] RRDP https://0.sb/rrdp/notification.xml: updating from snapshot.
[DEBUG] RRDP https://0.sb/rrdp/notification.xml: snapshot update completed.
[DEBUG] RRDP https://rrdp.sub.apnic.net/notification.xml: updating from snapshot.
[DEBUG] RRDP https://rrdp.sub.apnic.net/notification.xml: snapshot update completed.
[DEBUG] RRDP https://rpki.roa.net/rrdp/notification.xml: updating from snapshot.
[DEBUG] RRDP https://rpki.roa.net/rrdp/notification.xml: snapshot update completed.
[DEBUG] RRDP https://rrdp.rp.ki/notification.xml: updating from snapshot.
[DEBUG] RRDP https://rpki.cnnic.cn/rrdp/notify.xml: snapshot update completed.
...
ASN,IP Prefix,Max Length,Trust Anchor
AS137884,103.116.116.0/23,23,apnic
AS9003,91.151.112.0/20,20,ripe
AS38553,120.72.19.0/24,24,apnic
AS58045,37.209.242.0/24,24,ripe
AS9583,202.177.175.0/24,24,apnic
AS50629,2a0f:ba80::/29,29,ripe
AS398085,2602:801:a008::/48,48,arin
AS21050,83.96.22.0/24,24,ripe
AS55577,183.82.223.0/24,24,apnic
AS44444,157.167.73.0/24,24,ripe
AS197695,194.67.97.0/24,24,ripe
...

View File

@ -59,7 +59,6 @@ Open-source with professional support services
installation
building
initialisation
configuration
.. toctree::

View File

@ -1,234 +0,0 @@
Initialisation
==============
Before running Routinator for the first time, you must prepare the working
environment. You do this using the :subcmd:`init` subcommand. This will create
the directory for the :term:`Trust Anchor Locator (TAL)` files and copy the
desired TALs into it, and create the directory for the local RPKI cache.
If you have installed Routinator using a package from our software package
repository, the application is configured to run as a system service with the
user *routinator*. We have included an initialisation script named
:program:`routinator-init` and pre-installed a :doc:`configuration
file<configuration>` located in ``/etc/routinator/routinator.conf`` to make the
setup process easy for you. The configuration is meant to prepare Routinator for
production environments, explicitly setting the TAL and RPKI cache directories
and enabling the HTTP and RTR servers on localhost.
The :program:`routinator-init` script invokes the :subcmd:`init` subcommand as
the user *routinator* and takes configuration file into consideration. All of
the options for the :subcmd:`init` subcommand can be appended to the
:program:`routinator-init` script, which are described below. If you have built
Routinator using Cargo you also have to perform the initialisation steps, but in
this case you invoke the :subcmd:`init` subcommand directly.
.. Important:: There is a subtle difference in the initialisation commands
depending on how you installed Routinator.
When installed using a package, you would for example enter:
.. code-block:: text
routinator-init --list-tals
When built using Cargo, you would use:
.. code-block:: text
routinator init --list-tals
Trust Anchor Locators
---------------------
Trust Anchor Locators (TALs) provide hints for the trust anchor certificates to
be used both to discover and validate all RPKI content. There are five TALs, one
for each Regional Internet Registry (RIR). For production environments these are
the only five you will ever need to fetch and validate all available RPKI data.
Some RIRs and third parties also provide separate TALs for testing purposes,
allowing operators to gain experience with using RPKI in a safe environment.
Both the production and testbed TALs are bundled with Routinator and can be
installed with the :subcmd:`init` subcommand.
To get an overview of all available TALs use the :option:`--list-tals` option:
.. code-block:: text
routinator init --list-tals
This displays the following overview:
.. code-block:: text
.---- --rir-tals
| .- --rir-test-tals
V V
X afrinic AFRINIC production TAL
X apnic APNIC production TAL
X arin ARIN production TAL
X lacnic LACNIC production TAL
X ripe RIPE production TAL
X apnic-testbed APNIC RPKI Testbed
X arin-ote ARIN Operational Test and Evaluation Environment
X ripe-pilot RIPE NCC RPKI Test Environment
nlnetlabs-testbed NLnet Labs RPKI Testbed
Preparing for Production Environments
"""""""""""""""""""""""""""""""""""""
.. Warning:: Using the TAL from ARIN requires you to read and accept their
`Relying Party Agreement
<https://www.arin.net/resources/manage/rpki/tal/>`_ before you can
use it. Running the :subcmd:`init` subcommand will provide you with
instructions.
By default, the repository and TAL directory will be created under
:file:`$HOME/.rpki-cache`. You can change their location using the
:option:`--repository-dir` and :option:`--tal-dir` options, or by using a
:doc:`configuration file<configuration>`.
In the most common scenario, you will want to install the TALs of the five RIRs.
To do this, run the following command:
.. code-block:: text
routinator init --rir-tals
This will return the following message:
.. code-block:: text
Before we can install the ARIN TAL, you must have read
and agree to the ARIN Relying Party Agreement (RPA).
It is available at
https://www.arin.net/resources/manage/rpki/rpa.pdf
If you agree to the RPA, please run the command
again with the --accept-arin-rpa option.
Running the :subcmd:`init` subcommand with the :option:`--accept-arin-rpa`
option added will create the repository and TAL directory and copy the five
Trust Anchor Locator files into it:
.. code-block:: bash
routinator init --rir-tals --accept-arin-rpa
If you built Routinator using Cargo and set up a :doc:`configuration
file<configuration>` before initialisation, make sure to refer to it using the
:option:`--config` option, e.g.:
.. code-block:: bash
routinator --config /home/routinator/routinator.conf init --rir-tals --accept-arin-rpa
If you decide you cannot agree to the ARIN RPA terms, you can use the
:option:`--skip-tal` option to exclude the TAL. If, at a later point, you wish
to include the ARIN TAL you can add it to your current installation using the
:option:`--force` option, to force the installation of all TALs.
Preparing for Test Environments
"""""""""""""""""""""""""""""""
To install all of the TALs for the various test environments, you can use the
:option:`--rir-test-tals` option. However, in most cases you will want to
install a specific one, using the :option:`--tal` option.
For example, to add the TAL for the `ARIN Operational Test and Evaluation
Environment <https://www.arin.net/reference/tools/testing/#rpki>`_ to an already
initialised Routinator, enter:
.. code-block:: bash
routinator init --force --tal arin-ote
.. versionadded:: 0.9.0
:option:`--list-tals`, :option:`--rir-tals`, :option:`--rir-test-tals`,
:option:`--tal` and :option:`--skip-tal`
.. deprecated:: 0.9.0
``--decline-arin-rpa``, use :option:`--skip-tal` instead
Verifying Initialisation
------------------------
You should verify if Routinator has been initialised correctly and your firewall
allows the required outbound connections on ports 443 and 873. From a cold
start, it will take ten to fifteen minutes to do the first validation run that
builds up the validated cache. Subsequent runs will be much faster, because only
the changes between the repositories and the validated cache need to be
processed.
If you have installed Routinator from a package and run it as a service, you can
check the status using:
.. code-block:: bash
sudo systemctl status routinator
And check the logs using:
.. code-block:: bash
sudo journalctl --unit=routinator
.. Important:: Because it is expected that the state of the entire RPKI is not
perfect as all times, you may see several warnings about objects
that are either stale or failed cryptographic verification, or
repositories that are temporarily unavailable.
If you have built Routinator using Cargo it is recommended to perform an
initial test run. You can do this by having Routinator print a validated ROA
payload (VRP) list with the :subcmd:`vrps` subcommand, and using :option:`-v`
twice to increase the :doc:`log level<logging>` to *debug*:
.. code-block:: bash
routinator -vv vrps
Now, you can see how Routinator connects to the RPKI trust anchors, downloads
the the contents of the repositories to your machine, verifies it and produces a
list of VRPs in the default CSV format to standard output.
.. code-block:: text
RRDP https://rrdp.ripe.net/notification.xml: Tree has 0 entries.
RRDP https://rrdp.ripe.net/notification.xml: updating from snapshot.
Found valid trust anchor https://rpki.afrinic.net/repository/AfriNIC.cer. Processing.
Found valid trust anchor https://rpki.apnic.net/repository/apnic-rpki-root-iana-origin.cer. Processing.
RRDP https://rrdp.afrinic.net/notification.xml: Tree has 0 entries.
RRDP https://rrdp.afrinic.net/notification.xml: updating from snapshot.
RRDP https://rrdp.apnic.net/notification.xml: Tree has 0 entries.
RRDP https://rrdp.apnic.net/notification.xml: updating from snapshot.
RRDP https://rrdp.afrinic.net/notification.xml: snapshot update completed.
Found valid trust anchor https://rrdp.arin.net/arin-rpki-ta.cer. Processing.
RRDP https://rrdp.arin.net/notification.xml: Tree has 0 entries.
RRDP https://rrdp.arin.net/notification.xml: updating from snapshot.
rsync://repository.lacnic.net/rpki/: successfully completed.
Found valid trust anchor https://rrdp.lacnic.net/ta/rta-lacnic-rpki.cer. Processing.
RRDP https://rrdp.lacnic.net/rrdp/notification.xml: Tree has 0 entries.
RRDP https://rrdp.lacnic.net/rrdp/notification.xml: updating from snapshot.
RRDP https://rrdp.arin.net/notification.xml: snapshot update completed.
RRDP https://rrdp.sub.apnic.net/notification.xml: Tree has 0 entries.
RRDP https://rrdp.sub.apnic.net/notification.xml: updating from snapshot.
RRDP https://rrdp.ripe.net/notification.xml: snapshot update completed.
RRDP https://rrdp.sub.apnic.net/notification.xml: snapshot update completed.
RRDP https://rpki-repo.registro.br/rrdp/notification.xml: Tree has 0 entries.
RRDP https://rpki-repo.registro.br/rrdp/notification.xml: updating from snapshot.
RRDP https://rrdp.twnic.tw/rrdp/notify.xml: Tree has 0 entries.
RRDP https://rrdp.twnic.tw/rrdp/notify.xml: updating from snapshot.
...
ASN,IP Prefix,Max Length,Trust Anchor
AS137884,103.116.116.0/23,23,apnic
AS9003,91.151.112.0/20,20,ripe
AS38553,120.72.19.0/24,24,apnic
AS58045,37.209.242.0/24,24,ripe
AS9583,202.177.175.0/24,24,apnic
AS50629,2a0f:ba80::/29,29,ripe
AS398085,2602:801:a008::/48,48,arin
AS21050,83.96.22.0/24,24,ripe
AS55577,183.82.223.0/24,24,apnic
AS44444,157.167.73.0/24,24,ripe
AS197695,194.67.97.0/24,24,ripe
...

View File

@ -8,15 +8,14 @@ Routinator has minimal system requirements. When choosing a system, a
powerful CPU is not required. Make sure you have 1GB of available memory and
4GB of disk space for the application.
Please keep in mind that the RPKI consists of a very large number of small
files. As a result, Routinator will use a large number of inodes. You should
Please keep in mind that the RPKI consists of a great number of small files.
As a result, Routinator will use a large amount of inodes. You should
accommodate for at least 500,000 inodes, but one million will provide more
breathing room. This will give you ample margin for the RPKI repositories to
grow over time, as adoption increases.
.. Tip:: A "No space left on device" error may be caused by running out of
inodes instead of disk space. To verify this, the ``df -i`` command
shows the amount of inodes available, used, and free.
.. Tip:: The ``df -i`` command shows the amount of inodes available, used,
and free.
As new RPKI repositories can emerge in any IP address range and on any domain
name, outbound traffic must not be blocked based on IP or DNS in any way.
@ -93,26 +92,11 @@ to get started.
sudo apt install routinator
Before running Routinator for the first time, you must prepare the
directory for the local RPKI cache, as well as the directory where the
:term:`Trust Anchor Locator (TAL)` files reside. After entering this
command, **follow the instructions** provided about the ARIN TAL:
.. code-block:: bash
sudo routinator-init
To learn more about this process refer to the :doc:`initialisation`
section. After successful initialisation you can enable Routinator
with:
.. code-block:: bash
sudo systemctl enable --now routinator
By default, Routinator will start the RTR server on port 3323 and the
HTTP server on port 8323. These, and other values can be changed in
the :doc:`configuration file<configuration>` located in
After installation Routinator will run immediately as the user
*routinator* and be configured to start at boot. By default, it will
run the RTR server on port 3323 and the HTTP server on port 8323.
These, and other values can be changed in the :doc:`configuration
file<configuration>` located in
:file:`/etc/routinator/routinator.conf`.
You can check the status of Routinator with:
@ -181,26 +165,11 @@ to get started.
sudo apt install routinator
Before running Routinator for the first time, you must prepare the
directory for the local RPKI cache, as well as the directory where the
:term:`Trust Anchor Locator (TAL)` files reside. After entering this
command, **follow the instructions** provided about the ARIN TAL:
.. code-block:: bash
sudo routinator-init
To learn more about this process refer to the :doc:`initialisation`
section. After successful initialisation you can enable Routinator
with:
.. code-block:: bash
sudo systemctl enable --now routinator
By default, Routinator will start the RTR server on port 3323 and the
HTTP server on port 8323. These, and other values can be changed in
the :doc:`configuration file<configuration>` located in
After installation Routinator will run immediately as the user
*routinator* and be configured to start at boot. By default, it will
run the RTR server on port 3323 and the HTTP server on port 8323.
These, and other values can be changed in the :doc:`configuration
file<configuration>` located in
:file:`/etc/routinator/routinator.conf`.
You can check the status of Routinator with:
@ -243,26 +212,11 @@ to get started.
sudo yum install -y routinator
Before running Routinator for the first time, you must prepare the
directory for the local RPKI cache, as well as the directory where the
:term:`Trust Anchor Locator (TAL)` files reside. After entering this
command, **follow the instructions** provided about the ARIN TAL:
.. code-block:: bash
sudo routinator-init
To learn more about this process refer to the :doc:`initialisation`
section. After successful initialisation you can enable Routinator
with:
.. code-block:: bash
sudo systemctl enable --now routinator
By default, Routinator will start the RTR server on port 3323 and the
HTTP server on port 8323. These, and other values can be changed in
the :doc:`configuration file<configuration>` located in
After installation Routinator will run immediately as the user
*routinator* and be configured to start at boot. By default, it will
run the RTR server on port 3323 and the HTTP server on port 8323.
These, and other values can be changed in the :doc:`configuration
file<configuration>` located in
:file:`/etc/routinator/routinator.conf`.
You can check the status of Routinator with:
@ -279,49 +233,48 @@ to get started.
.. group-tab:: Docker
Routinator Docker images are built with Alpine Linux for
``amd64``/``x86_64`` architecture.
Due to the impracticality of complying with terms and conditions in an
unsupervised Docker environment, it is necessary to first review and
agree to the `ARIN Relying Party Agreement (RPA)
<https://www.arin.net/resources/manage/rpki/tal/>`_. If you agree, you
can let the Routinator Docker image install the :term:`Trust Anchor
Locator (TAL)` files into a mounted volume that is later reused for
the server.
Routinator Docker images are built with Alpine Linux. The supported
CPU architectures are shown on the `Docker Hub Routinator page
<https://hub.docker.com/r/nlnetlabs/routinator/tags>`_ per Routinator
version (aka Docker "tag") in the ``OS/ARCH`` column.
First, create a Docker volume to persist the TAL files in:
To run Routinator as a background daemon with the default settings (RTR
server on port 3323 and HTTP server on port 8323) can be done like so:
.. code-block:: bash
sudo docker volume create routinator-tals
Then run a disposable container to install the TALs:
.. code-block:: bash
sudo docker run --rm -v routinator-tals:/home/routinator/.rpki-cache/tals \
nlnetlabs/routinator init -f --accept-arin-rpa
Finally, launch the detached container named *routinator*, exposing
the :term:`RPKI-to-Router (RPKI-RTR)` protocol on port 3323 and HTTP
on port 8323:
.. code-block:: bash
sudo docker run -d --restart=unless-stopped --name routinator -p 3323:3323 \
-p 8323:8323 -v routinator-tals:/home/routinator/.rpki-cache/tals \
nlnetlabs/routinator
sudo docker run -d --restart=unless-stopped --name routinator \
-p 3323:3323 \
-p 8323:8323 \
nlnetlabs/routinator
The Routinator container is known to run successfully run under
`gVisor <https://gvisor.dev/>`_ for additional isolation.
To adjust the configuration you can pass command line arguments to
Routinator (try :option:`--help` for more information) and/or supply your
own Routinator configuration file (by mapping it from the host into
the container using ``-v host/path/to/routinator.conf:/etc/routinator.conf``
and passing ``--config /etc/routinator.conf`` when running the container).
To persist the RPKI cache data you can create a separate Docker volume
and mount it into the container like so:
.. code-block:: bash
sudo docker volume create rpki-cache
sudo docker run <your usual arguments> \
-v rpki-cache:/home/routinator/.rpki-cache \
nlnetlabs/routinator
.. versionadded:: 0.9.0
RPM packages
.. versionadded:: 0.11.0
Debian packages for ``armhf`` and ``arm64`` architecture
.. versionadded:: 0.11.2
Ubuntu packages for Jammy 22.04 (LTS)
.. deprecated:: 0.12.0
``routinator-init`` and ``--accept-arin-rpa``
Updating
--------
@ -389,11 +342,14 @@ Updating
.. group-tab:: Docker
Upgrading to the latest version of Routinator can be done with:
Assuming that you run Docker with image `nlnetlabs/routinator`, upgrading
to the latest version can be done by running the following commands:
.. code-block:: text
docker run -it nlnetlabs/routinator:latest
sudo docker pull nlnetlabs/routinator
sudo docker rm --force routinator
sudo docker run <your usual arguments> nlnetlabs/routinator
Installing Specific Versions
----------------------------
@ -510,5 +466,5 @@ a specific version, if needed.
.. code-block:: text
docker run -it nlnetlabs/routinator:v0.9.0-rc2
sudo docker run <your usual arguments> nlnetlabs/routinator:v0.9.0-rc2

View File

@ -4,8 +4,6 @@ Manual Page
Synopsis
--------
:program:`routinator` [``options``] :subcmd:`init` [``init-options``]
:program:`routinator` [``options``] :subcmd:`vrps` [``vrps-options``] [:samp:`-o {output-file}`] [:samp:`-f {format}`]
:program:`routinator` [``options``] :subcmd:`validate` [``validate-options``] [:samp:`-a {asn}`] [:samp:`-p {prefix}`]
@ -49,15 +47,6 @@ The available options are:
See `CONFIGURATION FILE`_ below for more information on the format and
contents of the configuration file.
.. option:: -b dir, --base-dir=dir
Specifies the base directory to keep status information in. Unless
overwritten by the :option:`-r` or :option:`-t` options, the local
repository will be kept in the sub-directory :file:`repository` and the
TALs will be kept in the sub-directory :file:`tals`.
If omitted, the base directory defaults to :file:`$HOME/.rpki-cache`.
.. option:: -r dir, --repository-dir=dir
Specifies the directory to keep the local repository in. This is
@ -65,12 +54,43 @@ The available options are:
and thus is a copy of all the data referenced via the trust
anchors.
.. option:: -t dir, --tal-dir=dir
If omitted, defaults to :file:`$HOME/.rpki-cache/repository`.
Specifies the directory containing the trust anchor locators (TALs) to
use. Trust anchor locators are the starting points for collecting and
validating RPKI data. See `TRUST ANCHOR LOCATORS`_ for more information
on what should be present in this directory.
.. option:: --no-rir-tals
If present, Routinator will not use the bundled trust anchor locators
(TALs) of the five Regional Internet Registries (RIRs).
Trust anchor locators are the starting points for collecting and
validating RPKI data. Each of the five RIRs provides a TAL that adds
resources from their area. For normal production installations, these
are the only TALs that should be used.
Using this option as well as the :option:`--tal` and
:option:`--extra-tals-dir` options you can change which TALs
Routinator should use.
.. option:: --tal=name
Use the bundled TAL with the given name in addition to any other TAL.
Each RIR TAL is available through this option as well as TALs for a
few select test environments. If you use this option with the name
*list*, Routinator will print a list of all available bundled TALS and
exit.
The option can be given more than once.
.. option:: --extra-tals-dir=dir
Specifies a directory containing additional trust anchor locators
(TALs) to use. Routinator will use all files in this directory with
an extension of *.tal* as TALs. These files need to be in the format
described by :rfc:`8630`.
Note that Routinator will use all TALs provided. That means that if a
TAL in this directory is one of the bundled TALs, then these resources
will be validated twice.
.. option:: -x file, --exceptions=file
@ -385,52 +405,6 @@ Commands
Routinator provides a number of operations around the local RPKI repository.
These can be requested by providing different commands on the command line.
.. subcmd:: init
Prepares the local repository directories and the TAL directory for
running Routinator. Specifically, makes sure the local repository
directory exists, and creates the TAL directory and fills it with the
desired TALs.
For more information about TALs, see `TRUST ANCHOR LOCATORS`_ below.
.. option:: -f, --force
Forces installation of the TALs even if the TAL directory already
exists.
.. option:: --rir-tals
Selects the production TALs of the five RIRs for installation. If
no other TAL selection options are provided, this option is
assumed.
.. option:: --rir-test-tals
Selects the bundled TALs for RIR testbeds for installation.
.. option:: --tal=name
Selects the bundled TAL with the provided name for installation.
.. option:: --skip-tal=name
Deselects the bundled TAL with the given name.
.. option:: --list-tals
List all bundled TALs and exit. The list also shows which TALs are
selected by the :option:`--rir-tals` and :option:`--rir-test-tals`
options.
.. option:: --accept-arin-rpa
Before you can use the ARIN TAL, you need to agree to the ARIN
Relying Party Agreement (RPA). You can find it at
https://www.arin.net/resources/manage/rpki/rpa.pdf and explicitly
agree to it via this option. This explicit agreement is necessary
in order to install the ARIN TAL.
.. subcmd:: vrps
This command requests that Routinator update the local repository and
@ -707,8 +681,8 @@ These can be requested by providing different commands on the command line.
This command causes Routinator to act as a server for the
RPKI-to-Router (RTR) and HTTP protocols. In this mode, Routinator will
read all the TALs (See `TRUST ANCHOR LOCATORS`_ below) and will stay
attached to the terminal unless the :option:`-d` option is given.
read all the Trust Anchor Locators and will stay attached to the
terminal unless the :option:`-d` option is given.
The server will periodically update the local repository, every ten
minutes by default, notify any clients of changes, and let them fetch
@ -959,27 +933,6 @@ These can be requested by providing different commands on the command line.
the given file instead of displaying it. Use - to output the
manual page to standard output.
Trust Anchor Locators
---------------------
RPKI uses trust anchor locators, or TALs, to identify the location and public
keys of the trusted root CA certificates. Routinator keeps these TALs in
files in the TAL directory which can be set by the :option:`-t` option. If
the :option:`-b` option is used instead, the TAL directory will be in the
subdirectory *tals* under the directory specified in this option. The default
location, if no options are used at all is :file:`$HOME/.rpki-cache/tals`.
Routinator comes with a set of commonly used TALs that can be used to
populate the TAL directory via the init command. By default, the command will
install the TALs of the five Regional Internet Registries (RIRs) necessary
for the complete global RPKI repository.
If the directory does exist, Routinator will use all files with an extension
of *.tal* in this directory. This means that you can add and remove trust
anchors by adding and removing files in this directory. If you add files,
make sure they are in the format described by :rfc:`7730` or the upcoming
:rfc:`8630`.
Configuration File
------------------
@ -1003,9 +956,18 @@ All values can be overridden via the command line options.
A string containing the path to the directory to store the local
repository in. This entry is mandatory.
tal-dir
A string containing the path to the directory that contains the
Trust Anchor Locators. This entry is mandatory.
no-rir-tals
A boolean specifying whether the five RIR Trust Anchor Locators
(TALs) should not be added to the set of evaluated TALs. If
missing, the RIR TALs will be used.
tals
A list of strings, each containing the name of a bundled TAL to
be added to the set of TALs to be evaluated.
extra-tals-dir
A string containing the path to a directory that contains
additional TALs.
exceptions
A list of strings, each containing the path to a file with local

View File

@ -21,7 +21,13 @@
#
repository-dir = "..."
# Trust Anchor Locator (TAL) directory
# Do not use bundled RIR TALs.
#no-rir-tals = false
# Use additional bundled TALs.
#tals = [ "apnic-testbed", "nlnetlabs-testbed" ]
# Directory with additional TALs.
#
# All the files with the extension ".tal" in this directory are treated as
# trust anchor locators for RPKI validation.
@ -29,9 +35,7 @@ repository-dir = "..."
# A relative path is interpreted with respect to the directory this config
# lives in.
#
# This setting is mandatory.
#
tal-dir = "..."
#extra-tals-dir = "..."
# Local exceptions files
#

View File

@ -1,23 +1,20 @@
# Configuration for Running Routinator as a System Service
# ========================================================
#
# This configuration assumes that the TALs are placed in
# /var/lib/routinator/tals and the repository cache is maintained in
# This configuration assumes that the repository cache is maintained in
# /var/lib/routinator/rpki-cache.
#
# It will start Routinator with an RTR server listening on port 3323 and
# an HTTP server listening on port 8323. Both are limited to localhost by
# default.
#
# You can use this configuration as
# /etc/routinator/routinator.conf and start Routinator with
# --config /etc/routinator/routinator.conf.
# You can use this configuration as /etc/routinator/routinator.conf and
# start Routinator with --config /etc/routinator/routinator.conf.
#
# This file contains only the relevant configuration options. For a complete
# example, see etc/routinator.conf.example in the source distribution or
# consult the manual page.
repository-dir = "/var/lib/routinator/rpki-cache"
tal-dir = "/var/lib/routinator/tals"
rtr-listen = ["127.0.0.1:3323"]
http-listen = ["127.0.0.1:8323"]

View File

@ -1,21 +0,0 @@
#!/bin/bash
CMD="routinator --config /etc/routinator/routinator.conf init $@"
if [[ $EUID -eq $(id -u routinator) ]]; then
# We are the routinator user, go!
echo "Running command: $CMD"
$CMD
elif [[ $EUID -eq 0 ]]; then
# We are root, become routinator then go!
echo "Running command as user routinator: $CMD"
su -s /bin/sh -c "$CMD" routinator
else
# We are some other user, is sudo installed?
if command -v sudo &> /dev/null; then
echo "Running command as user routinator via sudo: $CMD"
sudo -u routinator $CMD
else
echo >&2 "Error: Unable to become user 'routinator' to run command: $CMD"
exit 1
fi
fi

View File

@ -1 +0,0 @@
disable routinator.service

View File

@ -30,7 +30,8 @@ if [ $1 -eq 1 ] ; then
# Ensure that the home directory has the correct permissions
chmod ${R_HOME_DIR_PERMS} ${R_HOME_DIR}
systemctl preset routinator.service 2>&1 || :
# Set the Routinator service to start now and on boot
systemctl enable --now routinator.service
fi
'''

View File

@ -23,10 +23,3 @@ target:
# exclude:
# - image: 'debian:bullseye'
# mode: 'upgrade-from-published'
exclude:
- image: 'ubuntu:jammy'
mode: 'upgrade-from-published'
- image: 'centos:7'
mode: 'upgrade-from-published' # disabled due to #773, until at least one version with #773 has been released
- image: 'centos:8'
mode: 'upgrade-from-published' # disabled due to #773, until at least one version with #773 has been released

View File

@ -6,7 +6,8 @@ set -x
case $1 in
post-install)
echo -e "\nROUTINATOR VERSION:"
routinator --version
VER=$(routinator --version)
echo $VER
echo -e "\nROUTINATOR CONF:"
cat /etc/routinator/routinator.conf
@ -14,37 +15,44 @@ case $1 in
echo -e "\nROUTINATOR DATA DIR:"
ls -la /var/lib/routinator
echo -e "\nROUTINATOR SERVICE STATUS BEFORE ENABLE:"
systemctl status routinator || true
# For newer Routinator init is no longer required and the Routinator service should be automatically enabled and
# started, for 0.11.3 and earlier init had to be done first and then the service manually enabled and started:
if [[ "$VER" == "Routinator 0.11.3" ]]; then
echo -e "\nROUTINATOR SERVICE STATUS BEFORE ENABLE:"
systemctl status routinator || true
echo -e "\nINIT ROUTINATOR:"
sudo routinator-init --accept-arin-rpa
echo -e "\nINIT ROUTINATOR:"
sudo routinator-init --accept-arin-rpa
echo -e "\nROUTINATOR DATA DIR AFTER INIT:"
ls -la /var/lib/routinator
echo -e "\nROUTINATOR DATA DIR AFTER INIT:"
ls -la /var/lib/routinator
echo -e "\nENABLE ROUTINATOR SERVICE:"
systemctl enable routinator
echo -e "\nENABLE ROUTINATOR SERVICE:"
systemctl enable routinator
echo -e "\nROUTINATOR SERVICE STATUS AFTER ENABLE:"
systemctl status routinator || true
echo -e "\nROUTINATOR SERVICE STATUS AFTER ENABLE:"
systemctl status routinator || true
echo -e "\nSTART ROUTINATOR SERVICE:"
systemctl start routinator
echo -e "\nROUTINATOR TALS DIR:"
ls -la /var/lib/routinator/tals/
fi
echo -e "\nROUTINATOR SERVICE SHOULD BE ENABLED:"
systemctl is-enabled --quiet routinator
echo -e "\nROUTINATOR SERVICE SHOULD BE ACTIVE:"
systemctl is-active --quiet routinator
echo -e "\nSTART ROUTINATOR SERVICE:"
systemctl start routinator
sleep 15s
echo -e "\nROUTINATOR LOGS AFTER START:"
journalctl --unit=routinator
echo -e "\nROUTINATOR SERVICE STATUS AFTER START:"
systemctl status routinator
echo -e "\nROUTINATOR MAN PAGE:"
man -P cat routinator
echo -e "\nROUTINATOR TALS DIR:"
ls -la /var/lib/routinator/tals/
echo -e "\nROUTINATOR MAN PAGE (first 20 lines only):"
man -P cat routinator | head -n 20 || true
echo -e "\nROUTINATOR RPKI CACHE DIR (first 20 lines of ls output only):"
ls -ltR /var/lib/routinator/rpki-cache/ | head -n 20 || true
@ -65,10 +73,15 @@ case $1 in
echo -e "\nROUTINATOR MAN PAGE:"
man -P cat routinator
echo -e "\nROUTINATOR TALS DIR:"
ls -la /var/lib/routinator/tals/
echo -e "\nOLD ROUTINATOR-INIT SCRIPT SHOULD NOT EXIST:"
if [ ! -f /usr/bin/routinator-init ]; then
echo "Confirmed that /usr/bin/routinator-init does not exist."
else
echo >&2 "ERROR: /usr/bin/routinator-init exists but should have been removed if it was present"
exit 1
fi
echo -e "\nROUTINATOR RPKI CACHE DIR (first 20 lines of ls output only):"
ls -ltR /var/lib/routinator/rpki-cache/ | head -n 20 || true
;;

View File

@ -2,11 +2,10 @@
//!
//! This is a private module. Its types are re-exported by the parent.
use std::{fs, io};
use std::collections::HashSet;
use std::path::Path;
use bytes::Bytes;
use log::{error, info};
use log::info;
use rpki::repository::tal::TalUri;
use rpki::uri;
use crate::config::{Config, FallbackPolicy};
@ -47,28 +46,11 @@ pub struct Collector {
impl Collector {
/// Initializes the collector without creating a value.
///
/// Ensures that the base directory exists. This will _not_ create the
/// base directory to ensure that `routinator init` has been run.
/// Ensures that the collectors directories exists and creates them if
/// necessary.
///
/// The function is called implicitly by [`new`][Self::new].
pub fn init(config: &Config) -> Result<(), Failed> {
if let Err(err) = fs::read_dir(&config.cache_dir) {
if err.kind() == io::ErrorKind::NotFound {
error!(
"Missing repository directory {}.\n\
You may have to initialize it via \
\'routinator init\'.",
config.cache_dir.display()
);
}
else {
error!(
"Failed to open repository directory {}: {}",
config.cache_dir.display(), err
);
}
return Err(Failed)
}
rrdp::Collector::init(config)?;
rsync::Collector::init(config)?;
Ok(())

View File

@ -6,7 +6,7 @@
//!
//! [`Config`]: struct.Config.html
use std::{env, fmt, fs};
use std::{env, fmt, fs, process};
use std::collections::HashMap;
use std::convert::{TryFrom, TryInto};
use std::io::Read;
@ -19,8 +19,9 @@ use clap::{
crate_version,
};
use dirs::home_dir;
use log::{LevelFilter, error};
use log::{LevelFilter, error, warn};
#[cfg(unix)] use syslog::Facility;
use crate::tals;
use crate::error::Failed;
@ -125,8 +126,14 @@ pub struct Config {
/// Path to the directory that contains the repository cache.
pub cache_dir: PathBuf,
/// Path to the directory that contains the trust anchor locators.
pub tal_dir: PathBuf,
/// Should we not use the RIR TALs?
pub no_rir_tals: bool,
/// Additional bundled TALs to use.
pub bundled_tals: Vec<String>,
/// Path to a directory that contains additional trust anchor locators.
pub extra_tals_dir: Option<PathBuf>,
/// Paths to the local exceptions files.
pub exceptions: Vec<PathBuf>,
@ -381,7 +388,6 @@ impl Config {
///
/// The path arguments in `matches` will be interpreted relative to
/// `cur_dir`.
#[allow(clippy::cognitive_complexity)]
fn apply_arg_matches(
&mut self,
matches: &ArgMatches,
@ -391,6 +397,14 @@ impl Config {
matches
).expect("bug in command line arguments parser");
// Quick check: If we have the entry "list" in bundled_tals, we
// are supposed to print the TALs and exit.
if let Some(tals) = args.bundled_tals.as_ref() {
if tals.iter().any(|tal| tal == "list") {
tals::print_tals();
process::exit(0);
}
}
// log_target - Goes first so we can move things out of args later.
self.apply_log_matches(&args, cur_dir)?;
@ -399,9 +413,6 @@ impl Config {
if let Some(dir) = args.repository_dir {
self.cache_dir = cur_dir.join(dir)
}
else if let Some(dir) = args.base_dir.as_ref() {
self.cache_dir = cur_dir.join(dir).join("repository")
}
if self.cache_dir == Path::new("") {
error!(
"Couldnt determine default repository directory: \
@ -411,22 +422,19 @@ impl Config {
return Err(Failed)
}
// tal_dir
if let Some(dir) = args.tal_dir {
self.tal_dir = cur_dir.join(dir)
// no_rir_tals
if args.no_rir_tals {
self.no_rir_tals = true
}
else if let Some(dir) = args.base_dir.as_ref() {
self.tal_dir = cur_dir.join(dir).join("tals")
}
if self.tal_dir == Path::new("") {
error!(
"Couldnt determine default TAL directory: \
no home directory.\n\
Please specify the repository directory with the -t option."
);
return Err(Failed)
// bundled_tals
if let Some(tals) = args.bundled_tals {
self.bundled_tals = tals;
}
// extra_tals_dir
self.extra_tals_dir = args.extra_tals_dir.map(|dir| cur_dir.join(dir));
// exceptions
if let Some(list) = args.exceptions {
self.exceptions = list.into_iter().map(|path| {
@ -834,7 +842,12 @@ impl Config {
let log_target = Self::log_target_from_config_file(&mut file)?;
let res = Config {
cache_dir: file.take_mandatory_path("repository-dir")?,
tal_dir: file.take_mandatory_path("tal-dir")?,
no_rir_tals: file.take_bool("no-rir-tals")?.unwrap_or(false),
bundled_tals: {
file.take_string_array("tals")?
.unwrap_or_default()
},
extra_tals_dir: file.take_path("extra-tals-dir")?,
exceptions: {
file.take_path_array("exceptions")?.unwrap_or_default()
},
@ -985,6 +998,13 @@ impl Config {
group: file.take_string("group")?,
tal_labels: file.take_string_map("tal-labels")?.unwrap_or_default(),
};
if file.take_path("tal-dir")?.is_some() {
warn!(
"Ignoring obsolete \"tal-dir\" option in config file {}.",
file.path.display()
);
}
file.check_exhausted()?;
Ok(res)
@ -1078,12 +1098,14 @@ impl Config {
/// Creates a default config with the given paths.
///
/// Uses default values for everything except for the cache and TAL
/// directories which are provided.
fn default_with_paths(cache_dir: PathBuf, tal_dir: PathBuf) -> Self {
/// Uses default values for everything except for the cache directory
/// which needs to be provided.
fn default_with_paths(cache_dir: PathBuf) -> Self {
Config {
cache_dir,
tal_dir,
no_rir_tals: false,
bundled_tals: Vec::new(),
extra_tals_dir: None,
exceptions: Vec::new(),
strict: DEFAULT_STRICT,
stale: DEFAULT_STALE_POLICY,
@ -1154,16 +1176,20 @@ impl Config {
return Err(Failed)
}
};
self.tal_dir = match self.tal_dir.strip_prefix(chroot) {
Ok(dir) => dir.into(),
Err(_) => {
error!(
"Fatal: TAL directory {} not under chroot {}.",
self.tal_dir.display(), chroot.display()
);
return Err(Failed)
}
};
if let Some(extra_tals_dir) = self.extra_tals_dir.take() {
self.extra_tals_dir = match extra_tals_dir.strip_prefix(
chroot
) {
Ok(dir) => Some(dir.into()),
Err(_) => {
error!(
"Fatal: TAL directory {} not under chroot {}.",
extra_tals_dir.display(), chroot.display()
);
return Err(Failed)
}
};
}
for item in &mut self.exceptions {
*item = match item.strip_prefix(chroot) {
Ok(path) => path.into(),
@ -1211,10 +1237,12 @@ impl Config {
"repository-dir".into(),
self.cache_dir.display().to_string().into()
);
res.insert(
"tal-dir".into(),
self.tal_dir.display().to_string().into()
);
if let Some(extra_tals_dir) = self.extra_tals_dir.as_ref() {
res.insert(
"extra-tals-dir".into(),
extra_tals_dir.display().to_string().into()
);
}
res.insert(
"exceptions".into(),
toml::Value::Array(
@ -1469,15 +1497,13 @@ impl Default for Config {
fn default() -> Self {
match home_dir() {
Some(dir) => {
let base = dir.join(".rpki-cache");
Config::default_with_paths(
base.join("repository"),
base.join("tals")
dir.join(".rpki-cache/repository"),
)
}
None => {
Config::default_with_paths(
PathBuf::from(""), PathBuf::from("")
PathBuf::from(""),
)
}
}
@ -1669,17 +1695,21 @@ struct GlobalArgs {
#[arg(short, long, value_name="PATH")]
config: Option<PathBuf>,
/// Sets the base directory for cache and TALs
#[arg(short, long, value_name="PATH")]
base_dir: Option<PathBuf>,
/// Sets the repository cache directory
#[arg(short, long, value_name="PATH")]
repository_dir: Option<PathBuf>,
/// Sets the TAL directory
#[arg(short, long, value_name="PATH")]
tal_dir: Option<PathBuf>,
/// Do not use the bundled RIR TALs
#[arg(long)]
no_rir_tals: bool,
/// Add an additional bundled TAL ("list" for a list)
#[arg(long = "tal", value_name="NAME")]
bundled_tals: Option<Vec<String>>,
/// A directory to load additional TALs from
#[arg(long, value_name="PATH")]
extra_tals_dir: Option<PathBuf>,
/// File with local exceptions (see RFC 8416 for format)
#[arg(short = 'x', long, value_name="PATH")]
@ -2568,10 +2598,7 @@ mod test {
config.cache_dir,
home_dir().unwrap().join(".rpki-cache").join("repository")
);
assert_eq!(
config.tal_dir,
home_dir().unwrap().join(".rpki-cache").join("tals")
);
assert!(config.extra_tals_dir.is_none());
assert!(config.exceptions.is_empty());
assert_eq!(config.strict, DEFAULT_STRICT);
assert_eq!(config.validation_threads, ::num_cpus::get());
@ -2591,7 +2618,7 @@ mod test {
fn good_config_file() {
let config = ConfigFile::parse(
"repository-dir = \"/repodir\"\n\
tal-dir = \"taldir\"\n\
extra-tals-dir = \"taldir\"\n\
exceptions = [\"ex1\", \"/ex2\"]\n\
strict = true\n\
validation-threads = 1000\n\
@ -2609,7 +2636,10 @@ mod test {
).unwrap();
let config = Config::from_config_file(config).unwrap();
assert_eq!(config.cache_dir.to_str().unwrap(), "/repodir");
assert_eq!(config.tal_dir.to_str().unwrap(), "/test/taldir");
assert_eq!(
config.extra_tals_dir.unwrap().to_str().unwrap(),
"/test/taldir"
);
assert_eq!(
config.exceptions,
vec![PathBuf::from("/test/ex1"), PathBuf::from("/ex2")]
@ -2644,12 +2674,14 @@ mod test {
fn minimal_config_file() {
let config = ConfigFile::parse(
"repository-dir = \"/repodir\"\n\
tal-dir = \"taldir\"",
extra-tals-dir = \"taldir\"",
Path::new("/test/routinator.conf")
).unwrap();
let config = Config::from_config_file(config).unwrap();
assert_eq!(config.cache_dir.to_str().unwrap(), "/repodir");
assert_eq!(config.tal_dir.to_str().unwrap(), "/test/taldir");
assert_eq!(
config.extra_tals_dir.unwrap().to_str().unwrap(), "/test/taldir"
);
assert!(config.exceptions.is_empty());
assert!(!config.strict);
assert_eq!(config.validation_threads, ::num_cpus::get());
@ -2668,24 +2700,6 @@ mod test {
);
}
#[test]
fn bad_config_file() {
let config = ConfigFile::parse(
"", Path::new("/test/routinator.conf")
).unwrap();
assert!(Config::from_config_file(config).is_err());
let config = ConfigFile::parse(
"repository-dir=\"bla\"",
Path::new("/test/routinator.conf")
).unwrap();
assert!(Config::from_config_file(config).is_err());
let config = ConfigFile::parse(
"tal-dir=\"bla\"",
Path::new("/test/routinator.conf")
).unwrap();
assert!(Config::from_config_file(config).is_err());
}
#[test]
fn read_your_own_config() {
let out_config = get_default_config();
@ -2701,13 +2715,12 @@ mod test {
#[cfg(unix)]
fn basic_args() {
let config = process_basic_args(&[
"routinator", "-r", "/repository", "-t", "tals",
"routinator", "-r", "/repository",
"-x", "/x1", "--exceptions", "x2", "--strict",
"--validation-threads", "2000",
"--syslog", "--syslog-facility", "auth"
]);
assert_eq!(config.cache_dir, Path::new("/repository"));
assert_eq!(config.tal_dir, Path::new("/test/tals"));
assert_eq!(
config.exceptions, [Path::new("/x1"), Path::new("/test/x2")]
);

View File

@ -18,7 +18,7 @@
/// the accompanying trait [`ProcessPubPoint`] dealing with individual
/// publication points.
use std::{fmt, fs, io};
use std::{fmt, fs};
use std::borrow::Cow;
use std::collections::HashMap;
use std::fs::File;
@ -39,7 +39,7 @@ use rpki::repository::sigobj::SignedObject;
use rpki::repository::tal::{Tal, TalInfo, TalUri};
use rpki::repository::x509::{Time, Validity};
use rpki::uri;
use crate::{collector, store};
use crate::{collector, store, tals};
use crate::config::{Config, FilterPolicy};
use crate::collector::Collector;
use crate::error::Failed;
@ -80,8 +80,11 @@ const CRL_CACHE_LIMIT: usize = 50;
/// drives the validation run.
#[derive(Debug)]
pub struct Engine {
/// The directory to load TALs from.
tal_dir: PathBuf,
/// A list of built-in TALs to use.
bundled_tals: Vec<Tal>,
/// An optional directory to load TALs from.
extra_tals_dir: Option<PathBuf>,
/// A mapping of TAL file names to TAL labels.
tal_labels: HashMap<String, String>,
@ -145,7 +148,8 @@ impl Engine {
};
let store = Store::new(config)?;
let mut res = Engine {
tal_dir: config.tal_dir.clone(),
bundled_tals: tals::collect_tals(config)?,
extra_tals_dir: config.extra_tals_dir.clone(),
tal_labels: config.tal_labels.clone(),
tals: Vec::new(),
collector,
@ -170,84 +174,79 @@ impl Engine {
/// It is not considered an error if there are no TAL files in the TAL
/// directory. However, a warning will be logged in this case.
pub fn reload_tals(&mut self) -> Result<(), Failed> {
let mut res = Vec::new();
let dir = match fs::read_dir(&self.tal_dir) {
Ok(dir) => dir,
Err(err) => {
if err.kind() == io::ErrorKind::NotFound {
error!(
"Missing TAL directory {}.\n\
You may have to initialize it via \
\'routinator init\'.",
self.tal_dir.display()
);
}
else {
error!("Failed to open TAL directory: {}.", err);
}
return Err(Failed)
}
};
for entry in dir {
let entry = match entry {
Ok(entry) => entry,
let mut res = self.bundled_tals.clone();
if let Some(extra_tals_dir) = self.extra_tals_dir.as_ref() {
let dir = match fs::read_dir(extra_tals_dir) {
Ok(dir) => dir,
Err(err) => {
error!(
"Failed to iterate over tal directory: {}",
err
error!("Failed to open TAL directory {}: {}.",
extra_tals_dir.display(), err
);
return Err(Failed)
}
};
for entry in dir {
let entry = match entry {
Ok(entry) => entry,
Err(err) => {
error!(
"Failed to iterate over tal directory: {}",
err
);
return Err(Failed)
}
};
if !entry.file_type().map(|ft| ft.is_file()).unwrap_or(false) {
continue
if !entry.file_type().map(|ft| ft.is_file()).unwrap_or(false) {
continue
}
let path = entry.path();
if path.extension().map(|ext| ext != "tal").unwrap_or(true) {
continue
}
let mut file = match File::open(&path) {
Ok(file) => {
file
}
Err(err) => {
error!(
"Failed to open TAL {}: {}. \n\
Aborting.",
path.display(), err
);
return Err(Failed)
}
};
let mut tal = match Tal::read_named(
self.path_to_tal_label(&path),
&mut file
) {
Ok(tal) => tal,
Err(err) => {
error!(
"Failed to read TAL {}: {}. \n\
Aborting.",
path.display(), err
);
return Err(Failed)
}
};
tal.prefer_https();
res.push(tal);
}
let path = entry.path();
if path.extension().map(|ext| ext != "tal").unwrap_or(true) {
continue
}
let mut file = match File::open(&path) {
Ok(file) => {
file
}
Err(err) => {
error!(
"Failed to open TAL {}: {}. \n\
Aborting.",
path.display(), err
);
return Err(Failed)
}
};
let mut tal = match Tal::read_named(
self.path_to_tal_label(&path),
&mut file
) {
Ok(tal) => tal,
Err(err) => {
error!(
"Failed to read TAL {}: {}. \n\
Aborting.",
path.display(), err
);
return Err(Failed)
}
};
tal.prefer_https();
res.push(tal);
}
if res.is_empty() {
warn!(
"No TALs found in TAL directory. Starting anyway."
"No TALs provided. Starting anyway."
);
}
res.sort_by(|left, right| {
left.info().name().cmp(right.info().name())
});
self.tals = res;
Ok(())
}
@ -285,6 +284,10 @@ impl Engine {
pub fn start<P: ProcessRun>(
&self, processor: P
) -> Result<Run<P>, Failed> {
info!("Using the following TALs:");
for tal in &self.tals {
info!(" * {}", tal.info().name());
}
Ok(Run::new(
self,
self.collector.as_ref().map(Collector::start),

View File

@ -12,7 +12,6 @@
#![allow(clippy::unnecessary_wraps)]
use std::{fs, io, thread};
use std::collections::HashSet;
use std::io::Write;
use std::path::{Path, PathBuf};
use std::process::Command;
@ -31,7 +30,7 @@ use rpki::rtr::server::NotifySender;
use tempfile::NamedTempFile;
use tokio::sync::oneshot;
#[cfg(feature = "rta")] use crate::rta;
use crate::{output, tals, validity};
use crate::{output, validity};
use crate::config::Config;
use crate::error::{ExitError, Failed};
use crate::http::http_listener;
@ -64,7 +63,6 @@ use crate::slurm::LocalExceptions;
/// [`from_arg_matches`]: #method.from_arg_matches
/// [`run`]: #method.run
pub enum Operation {
Init(Init),
Server(Server),
Vrps(Vrps),
Validate(Validate),
@ -86,7 +84,6 @@ impl Operation {
/// Adds the command configuration to a clap app.
pub fn config_args<'a: 'b, 'b>(app: clap::Command) -> clap::Command {
let app = Init::config_args(app);
let app = Server::config_args(app);
let app = Vrps::config_args(app);
let app = Validate::config_args(app);
@ -107,9 +104,6 @@ impl Operation {
config: &mut Config
) -> Result<Self, Failed> {
Ok(match matches.subcommand() {
Some(("init", matches)) => {
Operation::Init(Init::from_arg_matches(matches)?)
}
Some(("server", matches)) => {
Operation::Server(
Server::from_arg_matches(matches, cur_dir, config)?
@ -166,7 +160,6 @@ impl Operation {
pub fn run(self, config: Config) -> Result<(), ExitError> {
let process = Process::new(config);
match self {
Operation::Init(cmd) => cmd.run(process),
Operation::Server(cmd) => cmd.run(process),
Operation::Vrps(cmd) => cmd.run(process),
Operation::Validate(cmd) => cmd.run(process),
@ -181,292 +174,6 @@ impl Operation {
}
//------------ Init ----------------------------------------------------------
/// Initialize the local repository.
pub enum Init {
/// Only list TALs and exit.
ListTals,
/// Actually do an initialization.
Init {
/// Force installation of TALs.
///
/// If the TAL directory is present, we will not touch it unless this
/// flag is `true`.
force: bool,
/// The set of TALs to install.
tals: Vec<&'static tals::BundledTal>,
}
}
impl Init {
/// Adds the command configuration to a clap app.
pub fn config_args<'a: 'b, 'b>(app: clap::Command) -> clap::Command {
let mut cmd = clap::Command::new("init")
.about("Initializes the local repository")
.arg(Arg::new("force")
.short('f')
.long("force")
.action(ArgAction::SetTrue)
.help("Overwrite an existing TAL directory")
)
.arg(Arg::new("rir-tals")
.long("rir-tals")
.action(ArgAction::SetTrue)
.help("Install all RIR production TALs")
)
.arg(Arg::new("rir-test-tals")
.long("rir-test-tals")
.action(ArgAction::SetTrue)
.help("Install all RIR testbed TALs")
)
.arg(Arg::new("tal")
.long("tal")
.action(ArgAction::Append)
.help(
"Name a TAL to be installed \
(--list-tals shows available TALs)"
)
)
.arg(Arg::new("skip-tal")
.long("skip-tal")
.action(ArgAction::Append)
.help("Name a TAL not to be in installed")
)
.arg(Arg::new("decline-arin-rpa")
.long("decline-arin-rpa")
.action(ArgAction::SetTrue)
.help("Same as '--skip-tal arin' (deprecated)")
)
.arg(Arg::new("list-tals")
.long("list-tals")
.action(ArgAction::SetTrue)
.help("List available TALs and exit")
)
.after_help(
"If none of --rir-tals, --rir-test-tals, or --tal is \
given, assumes --rir-tals.\n
\n\
Additional global options are available. \
Please consult 'routinator --help' for those."
);
for tal in tals::BUNDLED_TALS {
if let Some(opt_in) = tal.opt_in.as_ref() {
cmd = cmd.arg(
Arg::new(opt_in.option_name)
.long(opt_in.option_name)
.action(ArgAction::SetTrue)
.help(opt_in.option_help)
);
}
}
app.subcommand(cmd)
}
/// Creates a command from clap matches.
pub fn from_arg_matches(
matches: &ArgMatches,
) -> Result<Self, Failed> {
// Easy out for --list-tals
if matches.get_flag("list-tals") {
return Ok(Init::ListTals)
}
// Collect the names of all requested TALs.
let mut requested: HashSet<_> = matches.get_many::<String>(
"tal"
).map(|tals| {
tals.cloned().collect()
}).unwrap_or_default();
if matches.get_flag("rir-test-tals") {
for tal in tals::BUNDLED_TALS {
if tal.category == tals::Category::RirTest {
requested.insert(tal.name.into());
}
}
}
// --rir-tals or lack of other TAL commands includes all RIR TALs.
if matches.get_flag("rir-tals") || requested.is_empty() {
for tal in tals::BUNDLED_TALS {
if tal.category == tals::Category::Production {
requested.insert(tal.name.into());
}
}
}
// Removed --skip-tal TALs.
if let Some(values) = matches.get_many::<String>("skip-tal") {
for tal in values {
// Be strict to avoid accidents.
if !requested.remove(tal) {
eprintln!("Attempt to skip non-included TAL '{}'", tal);
return Err(Failed)
}
}
}
// Remove ARIN Tal.
if matches.get_flag("decline-arin-rpa") {
eprintln!(
"Warning: '--decline-arin-rpa' has been replaced \
by '--skip-tal arin' and \n will be removed."
);
if !requested.remove("arin") {
eprintln!("Attempt to skip non-included TAL 'arin'");
return Err(Failed)
}
}
let mut tals = Vec::new();
for tal in tals::BUNDLED_TALS {
if !requested.remove(tal.name) {
continue
}
tals.push(tal);
if let Some(opt_in) = tal.opt_in.as_ref() {
if !matches.get_flag(opt_in.option_name) {
eprintln!("{}", opt_in.message);
return Err(Failed)
}
}
}
if !requested.is_empty() {
for name in requested {
eprintln!("Unknown TAL '{}'", name);
}
return Err(Failed)
}
Ok(Init::Init {
force: matches.get_flag("force"),
tals,
})
}
/// Initializes the local repository.
///
/// Tries to create `config.cache_dir` if it doesnt exist. Creates the
/// `config.tal_dir` if it doesnt exist and installs the bundled TALs.
/// It also does the latter if the directory exists and `force` is
/// `true`.
pub fn run(self, process: Process) -> Result<(), ExitError> {
let (force, tals) = match self {
Init::ListTals => {
Self::list_tals();
return Ok(())
}
Init::Init { force, tals } => (force, tals)
};
process.create_cache_dir()?;
// Check if TAL directory exists and error out if needed.
if let Ok(metadata) = fs::metadata(&process.config().tal_dir) {
if metadata.is_dir() {
if !force {
error!(
"TAL directory {} exists.\n\
Use -f to force installation of TALs.",
process.config().tal_dir.display()
);
return Err(Failed.into());
}
}
else {
error!(
"TAL directory {} exists and is not a directory.",
process.config().tal_dir.display()
);
return Err(Failed.into())
}
}
// Try to create the TAL directory and error out if that fails.
if let Err(err) = fs::create_dir_all(&process.config().tal_dir) {
error!(
"Cannot create TAL directory {}: {}",
process.config().tal_dir.display(), err
);
return Err(Failed.into())
}
// Now write all the TALs. Overwrite existing ones.
for tal in &tals {
Self::write_tal(&process.config().tal_dir, tal.name, tal.content)?;
}
// Not really an error, but thats our log level right now.
error!(
"Created local repository directory {}",
process.config().cache_dir.display()
);
error!(
"Installed {} TALs in {}",
tals.len(),
process.config().tal_dir.display()
);
Ok(())
}
/// Writes the given tal.
fn write_tal(
tal_dir: &Path,
name: &str,
content: &str,
) -> Result<(), Failed> {
let mut file = match fs::File::create(tal_dir.join(
format!("{}.tal", name)
)) {
Ok(file) => file,
Err(err) => {
error!(
"Can't create TAL file {}: {}.\n Aborting.",
tal_dir.join(name).display(), err
);
return Err(Failed);
}
};
if let Err(err) = file.write_all(content.as_ref()) {
error!(
"Can't create TAL file {}: {}.\n Aborting.",
tal_dir.join(name).display(), err
);
return Err(Failed);
}
Ok(())
}
/// Lists all the bundled TALs and exits.
fn list_tals() {
let max_len = tals::BUNDLED_TALS.iter().map(|tal|
tal.name.len()
).max().unwrap_or(0) + 2;
println!(" .---- --rir-tals");
println!(" | .- --rir-test-tals");
println!(" V V\n");
for tal in tals::BUNDLED_TALS {
match tal.category {
tals::Category::Production => print!(" X "),
tals::Category::RirTest => print!(" X "),
_ => print!(" "),
}
println!(
"{:width$} {}", tal.name, tal.description, width = max_len
);
}
}
}
//------------ Server --------------------------------------------------------
/// Run as server.

View File

@ -1,5 +1,83 @@
//! The TALs bundled with Routinator.
use std::collections::HashMap;
use log::error;
use rpki::repository::tal::Tal;
use crate::config::Config;
use crate::error::Failed;
//------------ collect_tals --------------------------------------------------
/// Produces the set of bundled TALs to use from config.
pub fn collect_tals(config: &Config) -> Result<Vec<Tal>, Failed> {
let mut res = HashMap::new();
// Add all explicitely mentioned TALs.
for name in &config.bundled_tals {
let mut added = false;
for tal in BUNDLED_TALS {
if tal.name == name {
if !res.contains_key(tal.name) {
res.insert(tal.name.to_string(), tal.to_tal());
}
added = true;
break;
}
}
if !added {
error!("Unknown TAL '{}' in --tal option", name);
return Err(Failed)
}
}
// Add all the RIR TALs unless specifically disabled.
//
// (We are doing this second because it cannot ever fail.)
if !config.no_rir_tals {
for tal in BUNDLED_TALS {
if
tal.category == Category::Production
&& !res.contains_key(tal.name)
{
res.insert(tal.name.to_string(), tal.to_tal());
}
}
}
for tal in res.values_mut() {
tal.prefer_https()
}
Ok(res.into_values().collect())
}
//------------ print_tals ----------------------------------------------------
/// Prints all the bundled TALs to stdout.
pub fn print_tals() {
let max_len = BUNDLED_TALS.iter().map(|tal|
tal.name.len()
).max().unwrap_or(0) + 2;
println!(" .---- RIR TALs");
println!(" | .- RIR test TALs");
println!(" V V\n");
for tal in BUNDLED_TALS {
match tal.category {
Category::Production => print!(" X "),
Category::RirTest => print!(" X "),
_ => print!(" "),
}
println!(
"{:width$} {}", tal.name, tal.description, width = max_len
);
}
}
//------------ BundledTal ----------------------------------------------------
@ -14,26 +92,16 @@ pub struct BundledTal {
/// The category of the TAL.
pub category: Category,
/// Does this TAL need explicit opt-in and if so, how is it to be done?
pub opt_in: Option<OptIn>,
/// The actual content of the TAL.
pub content: &'static str,
}
//------------ OptIn ---------------------------------------------------------
/// Information about performing the opt-in procedure for some TALs.
pub struct OptIn {
/// The command line option for explicitely opting in.
pub option_name: &'static str,
/// The help text for the command line option.
pub option_help: &'static str,
/// The text to show when opt-in is missing.
pub message: &'static str,
impl BundledTal {
fn to_tal(&self) -> Tal {
Tal::read_named(
self.name.into(), &mut self.content.as_bytes()
).expect("bundled broken TAL")
}
}
@ -67,49 +135,30 @@ pub static BUNDLED_TALS: &[BundledTal] = &[
name: "afrinic",
description: "AFRINIC production TAL",
category: Category::Production,
opt_in: None,
content: include_str!("../tals/afrinic.tal"),
},
BundledTal {
name: "apnic",
description: "APNIC production TAL",
category: Category::Production,
opt_in: None,
content: include_str!("../tals/apnic.tal"),
},
BundledTal {
name: "arin",
description: "ARIN production TAL",
category: Category::Production,
opt_in: Some(OptIn {
option_name: "accept-arin-rpa",
option_help:
"You have read and accept \
https://www.arin.net/resources/manage/rpki/rpa.pdf",
message:
"Before we can install the ARIN TAL, you must have read\n\
and agree to the ARIN Relying Party Agreement (RPA).\n\
It is available at\n\
\n\
https://www.arin.net/resources/manage/rpki/rpa.pdf\n\
\n\
If you agree to the RPA, please run the command\n\
again with the --accept-arin-rpa option."
}),
content: include_str!("../tals/arin.tal"),
},
BundledTal {
name: "lacnic",
description: "LACNIC production TAL",
category: Category::Production,
opt_in: None,
content: include_str!("../tals/lacnic.tal"),
},
BundledTal {
name: "ripe",
description: "RIPE production TAL",
category: Category::Production,
opt_in: None,
content: include_str!("../tals/ripe.tal"),
},
@ -118,21 +167,18 @@ pub static BUNDLED_TALS: &[BundledTal] = &[
name: "apnic-testbed",
description: "APNIC RPKI Testbed",
category: Category::RirTest,
opt_in: None,
content: include_str!("../tals/apnic-testbed.tal"),
},
BundledTal {
name: "arin-ote",
description: "ARIN Operational Test and Evaluation Environment",
category: Category::RirTest,
opt_in: None,
content: include_str!("../tals/arin-ote.tal"),
},
BundledTal {
name: "ripe-pilot",
description: "RIPE NCC RPKI Test Environment",
category: Category::RirTest,
opt_in: None,
content: include_str!("../tals/ripe-pilot.tal"),
},
@ -141,7 +187,6 @@ pub static BUNDLED_TALS: &[BundledTal] = &[
name: "nlnetlabs-testbed",
description: "NLnet Labs RPKI Testbed",
category: Category::Test,
opt_in: None,
content: include_str!("../tals/nlnetlabs-testbed.tal"),
}
];

View File

@ -1,13 +1,10 @@
Trust Anchor Locators
=====================
This directory contains the trust anchor locators (TALs) of the five
Regional Internet Registries (RIRs) that are bundled with Routinator
and are necessary for RPKI validation.
This directory contains the trust anchor locators (TALs) that are bundled
with Routinator. These are the TALs of the five Regional Internet Registries
(RIRs) as well as those for a number of test setups.
Please be aware that you can only use the ARIN TAL (in file `arin.tal`)
if you agree to the [ARIN Relying Party Agreement (PDF)]. This TAL has been
included in Routinator with permission by ARIN provided we gain agreement
to the RPA before installation or use.
For more information, please refer to `src/tals.rs` which is the canonical
place to describe and categorize them.
[ARIN Relying Party Agreement (PDF)]: https://www.arin.net/resources/manage/rpki/rpa.pdf