rcynic
is the core RPKI relying party tool, and is the code which performs
the actual RPKI validation. Most of the other relying party tools just use
rcynic
's output.
The name is short for "cynical rsync", because rcynic
's task involves an
interleaved process of rsync
retrieval and RPKI validation.
This code was developed on FreeBSD, and has been tested most heavily on
FreeBSD versions 6-STABLE through 8-STABLE. It is also known to work on Ubuntu
(12.04 LTS), Debian (Wheezy) and Mac OS X (Snow Leopard). In theory it should
run on any reasonably POSIX-like system. As far as we know, rcynic
does not
use any seriously non-portable features, but neither have we done a POSIX
reference manual lookup for every function call. Please report any portability
problems.
rcynic
has a lot of options, but it attempts to choose reasonable defaults
where possible. The installation process will create a basic working rcynic
configuration for you and arrange for this to run hourly under cron. If all
goes well, this should "just work".
rcynic
has the ability to do all of its work in a chroot jail. This used to
be the default configuration, but integrating this properly with platform-
specific packaging systems (FreeBSD ports, apt-get
on Ubuntu and Debian,
etc) proved impractical. You can still get this behavior if you need it, by
installing from source and using the --enable-rcynic-jail
option to
./configure
.
The default configuration set up by make install
and the various packaging
systems will run rcynic
under cron
using the rcynic-cron
wrapper script.
See the instructions for setting up your own cron jobs if you need something
more complicated; also see the instructions for setting up hierarchical rsync
if you need to build a complex topology of rcynic validators.
rcynic
depends heavily on the OpenSSL libcrypto
library, and requires a
reasonably current version of OpenSSL with both RFC 3779 and CMS support.
rcynic
expects all certificates, CRLs, and CMS objects to be in DER format.
rcynic
stores its database using filenames derived from the RPKI rsync URIs
at which the data are published.
All configuration is via an OpenSSL-style configuration file, except for
selection of the name of the configuration file itself. A few other parameters
can also be set from the command line. The default name for the configuration
is "rcynic.conf
"; you can override this with the -c
option on the command
line. The configuration file uses OpenSSL's configuration file syntax, and you
can set OpenSSL library configuration paramaters (eg, "engine" settings) in
the config file as well. rcynic
's own configuration parameters are in a
section called "[rcynic]
".
Most configuration parameters are optional and have defaults which should do
something reasonable if you are running rcynic
in a test directory. If
you're running rcynic as a system program, perhaps under cron
via the
rcynic-cron
script, you'll want to set additional parameters to tell
rcynic
where to find its data and where to write its output (the
installation process sets these parameters for you). The configuration file
itself, however, is not optional. In order for rcynic
to do anything useful,
your configuration file MUST at minimum tell rcynic
where to find one or
more RPKI trust anchors or trust anchor locators (TALs).
- To specify a trust anchor, use the
trust-anchor
directive to name the local file containing the trust anchor.
- To specify a trust anchor locator (TAL), use the
trust-anchor-locator
directive to name a local file containing the trust anchor locator.
- To specify a directory containing trust anchors or trust anchor locators, use the
trust-anchor-directory
directive to name the directory. Files in the specified directory with names ending in ".cer"
will be processed as trust anchors, while files with names ending in ".tal"
will be processed as trust anchor locators.
You may use a combination of these methods if necessary.
Trust anchors are represented as DER-formatted X.509 self-signed certificate
objects, but in practice trust anchor locators are more common, as they reduce
the amount of locally configured data to the bare minimum and allow the trust
anchor itself to be updated without requiring reconfiguration of validators
like rcynic. A trust anchor locator is a file in the format specified in
RFC-6490, consisting of the rsync
URI of the trust anchor followed by the Base64 encoding of the trust anchor's
public key.
Strictly speaking, trust anchors do not need to be self-signed, but many
programs (including OpenSSL) assume that trust anchors will be self-signed.
See the allow-non-self-signed-trust-anchor
configuration option if you need
to use a non-self-signed trust anchor, but be warned that the results, while
technically correct, may not be useful.
See the make-tal.sh
script in this directory if you need to generate your
own TAL file for a trust anchor.
As of this writing, there still is no single global trust anchor for the RPKI
system, so you have to provide separate trust anchors for each Regional
Internet Registry (RIR) which is publishing RPKI data. The installation
process installs the ones it knows about.
Example of a minimal config file specifying nothing but trust anchor locators:
[rcynic]
trust-anchor-locator.0 = trust-anchors/apnic.tal
trust-anchor-locator.1 = trust-anchors/ripe.tal
trust-anchor-locator.2 = trust-anchors/afrinic.tal
trust-anchor-locator.3 = trust-anchors/lacnic.tal
Eventually, this should all be collapsed into a single trust anchor, so that
relying parties don't need to sort this out on their own, at which point the
above configuration could become something like:
[rcynic]
trust-anchor-locator = trust-anchors/iana.tal
By default, rcynic
uses two writable directory trees:
unauthenticated
::
Raw data fetched via rsync
. In order to take full advantage of rsync
's
optimized transfers, you should preserve and reuse this directory across
rcynic
runs, so that rcynic
need not re-fetch data that have not changed.
authenticated
::
Data which rcynic
has checked. This is the real output of the validation
process.
authenticated
is really a symbolic link to a directory with a name of the
form "authenticated
.<timestamp>", where <timestamp> is an
ISO 8601 timestamp like 2001-04-01T01:23:45Z
. rcynic
creates a new
timestamped directory every time it runs, and moves the symbolic link as an
atomic operation when the validation process completes. The intent is that
authenticated
always points to the most recent usable validation results, so
that programs which use rcynic
's output don't need to worry about whether an
rcynic
run is in progress.
rcynic
installs trust anchors specified via the trust-anchor-locator
directive in the unauthenticated
tree just like any other fetched object,
and copies them into the authenticated
trees just like any other object once
they pass rcynic
's checks.
rcynic
copies trust anchors specified via the trust-anchor
directive into
the top level directory of the authenticated
tree with filenames of the form
<xxxxxxxx>.
<n>.cer
, where <xxxxxxxx> and
<n> are the OpenSSL object name hash and index within the resulting
virtual hash bucket, respectively. These are the same values that OpenSSL's
c_hash
Perl script would produce. The reason for this naming scheme is that
these trust anchors, by definition, are not fetched automatically, and thus do
not really have publication URIs in the sense that every other object in these
trees do. So rcynic
uses a naming scheme which insures:
- that each trust anchor has a unique name within the output tree and
- that trust anchors cannot be confused with certificates: trust anchors always go in the top level of the tree, data fetched via rsync always go in subdirectories.
Trust anchors and trust anchor locators taken from the directory named by the
trust-anchor-directory
directive will follow the same naming scheme trust
anchors and trust anchor locators specified via the trust-anchor
and trust-
anchor-locator
directives, respectively.
rcynic
has its own system of logging levels, similar to what syslog()
uses, but customized to the specific task rcynic
performs.
log_sys_err |
Error from operating system or library |
log_usage_err |
Bad usage (local configuration error) |
log_data_err |
Bad data (broken certificates or CRLs) |
log_telemetry |
Normal chatter about rcynic's progress |
log_verbose |
Extra verbose chatter |
log_debug |
Only useful when debugging |
-c configfile |
Path to configuration file (default: rcynic.conf ) |
-l loglevel |
Logging level (default: log_data_err ) |
-s |
Log via syslog |
-e |
Log via stderr when also using syslog |
-j |
Start-up jitter interval (see below; default: 600 ) |
-V |
Print rcynic's version to standard output and exit |
-x |
Path to XML "summary" file (see below; no default) |
rcynic
uses the OpenSSL libcrypto
configuration file mechanism. All
libcrypto
configuration options (eg, for engine support) are available. All
rcynic
-specific options are in the "[rcynic]
" section. You MUST have a
configuration file in order for rcynic
to do anything useful, as the
configuration file is the only way to list your trust anchors.
Path to output directory (where rcynic
should place objects it has been able
to validate).
Default: rcynic-data/authenticated
Path to directory where rcynic
should store unauthenticatd data retrieved
via rsync
. Unless something goes horribly wrong, you want rcynic
to
preserve and reuse this directory across runs to minimize the network traffic
necessary to bring your repository mirror up to date.
Default: rcynic-data/unauthenticated
How long (in seconds) to let rsync
run before terminating the rsync
process, or zero for no timeout. You want this timeout to be fairly long, to
avoid terminating rsync
connections prematurely. It's present to let you
defend against evil rsync
server operators who try to tarpit your connection
as a form of denial of service attack on rcynic
.
Default: 300
Upper limit on the number of copies of rsync
that rcynic
is allowed to run
at once. Used properly, this can speed up synchronization considerably when
fetching from repositories built with sub-optimal tree layouts or when dealing
with unreachable repositories. Used improperly, this option can generate
excessive load on repositories, cause synchronization to be interrupted by
firewalls, and generally creates create a public nuisance. Use with caution.
As of this writing, values in the range 2-4 are reasonably safe. Values above
10 have been known to cause problems.
rcynic
can't really detect all of the possible problems created by excessive
values of this parameter, but if rcynic's report shows that both successful
retrivial and skipped retrieval from the same repository host, that's a pretty
good hint that something is wrong, and an excessive value here is a good first
guess as to the cause.
Default: 1
Path to the rsync program.
Default: rsync
, but you should probably set this variable rather than just
trusting the PATH
environment variable to be set correctly.
Same as -l
option on command line. Command line setting overrides config
file setting.
Default: log_log_err
Same as -s
option on command line. Command line setting overrides config
file setting.
Values: true
or false
.
Default: false
Same as -e option on command line. Command line setting overrides config file
setting.
Values: true
or false
.
Default: false
, but if neither use-syslog
nor use-stderr
is set, log
output goes to stderr
.
Syslog facility to use.
Default: local0
(where xyz is an rcynic logging level, above)
Override the syslog priority value to use when logging messages at this rcynic
level.
Defaults:
syslog-priority-log_sys_err |
err |
syslog-priority-log_usage_err |
err |
syslog-priority-log_data_err |
notice |
syslog-priority-log_telemetry |
info |
syslog-priority-log_verbose |
info |
syslog-priority-log_debug |
debug |
Startup jitter interval, same as -j
option on command line. Jitter interval,
specified in number of seconds. rcynic
will pick a random number within the
interval from zero to this value, and will delay for that many seconds on
startup. The purpose of this is to spread the load from large numbers of
rcynic
clients all running under cron with synchronized clocks, in
particular to avoid hammering the global RPKI rsync
servers into the ground
at midnight UTC.
Default: 600
Name of lockfile, or empty for no lock. If you run rcynic
directly under
cron, you should use this parameter to set a lockfile so that successive
instances of rcynic don't stomp on each other. If you run rcynic
under
rcynic-cron
, you don't need to touch this, as rcynic-cron
maintains its
own lock.
Default: no lock
Enable output of a per-host summary at the end of an rcynic
run in XML
format.
Value: filename to which XML summary should be written; "-" will send XML
summary to standard output.
Default: no XML summary.
Allow use of CRLs which are past their nextUpdate
timestamp. This is usually
harmless, but since there are attack scenarios in which this is the first
warning of trouble, it's configurable.
Values: true
or false
.
Default: true
Clean up old files corresponding to URIs that rcynic
did not see at all
during this run. rcynic
invokes rsync
with the --delete
option to clean
up old objects from collections that rcynic
revisits, but if a URI changes
so that rcynic
never visits the old collection again, old files will remain
in the local mirror indefinitely unless you enable this option.
Note: Pruning only happens when run-rsync
is true. When the run-rsync
option is false, pruning is not done regardless of the setting of the prune
option option.
Values: true
or false
.
Default: true
Allow use of manifests which are past their nextUpdate
timestamp. This is
probably harmless, but since it may be an early warning of problems, it's
configurable.
Values: true
or false
.
Default: true
Reject publication point if manifest doesn't list the CRL that covers the
manifest EE certificate.
Values: true
or false
.
Default: false
Allow use of otherwise valid objects which are not listed in the manifest.
This is not supposed to happen, but is probably harmless.
Enabling this does, however, often result in noisier logs, as it increases the
chance that rcynic
will attempt to validate data which a CA removed from the
manifest but did not completely remove and revoke from the repository.
Values: true
or false
Default: false
Allow use of otherwise valid objects which are listed in the manifest with a
different digest value.
You probably don't want to touch this.
Values: true
or false
Default: true
Allow processing to continue on a publication point whose manifest lists a
different digest value for the CRL than the digest of the CRL we have in hand.
You probably don't want to touch this.
Values: true
or false
Default: true
Experimental. Attempts to work around OpenSSL's strong preference for self-
signed trust anchors.
We're not going to explain this one in any further detail. If you really want
to know what it does, Use The Source, Luke.
Do not even consider enabling this option unless you are intimately familiar with both X.509 and the internals of OpenSSL's X509_verify_cert()
function and really know what you are doing.
Values: true
or false
.
Default: false
Whether to run rsync
to fetch data. You don't generally want to change this
except when building complex topologies where rcynic
running on one set of
machines acts as aggregators for another set of validators. A large ISP might
want to build such a topology so that they could have a local validation cache
in each POP while minimizing load on the global repository system and
maintaining some degree of internal consistency between POPs. In such cases,
one might want the rcynic
instances in the POPs to validate data fetched
from the aggregators via an external process, without the POP rcynic
instances attempting to fetch anything themselves.
Values: true
or false
.
Default: true
Whether to use hard links rather than copying valid objects from the
unauthenticated to authenticated tree. Using links is slightly more fragile
(anything that stomps on the unauthenticated file also stomps on the
authenticated file) but is a bit faster and reduces the number of inodes
consumed by a large data collection. At the moment, copying is the default
behavior, but this may change in the future.
Values: true
or false
.
Default: false
Whether to force rsync
to run even when we have a valid manifest for a
particular publication point and its nextUpdate
time has not yet passed.
This is an experimental feature, and currently defaults to true, which is
the old behavior (running rsync
regardless of whether we have a valid cached
manifest). This default may change once we have more experience with
rcynic
's behavior when run with this option set to false
.
Skipping the rsync
fetch when we already have a valid cached manifest can
significantly reduce the total number of rsync
connections we need to make,
and significantly reduce the load that each validator places on the
authoritative publication servers. As with any caching scheme, however, there
are some potential problems involved with not fetching the latest data, and we
don't yet have enough experience with this option to know how this will play
out in practice, which is why this is still considered experimental.
Values: true
or false
Default: true
(but may change in the future)
Specify one RPKI trust anchor, represented as a local file containing an X.509
certificate in DER format. Value of this option is the pathname of the file.
No default.
Specify one RPKI trust anchor locator, represented as a local file in the
format specified in RFC-6490.
This a simple text format containing an rsync URI and the RSA public key of
the X.509 object specified by the URI; the first line of the file is the URI,
the remainder is the public key in Base64 encoded DER format.
Value of this option is the pathname of the file.
No default.
Specify a directory containing trust anchors, trust anchor locators, or both.
Trust anchors in such a directory must have filenames ending in ".cer
";
trust anchor locators in such a directory must have names ending in ".tal
";
any other files will be skipped.
This directive is an alternative to using the trust-anchor
and trust-anchor-
locator` directives. This is probably easier to use than the other trust
anchor directives when dealing with a collection of trust anchors. This may
change on that promised day when we have only a single global trust anchor to
deal with, but we're not there yet.
No default.
The distribution includes several post-processors for the XML output rcynic
writes describing the actions it has taken and the validation status of the
objects it has found.
rcynic-html
converts rcynic
's XML output into a collection of HTML pages
summarizing the results, noting problems encountered, and showing some history
of rsync
transfer times and repository object counts in graphical form.
rcynic-cron
runs rcynic-html
automatically, immediately after running
rcynic
. If for some reason you need to run rcynic-html
by hand, the
command syntax is:
$ rcynic-html rcynic.xml /web/server/directory/
rcynic-html
will write a collection of HTML and image files to the specified
output directory, along with a set of RRD databases. rcynic-html
will create
the output directory if necessary.
rcynic-html
requires rrdtool
, a specialized
database and graphing engine designed for this sort of work. You can run
rcynic-html
without rrdtool
by giving it the --no-show-graphs
option,
but the result won't be as useful.
rcynic-html
gets its idea of where to find the rrdtool
program from
autoconf, which usually works. If for some reason it doesn't work in your
environment, you will need to tell rcynic-html
where to find rrdtool
,
using the --rrdtool-binary
option:
$ rcynic-html --rrdtoolbinary /some/where/rrdtool rcynic.xml /web/server/directory/
rcynic.xsl
was an earlier attempt at the same kind of HTML output as rcynic-
html generates. XSLT was a convenient language for our initial attempts at
this, but as the processing involved got more complex, it became obvious that
we needed a general purpose programming language.
If for some reason XSLT works better in your environment than Python, you
might find this stylesheet to be a useful starting point, but be warned that
it's significantly slower than rcynic-html
, lacks many features, and is no
longer under development.
rcynic-text
provides a quick flat text summary of validation results. This
is useful primarily in test scripts (smoketest uses it).
Usage:
validation_status
provides a flat text translation of the detailed
validation results. This is useful primarily for checking the detailed status
of some particular object or set of objects, perhaps using a program like
grep
or awk
to filter validation_status
's output.
Usage:
$ validation_status rcynic.xml
$ validation_status rcynic.xml | fgrep rpki.misbehaving.org
$ validation_status rcynic.xml | fgrep object_rejected
rcynic-svn
is a tool for archiving rcynic
's results in a
Subversion repository. rcynic-svn
is not
integrated into rcynic-cron
, because this is not something that every
relying party is going to want to do. However, for relying parties who want to
analyze rcynic
's output over a long period of time, rcynic-svn
may provide
a useful starting point starting point.
To use rcynic-svn
, you first must set up a Subversion repository and check
out a working directory:
$ svnadmin create /some/where/safe/rpki-archive
$ svn co file:///some/where/safe/rpki-archive /some/where/else/rpki-archive
The name can be anything you like, in this example we call it "rpki-
archive
". The above sequence creates the repository, then checks out an empty
working directory /some/where/else/rpki-archive
.
The repository does not need to be on the same machine as the working
directory, but it probably should be for simplicity unless you have some
strong need to put it elsewhere.
Once you have the repository and working directory set up, you need to arrange
for rcynic-svn
to be run after each rcynic
run whose results you want to
archive. One way to do this would be to run rcynic-svn
in the same cron job
as rcynic-cron
, immediately after rcynic-cron
and specifying the same lock
file that rcynic-cron
uses.
Sample usage, assuming that rcynic
's data is in the usual place:
$ rcynic-svn --lockfile /var/rcynic/data/lock \
/var/rcynic/data/authenticated \
/var/rcynic/data/unauthenticated \
/var/rcynic/data/rcynic.xml \
/some/where/else/rpki-archive
where the last argument is the name of the Subversion working directory and
the other arguments are the names of those portions of rcynic
's output which
you wish to archive. Generally, the above set (authenticated
,
unauthenticated
, and rcynic.xml
) are the ones you want, but feel free to
experiment.