Releases: NICMx/FORT-validator
1.6.4
Improvements since 1.6.3:
- #74, #147: Add
--rsync.transfer-timeout
- #144: Improve compliance with RFC 9589
- #146: Set default HTTP transfer timeout to 900
- df66990: Improve Key Usage validation more
Thanks to Koen van Hove for reporting #74, and @job for pull-requesting #144, #146 and #147.
New CVE: (Pending ID)
1.6.3
Improvements since 1.6.2:
- 780b9f7: Update links to APNIC TALs
- #137: Update API usage for libxml2 2.12+
- #138: Add self-signed certificate signature validation
- #139, #141: Shuffle Manifest entries to complicate attacks relying on traversal order
- #143: Use HTTP compressed encoding when available
- 5689dea: Prevent crash on malformed subjectPublicKey
- 939d988: Prevent crash on malformed Key Usage
- b1eb3c5: Prevent crash on missing Authority Key Identifier
- 4dafbd9: Prevent crash on missing signedAttrs
- 942f921: Prevent crash on missing eContent
- 521b1a0: Prevent crash on BER-encoded signedAttrs
Thanks to @antecrescent for contributing 2, @job for 3-5, and @niklbird and Haya Schulmann for researching and reporting 6-11.
1.6.2
- #106: Fix header version for Code 4 Error PDUs.
- 202e0fe: Bind all --server.address addresses, not just the first that succeeds. (And also a few other tweaks to the bind algorithm.)
- This changed
--server.address
's default value.
- This changed
- 7846f00: Fix bad date management in the cache, which caused files to expire at incorrect timings.
- #122: Add
--mode=print
, an operation mode that Jsonifies an RPKI file into standard output. - #111: Add rtrlib to the docker image.
- #133: Restore the "now you can connect your routers" warning (for the time being).
Harder to notice bugfixes:
- 2278558, 1165270, cc17e13, 17250cb: Improve libcrypto API usage.
- 6d7985b: Fix really bad usage of standard library function
strtol()
.
Also, the documentation now includes a roadmap.
1.6.1
Improvements since 1.6.0:
- #101:
- Enhance portability of unit tests.
- Disable misleading unit test error messages.
- #102: Upgrade
autogen.sh
so theconfigure
script can also be easily generated in OpenBSD and FreeBSD. - #103:
- Remove useless logging messages during startup.
- Stop printing logging severity (
INF
,WRN
,ERR
) in syslog. - 31414cd: Rephrase HTTP GET logs.
- Remove false alarm error message at the end of validation cycle logs:
Cannot generate [rsync URL]'s cage. I'm probably going to end up deleting it from the cache.
- #104: Add
CACHEDIR.TAG
file to cache, to hint backup software not to synchronize it. (See https://bford.info/cachedir/) - ec918ad: Remove bug-induced Cache Resets during RTR communication.
- 161c2af: Automatically clean up cache whenever Fort's version changes.
1.6.0
We are happy to announce the most significant upgrade in a while. Version 1.6.0 is an internal overhaul that improves overall stability and will allow us to implement new features more quickly.
This version is a big step in the new direction that we want to take the project, one where we aim for a high standard of quality and security. Version 1.6.0 fixes several bugs, including some of high severity, so we recommend updating.
Finally, we have redoubled our efforts with the FORT project, so we plan to release more frequently and implement the features that the community needs.
Bug fixes:
- #40: Induce crash on memory allocation failures, to prevent Fort from accidentally advertising incomplete information.
- #71: Implement HTTP redirects.
- #76: Reset
FILE
handle during retries, to prevent HTTP code from dumping unparseable garbage into the local cache. - #77: Treat HTTP response 304 as download success.
- #78: Provide a dedicated namespace for each RRDP notification, to prevent malicious RRDP sources from overriding each other's files.
- #79: Stop caching RRDP sessions and serials on RAM; extract them from actual cached notification files. (This prevents all RRDP from being considered outdated during startup.)
- #80: Deprecate and no-op
rsync.strategy
. (Onlyroot
synchronizations are supported now.) - #94: Merge
ASID.h
andASId.h
into a single module. (Likely used to cause issues cloning the code into case-insensitive filesystems.) - #98: Reduce severity of some RTR disconnection error messages.
- #100: Overhaul of default rsync command argument list.
- Remove ARIN's RPA confirmation from
--init-tals
, since it's no longer required. - Purge old deprecated configuration options:
init-locations
sync-strategy
rrdp.enabled
rrdp.priority
rrdp.retry.count
rrdp.retry.interval
http.idle-timeout
- Deprecate (and no-op) several configuration options:
shuffle-uris
(It was a seemingly pointless function.)stale-repository-period
(The relevant warning no longer exists.)rsync.strategy
(See #80 above.)rsync.arguments-flat
(Flat rsyncs are no longer employed.)thread-pool.validation.max
(It's best if Fort computes this value on its own.)
- Remove deprecated
fort_setup.sh
script. - 2b2f7c3: Remove
SO_REUSEPORT
(a portability liability) from the RTR socket bind. - 6d8081c: Change RRDP serials from
long
s toBIGNUM
s.
(The RFCs define these as "unbounded," which made Fort's old implementation incorrect.) - Rudimentary startup for automatic cache cleanup.
- 63e7194: Allow some
null
s in the configuration JSON.
In case you're parsing Fort's output, please be aware that several logging messages changed. In particular, the functionality that used to print the following message in the operation logs was removed:
The following repositories URIs couldn't be fetched (it can be a local issue or a server issue), please review previous log messages related to such URIs/servers:
Please complain if this affects you.
In addition to all this, the review revealed several instances of unsafe code that yielded undefined behavior that might have caused some of the crashes people have observed over the years. (#46, #65, #83, #89, #99.)
The directory layout of Fort 1.6.0's cache is incompatible with the one from previous versions. To save some disk space, you might want to empty your existing cache during the upgrade.
1.5.4
Improvements since 1.5.3:
- #62: Upgrade HTTP and rsync request logs to INFO
- #64: Patch compilation warnings in clang
- 5464579: Handle HTTP 304 more gracefully
- #86: Patch crash during
x509_name_equals()
(Tentative fix) - #88: Improve CA/EE certificate identification code
- 3412087: Fix deprecation warnings from newer versions of libcrypto
- b027fb4: Remove lots of unnecessary stack traces
1.5.3: The "NCSC release"
This release also contains security patches. Upgrading is strongly recommended.
1.5.3 addresses the security vulnerabilities recently disclosed by the NCSC:
- https://labs.ripe.net/author/koen-van-hove/improving-the-resiliency-of-rpki-relying-party-software/
- https://english.ncsc.nl/latest/news/2021/october/29/upcoming-announcement-of-rpki-cvd-procedure
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 pathrsync://example.org/../../etc/not-a-virus
? 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.
1.5.2
Improvements since 1.5.1:
- #51: Fix crash when
--server.address
is not defined in the configuration. - 673c679: Change
autogen.sh
's interpreter to/bin/sh
. (Allows straightforward compilation on default *BSDs.) - #53: Add RPM packages to the release.
- #55: Fix situational crash due to bad code cleanup.
- eb68ebb, 274dc14: Performance optimizations.
- #57: Fix practically inevitable crash in server mode's second iteration.
- #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.
v1.5.1
Changes:
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:
- 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.)
- 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
- Update the TAL URLs. (The old ones were very obsolete.)
- Add
--init-as0-tals
. (Used to download the ASN0 TALs.) - Deprecate and zero-op
--init-locations
. (Didn't make sense. If the user needs a different URL, they can do curl or wget instead.) - Deprecate
fort_setup.sh
. (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()
andfclose()
duringvalid_file_or_dir()
. (Ifstat()
is used instead offstat()
, 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.
v1.5.0
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
- Add links for router OS configurations (Mikrotik, Nokia, Arista, and Huawei) at Routers - Router configuration.
- Add "Quick Start" section at Home and README.