Skip to content
Choose a tag to compare

This release also contains security patches. Upgrading is strongly recommended.

1.5.3 addresses the security vulnerabilities recently disclosed by the NCSC:

Here are the details:

E: Infinite drip-feeding

Problem description:

The data in a repository has a certain size, and the repository and client can handle a certain bandwidth. The speed to download the data from a repository can vary greatly. A repository can abuse this by hosting quite a lot of data, and providing that data at a speed of, for example, 3 bytes per second. Some RP software requires a minimum bandwidth, or has a maximum transfer time, but there is software that would wait for all data to be transmitted, even if that would take several weeks.

FORT used to have a buggy defense against this.

--http.idle-timeout simultaneously controlled both CURLOPT_LOW_SPEED_LIMIT and CURLOPT_LOW_SPEED_TIME, but it did so clumsily. In pseudocode,

CURLOPT_LOW_SPEED_LIMIT = --http.idle-timeout
CURLOPT_LOW_SPEED_TIME = (--http.idle-timeout != 0) ? 1 : 0

The new code introduces two new flags. In pseudocode:

CURLOPT_LOW_SPEED_LIMIT = --http.low-speed-limit [2]
CURLOPT_LOW_SPEED_TIME = --http.low-speed-time [3]

--http.low-speed-limit defaults to 100 KB/s, and --http.low-speed-time defaults to 10 seconds.

L: Repository serves fake large files

Here I did something quite simple: what if I just serve a lot of data? Luckily, the RRDP protocol allows for the specification of absolute URIs, so I linked that to a large file usually used as a speedtest hosted externally. The contents of the file are random, and contain nothing useful. Some implementations went out of memory, some ignored the file.

rsync calls now include --max-size=20MB by default.

For RRDP, FORT introduces --http.max-file-size. It defaults to 1 GB. (Because of large and growing legitimate RRDP snapshots.)

O: Repository tricks the RP to write files outside of the cache directory

The last test I created was again regarding paths and filesystems. On most UNIX-based systems, there are two special folders in each folder: "." and "..". The former to stay in the current folder, and the latter to go one folder up. Thus I wondered: can I somehow make the RP software write files outside the directories they are supposed to end up in, by using a path rsync:// Most RP software rejected the path, but some did write files to random folders.

Fixed by implementing RFC 6486bis, section 4.2.2. The file validation is much stricter.

With the exception of H, J and K, FORT was found to be resilient against the other attack vectors the research proposed. H, J and K solutions have been postponed, because patching them properly requires IETF intervention.

Choose a tag to compare

Improvements since 1.5.1:

  1. #51: Fix crash when --server.address is not defined in the configuration.
  2. 673c679: Change's interpreter to /bin/sh. (Allows straightforward compilation on default *BSDs.)
  3. #53: Add RPM packages to the release.
  4. #55: Fix situational crash due to bad code cleanup.
  5. eb68ebb, 274dc14: Performance optimizations.
  6. #57: Fix practically inevitable crash in server mode's second iteration.
  7. #58: Remove BGPsec certificate code. (Was crashing easily; needs more testing.)

Please note that version numbers no longer include "v".
(ie. "1.5.2", not "v1.5.2".)
I did this to streamline RPM package generation.
You might need to adjust scripts.

Choose a tag to compare


Add ROA export in JSON format

Fort can now output ROAs (as well as Router Keys) in JSON format. (In addition to the old CSV format.) This is controlled by the --output.format flag.


Patch NID retrieval/registration

Fort was quitting (during initialization) when the libcrypto implementation already declared some of its NIDs. Fort now handles existing NIDs properly.


Ignore SIGPIPE in standalone mode

When the RPKI repository hangs in the middle of a file transfer, Fort sometimes receives a "Broken Pipe" signal (SIGPIPE). For dumb historical reasons, the default response to SIGPIPE is sudden program termination.

Previous versions of Fort actually did register a proper SIGPIPE handler, but only when in server mode. The handler now applies globally.


Near complete rewrite of the RTR server

Previous model:

When the RTR server opens a connection, it borrows a thread from the thread pool, and tasks it with the whole connection.

Needless to say, one thread per router didn't scale well. The new model is

