1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
|
****** rcynic RPKI validator ******
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 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 run work on Ubuntu
(8.10) 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.
***** Don't panic *****
rcynic has a lot of options, but it attempts to choose reasonable defaults
where possible. The installation process will create a basic rcynic.conf file
for you and set up the chroot jail.
See the instructions for setting up a cron job for details on how to run rcynic
automatically and feed its output into other relying party tools.
***** Overview *****
rcynic depends heavily on the OpenSSL libcrypto library, and requires a
reasonably current version of OpenSSL with both RFC 3779 and CMS support.
All certificates, CRLs, and CMS objects are in DER format, with 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 of the 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 config file uses OpenSSL's config 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 progran, perhaps under cron, you'll want to set
additional parameters to tell rcynic where to find its data and where to write
its output. The configuration file itself, however, is not optional. In order
for rcynic to do anything useful, your configuration file MUST specify the file
name(s) of one or more RPKI trust anchors or trust anchor locators.
**** Trust anchors ****
* 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.
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 global trust anchor for the RPKI system,
so you have to specify separate trust anchors for each Regional Internet
Registry (RIR) which is publishing RPKI data:
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
**** Output directories ****
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
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.
rynic stores trust anchors specified via the trust-anchor-locator directive in
the unauthenticated tree just like any other fetched object, and copies 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 xxxxxxxx.n.cer, where xxxxxxxx
and n are the OpenSSL object name hash and index within the resulting virtual
hash bucket (the same as the c_hash Perl script that comes with OpenSSL would
produce), and ".cer" is the literal string ".cer". The reason for this 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.
As currently implemented, rcynic does not attempt to maintain an in-memory
cache of objects it might need again later. It does keep an internal cache of
the URIs from which it has already fetched data in this pass, and it keeps a
stack (actually, multiple stacks, to support parallel operations) containing
the current certificate chain as it does its validation walk. All other data
(eg, CRLs) are freed immediately after use and read from disk again as needed.
From a database design standpoint, this is not very efficient, but as the
rcynic's main bottlenecks are expected to be crypto and network operations, it
seemed best to keep the design as simple as possible, at least until execution
profiling demonstrates a real issue here.
***** Usage and configuration *****
**** Logging levels ****
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
**** Command line options ****
-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
***** Configuration file reference *****
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.
Configuration variables:
authenticated::
Path to output directory (where rcynic should place objects it has
been able to validate).
Default: rcynic-data/authenticated
unauthenticated::
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
rsync-timeout::
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 seconds.
max-parallel-fetches::
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. At
least one RIR currently refuses service at settings above 4, and
another RIR appears to be running some kind of firewall that silently
blocks connections when it thinks decides that the connection rate is
excessive.
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
rsync-program::
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.
log-level::
Same as -l option on command line. Command line setting overrides
config file setting.
Default: log_log_err
use-syslog::
Same as -s option on command line. Command line setting overrides
config file setting.
Values: true or false.
Default: false
use-stderr::
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::
Syslog facility to use.
Default: local0
syslog-priority-xyz::
(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
jitter::
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 RPKI
rsync servers into the ground at midnight UTC.
Default: 600
lockfile::
Name of lockfile, or empty for no lock. If you run rcynic under cron,
you should use this parameter to set a lockfile so that successive
instances of rcynic don't stomp on each other.
Default: no lock
xml-summary::
Enable output of a per-host summary at the end of an rcynic run in
XML format. Some users prefer this to the log_telemetry style of
logging, or just want it in addition to logging. Value: filename to
which XML summary should be written; "-" will send XML summary to
stdout.
Default: no XML summary.
allow-stale-crl::
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
prune::
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-stale-manifest::
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
require-crl-in-manifest::
Reject publication point if manifest doesn't list the CRL that covers
the manifest EE certificate.
Values: true or false.
Default: false
allow-object-not-in-manifest::
Allow use of otherwise valid objects which are not listed in the
manifest. This is not supposed to happen, but is probably harmless.
Values: true or false
Default: true
allow-digest-mismatch::
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-crl-digest-mismatch::
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
allow-non-self-signed-trust-anchor::
Experimental. Attempts to work around OpenSSL's strong preference for
self-signed trust anchors. Do not even consider enabling this unless
you are intimately familiar with X.509 and really know what you are
doing.
Values: true or false.
Default: false
run-rsync::
Whether to run rsync to fetch data. You don't 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
consistancy 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
use-links::
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
trust-anchor::
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.
trust-anchor-locator
Specify one RPKI trust anchor, represented as a local file containing
an rsync URI and the RSA public key of the X.509 object specified by
the URI. First line of the file is the URI, remainder is the public
key in Base64 encoded DER format. Value of this option is the
pathname of the file.
No default.
***** Post-processing rcynic's XML output *****
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.
Usage:
$ 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.py ****
An earlier attempt at what rcynic-html now does. Kept briefly for backwards
compatability, but no longer maintained and will go away soon. Use rcynic-html
instead.
**** rcynic.xsl ****
An earlier attempt at the same kind of HTML display as rcynic-html. XSLT was a
convenient language for our initial attempts at this, but as the processing got
more and more complex, the speed and flexibility restrictions of XSLT became
prohibitive. 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. Useful primarily in
test scripts (smoketest uses it).
Usage:
$ rcynic-text rcynic.xml
**** validation_status.py ****
Provides a flat text translation of the detailed validation results. Useful
primarily for checking the detailed status of some particular object or set of
objects, most likely using a program like grep to filter the output.
Usage:
$ python validation_status.py rcynic.xml
$ python validation_status.py rcynic.xml | fgrep rpki.misbehaving.org
$ python validation_status.py rcynic.xml | fgrep object_rejected
***** Running rcynic chrooted *****
This is an attempt to describe the process of setting up rcynic in a chrooted
environment. The installation scripts that ship with rcynic attempt to do this
automatically for the platforms we support, but the process is somewhat
finicky, so some explanation seems in order. If you're running on one of the
supported platforms, the following steps may be handled for you by the
Makefiles, but you may still want to understand what all this is trying to do.
rcynic itself does not include any direct support for running chrooted, but is
designed to be (relatively) easy to run in a chroot jail. Here's how.
You'll either need staticly linked copies of rcynic and rsync, or you'll need
to figure out which shared libraries these programs need (try using the "ldd"
command). Here we assume staticly linked binaries, because that's simpler, but
be warned that statically linked binaries are not even possible on some
platforms, whether due to concious decisions on the part of operating system
vendors or due to hidden use of dynamic loading by other libraries at runtime.
You'll need a chroot wrapper program. Your platform may already have one
(FreeBSD does -- /usr/sbin/chroot), but if you don't, you can download Wietse
Venema's "chrootuid" program from ftp://ftp.porcupine.org/pub/security/
chrootuid1.3.tar.gz.
Warning::
The chroot program included in at least some Linux distributions is
not adaquate to this task, you need a wrapper that knows how to drop
privileges after performing the chroot() operation itself. If in
doubt, use chrootuid.
Unfortunately, the precise details of setting up a proper chroot jail vary
wildly from one system to another, so the following instructions will likely
not be a precise match for the preferred way of doing this on any particular
platform. We have sample scripts that do the right thing for FreeBSD, feel free
to contribute such scripts for other platforms.
1. Build the static binaries. You might want to test them at this stage too,
although you can defer that until after you've got the jail built.
2. Create a userid under which to run rcynic. Here we'll assume that you've
created a user "rcynic", whose default group is also named "rcynic". Do
not add any other userids to the rcynic group unless you really know what
you are doing.
3. Build the jail. You'll need, at minimum, a directory in which to put the
binaries, a subdirectory tree that's writable by the userid which will be
running rcynic and rsync, your trust anchors, and whatever device inodes
the various libraries need on your system. Most likely the devices that
matter will be /dev/null, /dev/random,a nd /dev/urandom; if you're running
a FreeBSD system with devfs, you do this by mounting and configuring a
devfs instance in the jail, on other platforms you probably use the mknod
program or something.
Important::
Other than the directories that you want rcynic and rsync to be able
to modify, nothing in the initial jail setup should be writable by
the rcynic userid. In particular, rcynic and rsync should not be
allowed to modify: their own binary images, any of the configuration
files, or your trust anchors. It's simplest just to have root own all
the files and directories that rcynic and rsync are not allowed to
modify, and make sure that the permissions for all of those
directories and files make them writable only by root.
Sample jail tree, assuming that we're putting all of this under /var/rcynic:
$ mkdir /var/rcynic
$ mkdir /var/rcynic/bin
$ mkdir /var/rcynic/data
$ mkdir /var/rcynic/dev
$ mkdir /var/rcynic/etc
$ mkdir /var/rcynic/etc/trust-anchors
Copy your trust anchors into /var/rcynic/etc/trust-anchors.
Copy the staticly linked rcynic and rsync into /var/rcynic/bin.
Copy /etc/resolv.conf and /etc/localtime (if it exists) into /var/rcynic/etc.
Write an rcynic configuration file as /var/rcynic/etc/rcynic.conf (path names
in this file must match the jail setup, more below).
$ chmod -R go-w /var/rcynic
$ chown -R root:wheel /var/rcynic
$ chown -R rcynic:rcynic /var/rcynic/data
If you're using devfs, arrange for it to be mounted at /var/rcynic/dev;
otherwise, create whatever device inodes you need in /var/rcynic/dev and make
sure that they have sane permissions (copying whatever permissions are used in
your system /dev directory should suffice).
rcynic.conf to match this configuration:
[rcynic]
trust-anchor-locator.1 = /etc/trust-anchors/ta-1.tal
trust-anchor-locator.2 = /etc/trust-anchors/ta-2.tal
trust-anchor-locator.3 = /etc/trust-anchors/ta-3.tal
rsync-program = /bin/rsync
authenticated = /data/authenticated
unauthenticated = /data/unauthenticated
Once you've got all this set up, you're ready to try running rcynic in the
jail. Try it from the command line first, then if that works, you should be
able to run it under cron.
Note: chroot, chrootuid, and other programs of this type are usually intended
to be run by root, and should not be setuid programs unless you really know
what you are doing.
Sample command line:
$ /usr/local/bin/chrootuid /var/rcynic rcynic /bin/rcynic -s -c /etc/
rcynic.conf
Note that we use absolute pathnames everywhere. This is not an accident.
Programs running in jails under cron should not make assumptions about the
current working directory or environment variable settings, and programs
running in chroot jails would need different PATH settings anyway. Best just to
specify everything.
**** Building static binaries ****
On FreeBSD, building a staticly linked rsync is easy: just set the environment
variable LDFLAGS='-static' before building the rsync port and the right thing
will happen. Since this is really just GNU configure picking up the environment
variable, the same trick should work on other platforms...except that some
compilers don't support -static, and some platforms are missing some or all of
the non-shared libraries you'd need to link the resulting binary.
For simplicity, we've taken the same approach with rcynic, so
$ make LDFLAGS='-static'
works. This isn't necessary on platforms where we know that static linking
works -- the default is static linking where supported.
**** syslog from chrooted environment ****
Depending on your syslogd configuration, syslog may not work properly with
rcynic in a chroot jail. On FreeBSD, the easiest way to fix this is to add the
following lines to /etc/rc.conf:
altlog_proglist="named rcynic"
rcynic_chrootdir="/var/rcynic"
rcynic_enable="YES"
|