# {{ page.title }}
+> TODO update with proper .tar.gz releases, once they are created
+
## Index
-1. [Install dependencies](#install-dependencies)
- 1. [libcrypto](#libcrypto)
- 2. [tomlc99](#tomlc99)
- 3. [rsync](#rsync)
-2. [Install Fort](#install-fort)
- 1. [libcmscodec](#libcmscodec)
- 2. [Validator](#validator)
- 3. [RTR Server](#rtr-server)
+1. [Dependencies](#dependencies)
+2. [Debian-based distributions](#debian-based-distributions)
+3. [OpenBSD](#openbsd)
+
+## Dependencies
-## Install dependencies
+> Note: I'm only including this section in case you intend to install Fort in an unlisted OS (and therefore need a little research). For Debians and OpenBSD, just follow the steps in the sections below.
-### libcrypto
+The dependencies are
-Either [LibreSSL](http://www.libressl.org/) or [OpenSSL](https://www.openssl.org/)
+1. [jansson](http://www.digip.org/jansson/)
+2. [libcmscodec](https://github.com/NICMx/libcmscodec)
+3. libcrypto (Either [LibreSSL](http://www.libressl.org/) or [OpenSSL](https://www.openssl.org/))
+4. [rsync](http://rsync.samba.org/)
-### tomlc99
+There's also [autoconf](https://www.gnu.org/software/autoconf/) and unzip (or [git](https://git-scm.com/)), but those are only needed for installation paperwork.
-[tomlc99](https://github.com/cktan/tomlc99)
+## Debian-based distributions
-### libcmscodec
+I haven't actually tried this in all the Debian-based distributions. Tested in Ubuntu 18.
{% highlight bash %}
-git clone https://github.com/ydahhrk/libcmscodec.git
-cd libcmscodec
-./autogen.sh
+########### normal dependencies ###########
+# autoconf 2.69 or higher, please.
+sudo apt install autoconf libjansson-dev libssl-dev rsync
+
+############### libcmscodec ###############
+mkdir libcmscodec
+cd libcmscodec/
+wget https://github.com/NICMx/libcmscodec/releases/download/beta1/libcmscodec-beta1.tar.gz
+tar xvzf libcmscodec-beta1.tar.gz
+cd libcmscodec-beta1/
./configure
make
sudo make install
-{% endhighlight %}
-
-### rsync
-
-[rsync](http://rsync.samba.org/)
-
-## Install Fort
-
-There are no packages just yet.
-
-{% highlight bash %}
-git clone https://github.com/ydahhrk/rpki-validator.git
-cd rpki-validator
+sudo ldconfig
+cd ../..
+
+################## fort ###################
+mkdir 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
+cd FORT-validator-master/
./autogen.sh
./configure
make
sudo make install
+cd ../..
{% endhighlight %}
## OpenBSD
+> TODO: The autotools are weird in this OS.
+>
+> They require some global variables the installer doesn't setup on its own for some reason, and then spew error messages encouraging long deprecated macros. WTF?
+>
+> For now, I'm working around this by running the `autogen.sh`s in Debian. It probably needn't be fixed, since the releases are going to ship with the `autogen.sh`s already executed anyway.
+
+> TODO: test this again
+
{% highlight bash %}
-# pkg_add libexecinfo jansson rsync
-$
-$ ftp <libcmscodec tar url>
-$ tar xvzf libcmscodec-<version>.tar.gz
-$ cd libcmscodec
-$ ./configure
-$ make
-# make install
-$ cd ..
-$ ftp <fort tar url>
-$ tar xvzf fort-<version>.tar.gz
-$ cd fort
-$ # clang is needed because of gnu11.
-$ env CC=clang CFLAGS=-I/usr/local/include LDFLAGS=-L/usr/local/lib ./configure
-$ make
-# make install
+########### normal dependencies ###########
+su
+# OpenBSD ships with LibreSSL
+# autoconf 2.69 or higher, please.
+pkg_add autoconf automake jansson libexecinfo rsync unzip
+exit
+
+# Adjust depending on the choices you made above.
+export AUTOCONF_VERSION=2.69
+export AUTOMAKE_VERSION=1.9
+
+############### libcmscodec ###############
+mkdir libcmscodec
+cd libcmscodec/
+ftp https://github.com/NICMx/libcmscodec/releases/download/beta1/libcmscodec-{{ site.libcmscodec-latest-version }}.tar.gz
+tar xvzf libcmscodec-{{ site.libcmscodec-latest-version }}.tar.gz
+cd libcmscodec-{{ site.libcmscodec-latest-version }}/
+./configure
+make
+su
+make install
+exit
+cd ../..
+
+################## fort ###################
+mkdir fort
+cd fort/
+ftp https://github.com/NICMx/FORT-validator/archive/master.zip
+# tar xvzf fort-{{ site.fort-latest-version }}.tar.gz
+unzip master.zip
+cd FORT*
+ksh ./autogen.sh
+# clang is needed because of gnu11.
+env CC=clang CFLAGS=-I/usr/local/include LDFLAGS=-L/usr/local/lib ./configure
+make
+su
+make install
+exit
+cd ../..
{% endhighlight %}
---
title: Validator Usage
-command: rpki_validator
+command: fort
---
# {{ page.title }}
3. [`--version`](#--version)
4. [`--tal`](#--tal)
5. [`--local-repository`](#--local-repository)
- 6. [`--roa-output-file`](#--roa-output-file)
- 7. [`--sync-strategy`](#--sync-strategy)
+ 6. [`--sync-strategy`](#--sync-strategy)
1. [`off`](#off)
2. [`strict`](#strict)
3. [`root`](#root)
4. [`root-except-ta`](#root-except-ta)
+ 7. [`--shuffle-uris`](#--shuffle-uris)
8. [`--maximum-certificate-depth`](#--maximum-certificate-depth)
- 9. [`--shuffle-uris`](#--shuffle-uris)
- 10. [`--color-output`](#--color-output)
- 11. [`--output-file-name-format`](#--output-file-name-format)
- 12. [`--configuration-file`](#--configuration-file)
- 13. [`rsync.program`](#rsyncprogram)
- 14. [`rsync.arguments-recursive`](#rsyncarguments-recursive)
- 15. [`rsync.arguments-flat`](#rsyncarguments-flat)
+ 9. [`--server.address`](#--serveraddress)
+ 10. [`--server.port`](#--serverport)
+ 11. [`--server.backlog`](#--serverbacklog)
+ 12. [`--server.validation-interval`](#--servervalidation-interval)
+ 13. [`--slurm`](#--slurm)
+ 14. [`--log.color-output`](#--logcolor-output)
+ 15. [`--log.file-name-format`](#--logfile-name-format)
+ 16. [`--configuration-file`](#--configuration-file)
+ 17. [`rsync.program`](#rsyncprogram)
+ 18. [`rsync.arguments-recursive`](#rsyncarguments-recursive)
+ 19. [`rsync.arguments-flat`](#rsyncarguments-flat)
## Syntax
+<!-- TODO: Update this -->
+
```
{{ page.command }}
- [--help]
+ [--help]
[--usage]
[--version]
[--configuration-file=<file>]
+ [--tal=<file>]
[--local-repository=<directory>]
[--sync-strategy=off|strict|root|root-except-ta]
- [--maximum-certificate-depth=<unsigned integer>]
- [--tal=<file>]
[--shuffle-uris]
- [--color-output]
- [--output-file-name-format=global-url|local-path|file-name]
- [--roa-output-file=<file>]
+ [--maximum-certificate-depth=<unsigned integer>]
+ [--server.address=<string>]
+ [--server.port=<string>]
+ [--server.backlog=<unsigned integer>]
+ [--server.validation-interval=<unsigned integer>]
+ [--slurm=<string>]
+ [--log.color-output]
+ [--log.file-name-format=global-url|local-path|file-name]
```
If an argument is declared more than once, the last one takes precedence:
### `--help`
- Type: None
-- Availability: `argv` only.
+- Availability: `argv` only
Prints medium-sized usage message.
### `--usage`
- Type: None
-- Availability: `argv` only.
+- Availability: `argv` only
Prints small-sized help message.
### `--version`
- Type: None
-- Availability: `argv` only.
+- Availability: `argv` only
Prints small-sized usage message.
### `--tal`
- Type: String (Path to file)
-- Availability: `argv` and TOML
+- Availability: `argv` and JSON
-Path to the _Trust Anchor Locator_ (TAL).
+Path to the _Trust Anchor Locator_ (TAL), or to a directory that contains TALs.
-The TAL is a file that points to the _Trust Anchor_ (TA). (The TA is the self-signed certificate that serves as the root of the tree you want validated.)
+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 a TAL instead of a TA is to allow the TA to be updated without needing to redistribute it.
+The reason why you provide locators instead of anchors is to allow anchors 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. FORT currently ships with the TALs of most of the five RIRs.
+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.
-> TODO state where they are and which is the missing one.
-
-the TAL file format has been standardized in [RFC 7730](https://tools.ietf.org/html/rfc7730). It is a text file that contains a list of URLs (which serve as alternate access methods for the TA), followed by a blank line, followed by the Base64-encoded public key of the TA.
+The TAL file format has been standardized in [RFC 7730](https://tools.ietf.org/html/rfc7730). It is a text file that contains a list of URLs (which serve as alternate access methods for the TA), followed by a blank line, followed by the Base64-encoded public key of the TA.
Just for completeness sake, here's an example on what a typical TAL looks like:
### `--local-repository`
- Type: String (Path to directory)
-- Availability: `argv` and TOML
+- Availability: `argv` and JSON
- Default: `/tmp/fort/repository`
-> TODO I just came up with the default value. Commit it.
-
-Path to the directory where FORT will store a local cache of the repository.
-
-RPKI repositories are typically accessed by way of [rsync](https://en.wikipedia.org/wiki/Rsync). During the validation cycle, FORT will literally invoke an `rsync` command (see `rsync.program` and `rsync.arguments`), which will download the files into `--local-repository`, and validate the result.
-
-Because rsync uses delta encoding, keeping this cache around significantly speeds up subsequent validation cycles.
+Path to the directory where Fort will store a local cache of the repository.
-### `--roa-output-file`
-
-- Type: String (Path to file)
-- Availability: `argv` and TOML
-- Default: `NULL`
+Right now, Fort accesses RPKI repositories by way of [rsync](https://en.wikipedia.org/wiki/Rsync). (The alternate protocol [RRDP](https://tools.ietf.org/html/rfc8182) is in the road map.) During each validation cycle, Fort will literally invoke an `rsync` command (see [`rsync.program`](#rsyncprogram) and [`rsync.arguments-recursive`](#rsyncarguments-recursive)), which will download the files into `--local-repository`. Fort's validation operates on the resulting copy.
-Path to a file where FORT will dump successfully validated ROAs (in CSV format). If `NULL`, the ROAs will be printed in standard error.
-
-This file is meant to be consumed by the beta version of the RTR Server. (In subsequent releases, this will no longer be required.)
+Because rsync uses delta encoding, you're advised to keep this cache around. It significantly speeds up subsequent validation cycles.
### `--sync-strategy`
- Type: Enumeration (`off`, `strict`, `root`, `root-except-ta`)
-- Availability: `argv` and TOML
+- Availability: `argv` and JSON
- Default: `root`
rsync synchronization strategy. Commands the way rsync URLs are approached during downloads.
A validator following the `strict` strategy would download `bar`, download `qux`, skip `bar`, download `corge/grault`, download `corge` and skip `corge/waldo`.
-Though this strategy is the only "strictly" correct one, it is also extremely slow. Its usage is _not_ recommended, unless your repository contains lots of spam files, awkward permissions or can't be found in a repository rooted in a URL that follows the pattern `rsync://.+/.+/`.
+Though this strategy is the only "strictly" correct one, it is also extremely slow. Its usage is _not_ recommended, unless your repository contains lots of spam files, awkward permissions or can't be found in a repository rooted in a URL that follows the regular expression "`rsync://.+/.+/`".
#### `root`
Useful if you want `root`, but the root certificate is separated from the rest of the repository. Also useful if you don't want the validator to download the entire repository without first confirming the integrity and legitimacy of the root certificate.
-### `--maximum-certificate-depth`
-
### `--shuffle-uris`
-- Availability: `argv` and TOML
+- 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.
+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.
-(Regardless of this flag, FORT will stop iterating through the URLs as soon as it finds one that yields a successful traversal.)
+(Regardless of this flag, Fort will stop iterating through the URLs as soon as it finds one that yields a successful traversal.)
Of course, this is only relevant if the TAL lists more than one URL.
-### `--color-output`
+### `--maximum-certificate-depth`
+
+> TODO; unfinished code
+
+### `--server.address`
+
+- 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.
+
+If this field is omitted, Fort falls back to perform an in-place standalone RPKI validation. Presently, this is only intended for debugging.
+
+### `--server.port`
+
+- Type: String
+- Availability: `argv` and JSON
+- Default: `"323"`
+
+TCP port or service the server will be bound to.
+
+This is a string because a service alias can be used as a valid value. The alias are commonly located at `/etc/services`. (See '`$ man services`'.)
+
+>  The default port is privileged. To improve security, either change or jail it.
+
+### `--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`
+
+RTR server's listen queue length. It's the second argument of [`listen()`](http://pubs.opengroup.org/onlinepubs/9699919799.2008edition/functions/listen.html):
+
+> The backlog argument provides a hint to the implementation which the implementation shall use to limit the number of outstanding connections in the socket's listen queue. Implementations may impose a limit on backlog and silently reduce the specified value. Normally, a larger backlog argument value shall result in a larger or equal length of the listen queue. Implementations shall support values of backlog up to SOMAXCONN, defined in <sys/socket.h>.
+
+See the corresponding manual page from your operating system (likely `man 2 listen`) for specific implementation details.
-- Availability: `argv` and TOML
+### `--server.validation-interval`
+
+- Type: Integer
+- Availability: `argv` and JSON
+- Default: 60
+- Range: 60--7200
+
+Number of seconds the server will sleep between validation cycles.
+
+The timer starts counting every time a validation is finished, not every time it begins. The actual validation loop is, therefore, longer than this number.
+
+> TODO rationale of default value and range?
+
+### `--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.
+
+> TODO this is somewhat involved, and needs a dedicated page. The format is standard, though.
+
+### `--log.color-output`
+
+- Availability: `argv` and JSON
If enabled, the logging output will contain ANSI color codes. Meant for human consumption.
<span style="color:magenta">CRT: Programming error: Array size is 1 but array is NULL.</span>
</code></pre>
-### `--output-file-name-format`
+### `--log.file-name-format`
- Type: Enumeration (`global-url`, `local-path`, `file-name`)
-- Availability: `argv` and TOML
+- Availability: `argv` and JSON
- Default: `global-url`
Decides which version of file names should be printed during most debug/error messages.
### `--configuration-file`
- Type: String (Path to file)
-- Availability: `argv`
-
-Path to a TOML file from which additional configuration will be read.
-
-The configuration options are mostly the same as the ones from the `argv` interface. Here's a full configuration file example:
-
-<pre><code>[root]
-<a href="#--local-repository">local-repository</a> = "/tmp/fort/repository"
-<a href="#--sync-strategy">sync-strategy</a> = "root"
-<a href="#--maximum-certificate-depth">maximum-certificate-depth</a> = 32
-
-[tal]
-<a href="#--tal">tal</a> = "/tmp/fort/example.tal"
-<a href="#--shuffle-uris">shuffle-uris</a> = true
-
-[rsync]
-<a href="#rsyncprogram">program</a> = "rsync"
-<a href="#rsyncarguments-recursive">arguments-recursive</a> = [ "--recursive", "--times", "$REMOTE", "$LOCAL" ]
-<a href="#rsyncarguments-flat">arguments-flat</a> = [ "--times", "$REMOTE", "$LOCAL" ]
-
-[output]
-<a href="#--color-output">color-output</a> = true
-<a href="#--output-file-name-format">output-file-name-format</a> = "file-name"
-<a href="#--roa-output-file">roa-output-file</a> = "/tmp/fort/roas.csv"
+- Availability: `argv` only
+
+Path to a JSON file from which additional configuration will be read.
+
+The configuration options are mostly the same as the ones from the `argv` interface. (See the "Availability" metadata of each field.) Here's a full configuration file example:
+
+<pre><code>{
+ "<a href="#--tal">tal</a>": "/tmp/tal/test.tal",
+ "<a href="#--local-repository">local-repository</a>": "tmp/repository",
+ "<a href="#--sync-strategy">sync-strategy</a>": "root",
+ "<a href="#--shuffle-uris">shuffle-uris</a>": true,
+
+ "server": {
+ "address": "192.0.2.1",
+ "port": "8323",
+ "backlog": 16,
+ "validation-interval": 120
+ },
+
+ "slurm": "test.slurm",
+
+ "log": {
+ "<a href="#--color-output">color-output</a>": true,
+ "<a href="#--output-file-name-format">file-name-format</a>": "file-name"
+ },
+
+ "rsync": {
+ "<a href="#rsyncprogram">program</a>": "rsync",
+ "<a href="#rsyncarguments-recursive">arguments-recursive</a>": [
+ "--recursive",
+ "--times",
+ "$REMOTE",
+ "$LOCAL"
+ ],
+ "<a href="#rsyncarguments-flat">arguments-flat</a>": [
+ "--times",
+ "$REMOTE",
+ "$LOCAL"
+ ]
+ },
+
+ "incidences": [
+ {
+ "name": "signature algorithm has parameters",
+ "action": "ignore"
+ }
+ ]
+}
</code></pre>
The file acts as a collection of equivalent `argv` arguments; precedence is not modified:
{% highlight bash %}
-$ cat cfg.toml
-[tal]
-tal = "bar"
-$ {{ page.command }} --tal="foo" # tal is "foo"
-$ {{ page.command }} --tal="foo" --configuration-file="cfg.toml" # tal is "bar"
-$ {{ page.command }} --tal="foo" --configuration-file="cfg.toml" --tal="qux" # tal is "qux"
+$ cat cfg.json
+{
+ "tal": "bar"
+}
-$ cat a.toml
-[root]
-local-repository = "a"
-sync-strategy = "root"
-maximum-certificate-depth = 1
-
-$ cat b.toml
-[root]
-sync-strategy = "strict"
-maximum-certificate-depth = 2
-
-$ cat c.toml
-[root]
-maximum-certificate-depth = 4
+$ {{ page.command }} --tal="foo" # tal is "foo"
+$ {{ page.command }} --tal="foo" --configuration-file="cfg.json" # tal is "bar"
+$ {{ page.command }} --tal="foo" --configuration-file="cfg.json" --tal="qux" # tal is "qux"
+
+$ cat a.json
+{
+ "local-repository": "a",
+ "sync-strategy": "root",
+ "maximum-certificate-depth": 1
+}
+
+$ cat b.json
+{
+ "sync-strategy": "strict"
+ "maximum-certificate-depth": 2
+}
+
+$ cat c.json
+{
+ "maximum-certificate-depth": 4
+}
$ {{ page.command }} \
- --configuration-file="a.toml" \
- --configuration-file="b.toml" \
- --configuration-file="c.toml"
+ --configuration-file="a.json" \
+ --configuration-file="b.json" \
+ --configuration-file="c.json"
$ # local-repository is "a", sync-strategy is "strict" and maximum-certificate-depth is 4
{% endhighlight %}
### rsync.program
- Type: String
-- Availability: TOML
+- Availability: JSON
- Default: `"rsync"`
Name of the program needed to invoke an rsync file transfer.
### rsync.arguments-recursive
- Type: String array
-- Availability: TOML
+- Availability: JSON
- Default: `[ "--recursive", "--delete", "--times", "--contimeout=20", "$REMOTE", "$LOCAL" ]`
Arguments needed by [`rsync.program`](#rsyncprogram) to perform a recursive 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.
+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.
### rsync.arguments-flat
- Type: String array
-- Availability: TOML
+- Availability: JSON
- 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.
+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.