When the RTR server receives a request, it borrows a thread from the thread pool, and tasks it with the request.

So --thread-pool.server.max was a hard limit for simultaneous RTR clients (routers), but now it's just a limit to simultaneous RTR requests. (Surplus requests will queue.) This is much less taxing to the CPU when there are hundreds of clients.

--thread-pool.server.max's maximum value also changed: From 500 to UINT_MAX.

Fix --work-offline

This flag stopped working in version 1.4.1. It's back now.

Changed the delta expiration conditional

Was "keep track of the clients, expire deltas when all clients outgrow them." I see two problems with that:

  1. It'll lead to bad performance if a client misbehaves by not maintaining the connection. (ie. the server will have to fall back to too many cache resets.)
  2. It might keep the deltas forever if a client bugs out without killing the connection.

New conditional is "keep deltas for server.deltas.lifetime iterations." --server.deltas.lifetime is a new configuration argument.

Improve --init-tals

  1. Update the TAL URLs. (The old ones were very obsolete.)
  2. Add --init-as0-tals. (Used to download the ASN0 TALs.)
  3. Deprecate and zero-op --init-locations. (Didn't make sense. If the user needs a different URL, they can do curl or wget instead.)
  4. Deprecate (Seems to be redundant. --init-tals already takes care of downloading TALs.)

Lots of small bugfixes

This list is probably not exhaustive:

  • Libcurl: Catch lots of status codes properly. (They were being ignored.)
  • Libcurl: Send proper data types to curl_easy_setopt(). (Argument types were not matching documented requirements.)
  • Libcurl: Eliminate the custom writefunction. (It was buggy, and there was no reason to override the default implementation.)
  • Remove redundant fopen() and fclose() during valid_file_or_dir(). (If stat() is used instead of fstat(), there's no need to open and close the file.)
  • Segmentation Fault handler: Remove illegal operations. (This was unlikely to be affecting anyone.)
  • main: Add result code sanitizer. (Forces Fort's exit status code to be in the range 0-125.)
  • Deltas: Do not discard meaningful validation results when the deltas array cannot be built for miscellaneous errors. (Deltas are optional; as long as Fort has the snapshot of the latest validation results, it can keep serving routers. At a lower performance, but functional nonetheless.)
  • Deltas: The database was always keeping one serial's worth of obsolete deltas. (Cleaned up, saves a potentially large amount of memory.)
  • Deltas: The code computed deltas even whene there were no routers listening. (Connected routers are the only delta consumers, so there was no need to waste all that time.)
  • Deltas: Start from serial 1. (I found an RTR client implementation [Cloudflare's rpki-rtr-client] that hangs when the first serial is zero. Zero is technically a valid serial, but whatever.)
  • sockaddr2str() was returning a pointer to invalid memory on success. (This was only used to print addresses.)
  • Deltas: Serials weren't being compared according to RFC 1982 serial arithmetic. This was going to cause mayhem when the integer wrapped. (Though Fort always started at 0, and serials are 32-bit unsigned integers, so this wasn't going to be a problem for a very long time.)
  • Thread pool: Hard to explain termination bug. (See problem 4.)

Tweaked lots of logging messages

Please review if you're parsing them.

One significant change is that logs are now semaphore'd, so they shouldn't mix anymore.

Choose a tag to compare

The main updates of this release are:

  • Add argument to daemonize the process (--daemon arg).
  • Integrate TALs download to the binary (--init-tals arg).
  • Implement a thread pool for incoming RTR clients and TALs validation.

Special thanks to Ivaylo Josifov from VarnaIX/Varteh Ltd! For his contribution regarding the implementation of the thread pool.

The public key to verify the tarball is here (it isn't certified yet).

Changes since v1.4.2:

  • Updates

    • Add a warning message to the operation logs when the first validation cycle begins and ends. This is only to notify the RTR server availability to receive clients (router connections).
    • Add --daemon argument to daemonize FORT validator; fixes #25.
    • Integrate the TALs download to FORT binary, by using --init-tals argument.
    • Terminate execution when there's no more memory available, since a full recovery after this isn't assured; related to #40. The RPM and DEB packages will restart the service if FORT validator ends this way, this is achieved using RestartForceExitStatus service setting.
    • Implement a thread pool that's utilized to attend incoming RTR clients (see --thread-pool.server.max) and to process TALs during each validation cycle (see --thread-pool.validation.max).
  • Docs

Choose a tag to compare

The main updates of this release are:

  • Use a local workspace to store all files fetched via HTTP (includes RRDP, see #39).
  • Fix bug that could lead to keep stale data when the local cache directory was removed.
  • Create an official RPM package.

The public key to verify the tarball is here (it isn't certified yet).

Changes since v1.4.1:

  • Bug fixes

    • If the --local-repository was deleted in between validation cycles, stale data could be kept a long time. Now this doesn't happens, since the files are sync'd again via RRDP if they aren't found (if RRDP is supported and --http.priority is on top).
  • Updates

    • Create and use local workspaces for all the files fetched via HTTP, including RRDP resultant files; related to #39.
  • Docs

Choose a tag to compare

This release fixes a couple of bugs found at v1.4.0:

  • Memory leak due to a bad structure release.
  • Bad lock usage when storing an error'd repository URI.

The issue #41 was a consequence of one of these bugs.

The public key to verify the tarball is here (it isn't certified yet).

Changes since v1.3.0:

  • Bug fixes

    • Use the adequate function to release a temporary URI structure (this bug was causing a memory leak).
    • Request write lock whenever a new error'd URI is stored, the lock is used from the start to the end of the transaction.
  • Docs

    • Add missing parenthesis at Logging section.
Choose a tag to compare

The main updates of this release are:

  • Upload Dockerfile so that the docker image can be built (located at the docker directory) (fixes issue #17).
  • Prefer HTTP repositories over RSYNC repositories by default (fixes issue #34).
  • RTR server can be bound to multiple IPs (server.address can be a list of addresses).
  • New incidences for stale manifests (incid-mft-stale) and stale CRLs (incid-crl-stale).

The public key to verify the tarball is here (it isn't certified yet).

Changes since v1.3.0:

  • Bug fixes

    • Some XML parsing and validation errors where printed straight to stderr, now they're printed to the configured validation-log.output.
    • The protocol part of an URI only was only valid in lowercase, now the case is ignored.
  • Updates

    • Upload Dockerfile in order to build a docker image, fixes issue #17.
    • RTR server can be bound to multiple IPs by using a list of addresses in server.address; each address must have the format <address>#<port> (the #port is optional, if none is indicated then server.port is utilized as the default port).
    • Deprecate all rrdp.* arguments, renaming them to http.*. The new arguments are http.enabled, http.priority, http.retry.count and http.retry.interval. They apply for each outgoing HTTP request.
    • 3 of the 4 TALs now include an HTTPs URI (one of them still hasn't the TA on an HTTPS URI), fixes issue #34.
    • HTTPS requests are now preferred by default over RSYNC requests, this applies only when both of the options are present, related to #34.
    • New incidences for stale manifests (incid-mft-stale) and stale CRLs (incid-crl-stale).
  • Docs

    • Add steps to install Debian package created by Marco D'Itri
    • Add build steps for Gentoo and Alpine.
    • Add docs to build and run the docker image.
    • Update docs to include new arguments http.*, behavior of server.address, and new incidences.
    • Add a section for deprecated arguments.
Choose a tag to compare

The main updates of this release are:

  • Separate validation logs from operation logs, the validation logs are disabled by default.
  • Allow to work with local files if a repository can't be synced.

The public key to verify the tarball is here (it isn't certified yet).

Changes since v1.2.1:

  • Bug fixes

    • Minimize function calls and processing once a fork is made to execute rsync, related to issue #35.
  • Updates

    • Separate the validation messages from the operation messages, each log type has its own configuration arguments.
    • Include a configurable syslog facility for each log type, useful when syslog is utilized.
    • Add new argument stale-repository-period. When a repository URI can't be reached, the validator will log the error messages at the operation log after stale-repository-period seconds had elapsed since the first error fetching the repository URI.
    • Allow to work with local files if a repository can't be synced.
  • Docs

    • Add installation steps for Gentoo, based on an ebuild from issue #23.
    • Update all logging docs, since now there are two types of logs: operation and validation.
    • Update docs to include new argument stale-repository-period.
Choose a tag to compare

The main updates at this release are:

  • Wait for RTR client connections once the first validation cycle is done.
  • Improve SLURM file(s) processing.
  • New incidences related to manifests validation.

The public key to verify the tarball is here (it isn't certified yet).

Changes since v1.2.0:

  • Bug fixes

    • Add broken pipe (SIGPIPE) signal handler, this avoids a sudden death when the socket is still alive at the server but closed at the client side.
    • Don't hold the DB lock when the SLURM is being loaded.
    • Specific for CentOS7 libcurl: check for time condition met/unmet (whenever the HTTP header "If-Modified-Since" is sent) when requesting RRDP update notification files.
    • Stop sending PDUs on reset exchange error.
    • Fix GCC 10 compiling error and warnings, this fixes #32.
  • Updates

    • Wait for client connections at --server.port until the first validation cycle is done.
    • Update internal PDU logs.
    • SLURM upgrades:
      • Improve loading process, use an internal cache when a SLURM file is being loaded.
      • Don't discard the loaded SLURM if there's an error applying it.
      • Calculate SLURM file(s) checksum and compare it with its previous one to avoid loading each SLURM at every validation cycle if there aren't updates.
      • Stop doing unnecessary validations, since they aren't part of the RFC 8416: duplicated elements at the same file, covered prefixes at the same file.
    • Add new incidences related to manifests processing, fixes issue #28. The new incidences are:
      • incid-file-at_mft-not-found (default value: error).
      • incid-file-at-mft-hash-not-match (default value: error).
    • Internal improvements resultant from a code review (thanks to @ydahhrk).
  • Docs

    • Add new incidences documentation: incid-file-at_mft-not-found and incid-file-at-mft-hash-not-match.
    • Add CAP_NET_BIND_SERVICE capability usage (thanks to @rfc1036 for the comment at #22 (comment)).
    • Fix Debian dependencies.
    • Add MALLOC_ARENA_MAX memory tuning quirk, specific for Linux and glibc.
Choose a tag to compare

The main updates at this release are:

The public key to verify the tarball is here (it isn't certified yet).

Changes since v1.1.3:

  • Bug fixes

    • Solve issue #9 "Use previous valid SLURM configuration on SLURM error": whenever there's an error, apply the last valid SLURM version.
    • If an empty value was sent to arguments that expect paths (eg. fort --tal=), this was treated as valid; now this isn't allowed.
    • rsync execution logs didn't logged to syslog, now they do.
    • Allow reuse server address/port on restart.
    • Try to fetch the trust anchor certificate from another URI whenever the previous TAL URI wasn't fetched due to an error.
    • Standard output wasn't flushed when the console logs where piped, now it is flushed.
  • Updates

    • Support RRDP (solves issue #20).
    • Support HTTPS URIs in TALs (solves issue #19).
    • Add new incidence incid-obj-not-der-encoded to validate signed objects DER encoding.
    • Log additional information on start/end of a validation cycle, the information is printed at log level info:
      • When a client starts/ends a connection, or when the connection is killed (print its address and an internal ID).
      • When a new validation cycle is started and finished (includes number of valid Prefixes and Router Keys, current/new serial number, and real execution time).
    • Add setup script to ease ARINs TAL download, explicitly accepting their RPA. The script does the following:
      • Invites to agree ARIN RPA and downloads ARIN's TAL.
      • Downloads the rest of the TALS from github repository.
      • Creates a local repository directory, and an example configuration file.
    • Create examples directory:
      • Move tal directory to this new directory.
      • Add a valid configuration file.
      • Add a valid SLURM file.
    • New configuration arguments added:
    • Update unit tests.
  • Docs

    • Indicate full RFC 8182 and RFC 8630 compliance.
    • Add docs for new configuration parameters (at web docs module 'Program arguments' and user man).
    • Add the usage of the setup script at Installation module, as well as the new dependencies of libcurl and libxml2.
    • Add new section 'Routers', contains a basic explanation of data exchange with routers.
    • Update 'Incidences' module to include DER encoding validation (incid-obj-not-der-encoded).
    • Update RFC compliance of RFC 6488 to 100%.
    • Update READMEs to use relative paths instead of always use master URLs.
    • Replace '2019' year refs to '2020'.