From: Alberto Leiva Popper Date: Tue, 21 May 2019 22:29:08 +0000 (-0500) Subject: Add slurm and incidences to the documentation X-Git-Tag: v0.0.2~24 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=f2552379f5e0bfe9e5f61423f41468ea0b75d965;p=thirdparty%2FFORT-validator.git Add slurm and incidences to the documentation --- diff --git a/README.md b/README.md index 401a43ee..337ce660 100644 --- a/README.md +++ b/README.md @@ -2,7 +2,7 @@ An RPKI Validator and RTR Server. -**Still under development!** +**This software is in beta** ## Installation diff --git a/docs/doc/incidence.md b/docs/doc/incidence.md new file mode 100644 index 00000000..be97eb56 --- /dev/null +++ b/docs/doc/incidence.md @@ -0,0 +1,91 @@ +--- +title: Incidence +--- + +[Documentation](index.html) > {{ page.title }} + +# {{ page.title }} + +## Index + +1. [Introduction](#introduction) +2. [`incidences` definition](#incidences-definition) +3. [Incidence types](#incidence-types) + 1. [rsaEncryption signature algorithm has parameters](#rsaencryption-signature-algorithm-has-parameters) + 2. [certificate public key algorithm is rsaEncryption](#certificate-public-key-algorithm-is-rsaencryption) + +## Introduction + +The RPKI RFCs define fairly strict profiles for RPKI objects, and are unequivocal in stating that incorrectly-formed objects are supposed to be rejected by Relying Party validation. In practice, however, this does not stop a significant amount of Certificate Authorities from issuing incorrect objects. + +By default, Fort is as pedantic as it can reasonably be. The `incidence` section of its configuration file is a means to modify its behavior upon encountering profile violations that, from experience, are often overlooked. + +## `incidences` definition + +`incidences` is a JSON array that contains (anonymous) incidence elements. Here's an example: + +``` +"incidences": [ + { + "name": "rsaEncryption signature algorithm has parameters", + "action": "warn" + }, { + "name": "certificate public key algorithm is rsaEncryption", + "action": "ignore" + } +] +``` + +`name` is the identifier of an incidence. It's case-sensitive and developer-defined. It states the particular error condition that will be handled by the remaining field. + +`action` is an enumeration that states the outcome of a violation of the corresponding incidence. It can take one of three values: + +1. `error`: Print error message in `error` log level, fail validation of the offending object (and all of its children). +2. `warn`: Print error message in `warning` log level, continue validation as if nothing happened. +3. `ignore`: Do not print error message, continue validation as if nothing happened. + +By Fort's pedantic nature, most incidences have an `action` of `error` by default. + +## Incidence types + +Presently, there are only two incidence types defined. This list might grow over time, depending on the state of the global RPKI and user demand. + +### rsaEncryption signature algorithm has parameters + +[RFC 6488](https://tools.ietf.org/html/rfc6488) (RPKI Signed Objects) defers signature algorithm specification to RFC 6485: + +``` +2.1.6.5. signatureAlgorithm + + The signatureAlgorithm MUST conform to the RPKI Algorithms and Key + Size Profile specification [RFC6485]. +``` + +[6485](https://tools.ietf.org/html/rfc6485) has been obsoleted by [7935](https://tools.ietf.org/html/rfc7935), which states the following: + +``` + RPKI implementations MUST + accept either rsaEncryption or sha256WithRSAEncryption for the + SignerInfo signatureAlgorithm field when verifying CMS SignedData + objects (for compatibility with objects produced by implementations + conforming to [RFC6485]). +``` + +Regarding `rsaEncryption`, [3370](https://tools.ietf.org/html/rfc3370) states + +``` + When the rsaEncryption algorithm identifier is used, the + AlgorithmIdentifier parameters field MUST contain NULL. +``` + +As of 2019-05-21, many signed objects in the global RPKI break this rule. (`parameters` is often defined as an empty object, but not NULL nonetheless.) + +If not `ignore`d, Fort will report this incidence with the following error message: + +``` +: : rsaEncryption signature algorithm has parameters. +``` + +### certificate public key algorithm is rsaEncryption + +> TODO missing code diff --git a/docs/doc/index.md b/docs/doc/index.md index ff39861e..0dd1f817 100644 --- a/docs/doc/index.md +++ b/docs/doc/index.md @@ -8,4 +8,6 @@ title: Documentation Index 2. [Introduction to Fort](intro-fort.html) 3. [Compilation and Installation](installation.html) 4. [Running Fort](run.html) -5. [Validator usage](usage.html) +5. [Fort usage](usage.html) +6. [SLURM](slurm.html) +7. [Incidences](incidence.html) diff --git a/docs/doc/installation.md b/docs/doc/installation.md index 7e08df77..4d972e5f 100644 --- a/docs/doc/installation.md +++ b/docs/doc/installation.md @@ -2,6 +2,8 @@ title: Compilation and Installation --- +[Documentation](index.html) > {{ page.title }} + # {{ page.title }} > TODO update with proper .tar.gz releases, once they are created @@ -44,11 +46,11 @@ cd libcmscodec-beta1/ make sudo make install sudo ldconfig -cd ../.. +cd ../../ ################## fort ################### mkdir fort -cd fort +cd fort/ wget https://github.com/NICMx/FORT-validator/archive/master.zip # tar xvzf fort-{{ site.fort-latest-version }}.tar.gz unzip master.zip @@ -57,7 +59,7 @@ cd FORT-validator-master/ ./configure make sudo make install -cd ../.. +cd ../../ {% endhighlight %} ## OpenBSD @@ -93,7 +95,7 @@ make su make install exit -cd ../.. +cd ../../ ################## fort ################### mkdir fort @@ -109,5 +111,5 @@ make su make install exit -cd ../.. +cd ../../ {% endhighlight %} diff --git a/docs/doc/intro-fort.md b/docs/doc/intro-fort.md index d1ff63c0..c344aa48 100644 --- a/docs/doc/intro-fort.md +++ b/docs/doc/intro-fort.md @@ -2,6 +2,8 @@ title: Introduction to Fort --- +[Documentation](index.html) > {{ page.title }} + # {{ page.title }} ## Design diff --git a/docs/doc/intro-rpki.md b/docs/doc/intro-rpki.md index 609aa0ae..e1bdb294 100644 --- a/docs/doc/intro-rpki.md +++ b/docs/doc/intro-rpki.md @@ -2,6 +2,8 @@ title: Introduction to RPKI --- +[Documentation](index.html) > {{ page.title }} + # {{ page.title }} ## Problem Statement diff --git a/docs/doc/run.md b/docs/doc/run.md index f5bc903d..34afb8f3 100644 --- a/docs/doc/run.md +++ b/docs/doc/run.md @@ -2,6 +2,8 @@ title: Running Fort --- +[Documentation](index.html) > {{ page.title }} + # {{ page.title }} This is probably all you need: diff --git a/docs/doc/slurm.md b/docs/doc/slurm.md new file mode 100644 index 00000000..98d86d48 --- /dev/null +++ b/docs/doc/slurm.md @@ -0,0 +1,130 @@ +--- +title: SLURM +--- + +[Documentation](index.html) > {{ page.title }} + +# {{ page.title }} + +## Introduction + +There are reasons why you might legitimately want to modify the RPKI assertions validated and published by an RTR server: + +- To assert the validity of private IP addresses and/or AS numbers for local use. (Since they are outside of the scope of the global RPKI.) +- To override temporarily incorrect or outdated global RPKI data. + +The "Simplified Local Internet Number Resource Management with the RPKI" (SLURM) is a [standard](https://tools.ietf.org/html/rfc8416) means to accomplish this. In a nutshell, it's just a bunch of JSON files with which you can filter out or append arbitrary ROAs to Fort's RTR payload. + +Note that, with the exception of the following section, most of this document is just a summary of [RFC 8416](https://tools.ietf.org/html/rfc8416). You can find more details there. + +## Handling of SLURM Files + +The SLURM files are defined by the [`--slurm`](usage.html#--slurm) flag. If the flag points to a file, the configuration is extracted from that single file. If it points to a directory, the configuration is the aggregation of its contained files' contents. + +> TODO: are the children filtered by extension? + +None of the entries of the SLURM configuration are allowed to collide with each other. If there is a collision, the overall SLURM configuration is rejected. + +Fort reloads the SLURM files during every validation cycle. If the new configuration is invalid, **it is treated as nonexistent**. Note that this means that an isolated mistake will temporarily drop all your SLURM overrides. This is intended to change in a future revision of Fort, in which the validator will fall back to the previous valid SLURM configuration on error. + +> TODO: open an issue for that. Giving the users the opportunity to argue it is probably a good idea. + +## SLURM File Definition + +### Root + +Each SLURM file is a JSON-formatted collection of filters and/or additions. Each of the members shown is mandatory: + +``` +{ + "slurmVersion": 1, + + "validationOutputFilters": { + "prefixFilters": [ ], + "bgpsecFilters": [] + }, + + "locallyAddedAssertions": { + "prefixAssertions": [ ], + "bgpsecAssertions": [] + } +} +``` + +The root object contains a `slurmVersion` field (which, for now, must be set to 1), a listing of filters called `validationOutputFilters`, and a listing of additions called `locallyAddedAssertions`. Fort does not yet support BGPsec, so `bgpsecFilters` and `bgpsecAssertions` must be empty. + +### `prefixFilters` + +`` expands to a sequence of (zero or more) JSON objects, each of which follows this pattern: + +``` +{ + "prefix": , + "asn": , + "comment": +} +``` + +Any ROAs that match `prefix` and `asn` will be invalidated. A ROA matches `prefix` by having an equal or more specific IP prefix, and `asn` by having the same AS number. + +One of `prefix` and `asn` can be absent. On absence, any prefix matches `prefix`, and any AS number matches `asn`. + +`comment` is always optional. + +### `prefixAssertions` + +`` expands to a sequence of (zero or more) JSON objects, each of which follows this pattern: + +``` +{ + "prefix": , + "asn": , + "maxPrefixLength": + "comment": +} +``` + +Will force Fort into believing that the [`prefix`, `asn`, `maxPrefixLength`] ROA validated successfully. + +`prefix` and `asn` are mandatory, `maxPrefixLength` and `comment` are not. `maxPrefixLength` defaults to `prefix`'s length. + +## SLURM File Example + +``` +{ + "slurmVersion": 1, + + "validationOutputFilters": { + "prefixFilters": [ + { + "prefix": "192.0.2.0/24", + "comment": "All VRPs encompassed by prefix" + }, { + "asn": 64496, + "comment": "All VRPs matching ASN" + }, { + "prefix": "198.51.100.0/24", + "asn": 64497, + "comment": "All VRPs encompassed by prefix, matching ASN" + } + ], + "bgpsecFilters": [] + }, + + "locallyAddedAssertions": { + "prefixAssertions": [ + { + "asn": 64496, + "prefix": "198.51.100.0/24", + "comment": "My important route" + }, { + "asn": 64496, + "prefix": "2001:DB8::/32", + "maxPrefixLength": 48, + "comment": "My important de-aggregated routes" + } + ], + "bgpsecAssertions": [] + } + } +``` diff --git a/docs/doc/usage.md b/docs/doc/usage.md index 3f75defc..03bdf1e9 100644 --- a/docs/doc/usage.md +++ b/docs/doc/usage.md @@ -1,8 +1,10 @@ --- -title: Validator Usage +title: Fort Usage command: fort --- +[Documentation](index.html) > {{ page.title }} + # {{ page.title }} ## Index @@ -32,6 +34,7 @@ command: fort 17. [`rsync.program`](#rsyncprogram) 18. [`rsync.arguments-recursive`](#rsyncarguments-recursive) 19. [`rsync.arguments-flat`](#rsyncarguments-flat) + 20. [`incidences`](#incidences) ## Syntax @@ -70,10 +73,10 @@ $ {{ page.command }} --tal="foo" --tal="bar" --tal="qux" # tal is "qux" ### `--help` -- Type: None -- Availability: `argv` only +- **Type:** None +- **Availability:** `argv` only -Prints medium-sized usage message. +Prints medium-sized syntax remainder message. {% highlight bash %} $ {{ page.command }} --help @@ -95,10 +98,10 @@ The slightly larger usage message is `man {{ page.command }}` and the large usag ### `--usage` -- Type: None -- Availability: `argv` only +- **Type:** None +- **Availability:** `argv` only -Prints small-sized help message. +Prints small-sized syntax remainder message. {% highlight bash %} $ {{ page.command }} --usage @@ -113,10 +116,10 @@ Usage: {{ page.command }} ### `--version` -- Type: None -- Availability: `argv` only +- **Type:** None +- **Availability:** `argv` only -Prints small-sized usage message. +Prints program version. {% highlight bash %} $ {{ page.command }} --version @@ -125,14 +128,14 @@ $ {{ page.command }} --version ### `--tal` -- Type: String (Path to file) -- Availability: `argv` and JSON +- **Type:** String (Path to file) +- **Availability:** `argv` and JSON Path to the _Trust Anchor Locator_ (TAL), or to a directory that contains TALs. A TAL is a file that points to a _Trust Anchor_ (TA). A TA is a self-signed certificate that serves as root of an RPKI tree you want validated. -The reason why you provide locators instead of anchors is to allow anchors to be officially updated without the need to awkwardly redistribute them. +The reason why you provide locators instead of anchors is to allow the latter to be officially updated without the need to awkwardly redistribute them. Whichever registry serves as root of the tree you want to validate is responsible for providing you with its TAL. For convenience, Fort currently ships with the TALs of four of the five RIRs. (The exception is ARIN's, since you need to read and accept an [agreement](https://www.arin.net/resources/manage/rpki/tal/) before you can use it.) If you are paranoid, however, you'd be advised to get your own. @@ -154,9 +157,9 @@ LQIDAQAB ### `--local-repository` -- Type: String (Path to directory) -- Availability: `argv` and JSON -- Default: `/tmp/fort/repository` +- **Type:** String (Path to directory) +- **Availability:** `argv` and JSON +- **Default:** `/tmp/fort/repository` Path to the directory where Fort will store a local cache of the repository. @@ -166,9 +169,9 @@ Because rsync uses delta encoding, you're advised to keep this cache around. It ### `--sync-strategy` -- Type: Enumeration (`off`, `strict`, `root`, `root-except-ta`) -- Availability: `argv` and JSON -- Default: `root` +- **Type:** Enumeration (`off`, `strict`, `root`, `root-except-ta`) +- **Availability:** `argv` and JSON +- **Default:** `root` rsync synchronization strategy. Commands the way rsync URLs are approached during downloads. @@ -212,7 +215,8 @@ Useful if you want `root`, but the root certificate is separated from the rest o ### `--shuffle-uris` -- Availability: `argv` and JSON +- **Type:** None +- **Availability:** `argv` and JSON If enabled, Fort will access TAL URLs in random order. This is meant for load balancing. If disabled, Fort will access TAL URLs in sequential order. @@ -226,9 +230,9 @@ Of course, this is only relevant if the TAL lists more than one URL. ### `--server.address` -- Type: String -- Availability: `argv` and JSON -- Default: `NULL` +- **Type:** String +- **Availability:** `argv` and JSON +- **Default:** `NULL` Hostname or numeric host address the RTR server will be bound to. Must resolve to (or be) a bindable IP address. IPv4 and IPv6 are supported. @@ -236,9 +240,9 @@ If this field is omitted, Fort falls back to perform an in-place standalone RPKI ### `--server.port` -- Type: String -- Availability: `argv` and JSON -- Default: `"323"` +- **Type:** String +- **Availability:** `argv` and JSON +- **Default:** `"323"` TCP port or service the server will be bound to. @@ -248,10 +252,10 @@ This is a string because a service alias can be used as a valid value. The alias ### `--server.backlog` -- Type: Integer -- Availability: `argv` and JSON -- Default: [`SOMAXCONN`](http://pubs.opengroup.org/onlinepubs/9699919799.2008edition/basedefs/sys_socket.h.html) -- Range: 1--`SOMAXCONN` +- **Type:** Integer +- **Availability:** `argv` and JSON +- **Default:** [`SOMAXCONN`](http://pubs.opengroup.org/onlinepubs/9699919799.2008edition/basedefs/sys_socket.h.html) +- **Range:** 1--`SOMAXCONN` RTR server's listen queue length. It's the second argument of [`listen()`](http://pubs.opengroup.org/onlinepubs/9699919799.2008edition/functions/listen.html): @@ -261,10 +265,10 @@ See the corresponding manual page from your operating system (likely `man 2 list ### `--server.validation-interval` -- Type: Integer -- Availability: `argv` and JSON -- Default: 60 -- Range: 60--7200 +- **Type:** Integer +- **Availability:** `argv` and JSON +- **Default:** 60 +- **Range:** 60--7200 Number of seconds the server will sleep between validation cycles. @@ -274,17 +278,16 @@ The timer starts counting every time a validation is finished, not every time it ### `--slurm` -- Type: String (path to file or directory) -- Availability: `argv` and JSON -- Default: `NULL` - -[SLURM](https://tools.ietf.org/html/rfc8416) file, or directory containing SLURM files. +- **Type:** String (path to file or directory) +- **Availability:** `argv` and JSON +- **Default:** `NULL` -> TODO this is somewhat involved, and needs a dedicated page. The format is standard, though. +SLURM file, or directory containing SLURM files. See [SLURM](slurm.html). ### `--log.color-output` -- Availability: `argv` and JSON +- **Type:** None +- **Availability:** `argv` and JSON If enabled, the logging output will contain ANSI color codes. Meant for human consumption. @@ -298,9 +301,9 @@ If enabled, the logging output will contain ANSI color codes. Meant for human co ### `--log.file-name-format` -- Type: Enumeration (`global-url`, `local-path`, `file-name`) -- Availability: `argv` and JSON -- Default: `global-url` +- **Type:** Enumeration (`global-url`, `local-path`, `file-name`) +- **Availability:** `argv` and JSON +- **Default:** `global-url` Decides which version of file names should be printed during most debug/error messages. @@ -313,16 +316,18 @@ Suppose a certificate was downloaded from `rsync://rpki.example.com/foo/bar/baz. {% highlight bash %} $ {{ page.command }} --output-file-name-format global-url --local-repository tmp/repository/ (...) ERR: rsync://rpki.afrinic.net/repository/arin/uHxadfPZV0E6uZhkaUbUVB1RFFU.mft: Certificate validation failed: certificate has expired + $ {{ page.command }} --output-file-name-format local-path --local-repository tmp/repository/ (...) ERR: tmp/repository/rpki.afrinic.net/repository/arin/uHxadfPZV0E6uZhkaUbUVB1RFFU.mft: Certificate validation failed: certificate has expired + $ {{ page.command }} --output-file-name-format file-name --local-repository tmp/repository/ (...) ERR: uHxadfPZV0E6uZhkaUbUVB1RFFU.mft: Certificate validation failed: certificate has expired {% endhighlight %} ### `--configuration-file` -- Type: String (Path to file) -- Availability: `argv` only +- **Type:** String (Path to file) +- **Availability:** `argv` only Path to a JSON file from which additional configuration will be read. @@ -333,19 +338,18 @@ The configuration options are mostly the same as the ones from the `argv` interf "local-repository": "tmp/repository", "sync-strategy": "root", "shuffle-uris": true, + "slurm": "test.slurm", "server": { - "address": "192.0.2.1", - "port": "8323", - "backlog": 16, - "validation-interval": 120 + "address": "192.0.2.1", + "port": "8323", + "backlog": 16, + "validation-interval": 120 }, - "slurm": "test.slurm", - "log": { - "color-output": true, - "file-name-format": "file-name" + "color-output": true, + "file-name-format": "file-name" }, "rsync": { @@ -363,9 +367,9 @@ The configuration options are mostly the same as the ones from the `argv` interf ] }, - "incidences": [ + "incidences": [ { - "name": "signature algorithm has parameters", + "name": "rsaEncryption signature algorithm has parameters", "action": "ignore" } ] @@ -411,17 +415,17 @@ $ # local-repository is "a", sync-strategy is "strict" and maximum-certificate-d ### rsync.program -- Type: String -- Availability: JSON -- Default: `"rsync"` +- **Type:** String +- **Availability:** JSON only +- **Default:** `"rsync"` Name of the program needed to invoke an rsync file transfer. ### rsync.arguments-recursive -- Type: String array -- Availability: JSON -- Default: `[ "--recursive", "--delete", "--times", "--contimeout=20", "$REMOTE", "$LOCAL" ]` +- **Type:** String array +- **Availability:** JSON only +- **Default:** `[ "--recursive", "--delete", "--times", "--contimeout=20", "$REMOTE", "$LOCAL" ]` Arguments needed by [`rsync.program`](#rsyncprogram) to perform a recursive rsync. @@ -429,10 +433,17 @@ Fort will replace `"$REMOTE"` with the remote URL it needs to download, and `"$L ### rsync.arguments-flat -- Type: String array -- Availability: JSON -- Default: `[ "--times", "--contimeout=20", "$REMOTE", "$LOCAL" ]` +- **Type:** String array +- **Availability:** JSON only +- **Default:** `[ "--times", "--contimeout=20", "$REMOTE", "$LOCAL" ]` Arguments needed by [`rsync.program`](#rsyncprogram) to perform a single-file rsync. Fort will replace `"$REMOTE"` with the remote URL it needs to download, and `"$LOCAL"` with the target local directory where the file is supposed to be dropped. + +### `incidences` + +- **Type:** JSON Object +- **Availability:** JSON only + +A listing of actions to be performed by validation upon encountering certain error conditions. See [incidence](incidence.html). diff --git a/src/algorithm.c b/src/algorithm.c index e2439cb3..9b671717 100644 --- a/src/algorithm.c +++ b/src/algorithm.c @@ -133,9 +133,9 @@ validate_cms_signature_algorithm(AlgorithmIdentifier_t *id) * AlgorithmIdentifier, the parameters MUST be NULL. Implementations * MUST accept the parameters being absent as well as present. */ - if (id->parameters != NULL) { - error = incidence(INID_SIGNATURE_ALGORITHM_HAS_PARAMS, - "The signature algorithm has parameters."); + if (last == 1 && id->parameters != NULL) { + error = incidence(INID_RSAENCRYPTION_SIGNALG_HAS_PARAMS, + "rsaEncryption signature algorithm has parameters."); if (error) return error; } diff --git a/src/incidence/incidence.c b/src/incidence/incidence.c index f6e36a7d..dff05049 100644 --- a/src/incidence/incidence.c +++ b/src/incidence/incidence.c @@ -17,9 +17,9 @@ struct incidence { static struct incidence incidences[__INID_MAX] = { { - INID_SIGNATURE_ALGORITHM_HAS_PARAMS, - "signature algorithm has parameters", - INAC_WARN, + INID_RSAENCRYPTION_SIGNALG_HAS_PARAMS, + "rsaEncryption signature algorithm has parameters", + INAC_ERROR, }, }; diff --git a/src/incidence/incidence.h b/src/incidence/incidence.h index dccd12aa..7b53284d 100644 --- a/src/incidence/incidence.h +++ b/src/incidence/incidence.h @@ -8,7 +8,7 @@ * remember that you also need to add it to the incidences array. That's all. */ enum incidence_id { - INID_SIGNATURE_ALGORITHM_HAS_PARAMS, + INID_RSAENCRYPTION_SIGNALG_HAS_PARAMS, __INID_MAX, }; diff --git a/test/impersonator.c b/test/impersonator.c index 61e22baf..b8e0149e 100644 --- a/test/impersonator.c +++ b/test/impersonator.c @@ -80,7 +80,5 @@ config_get_slurm(void) enum incidence_action incidence_get_action(enum incidence_id id) { - return (id == INID_SIGNATURE_ALGORITHM_HAS_PARAMS) - ? INAC_WARN - : INAC_ERROR; + return INAC_ERROR; }