Today, we’re releasing Ferron 3.0.0-beta.10, the tenth beta version of what it would be Ferron 3. This release involves security hardening, HTTP/3 stabilization, correctness for your services, and more.
Breaking changes
But first, let’s talk about the breaking changes.
First, Ferron 3 uses a linear-time regular expression engine instead of a backtracking one, which means that backtracking regex patterns are no longer supported. This change was made to avoid potential ReDoS and catastrophic backtracking issues. If you are using syntax such as (?= ...), (?! ...), (?<= ...), (?<! ...), or \1, you need to rewrite the regexes.
Also, following symlinks during static file resolution from webroot is now disabled by default for symlink attack prevention. Check if web application uses symlinks (if it uses, use disable_symlinks false or a similar setting).
Also we reduced the DNS provider support for automatic TLS DNS-01 challenge to a minimal set of providers, to keep Ferron lightweight and lean. Supported providers are now rfc2136, route53, bunny, digitalocean, cloudflare, dnsimple, googlecloud, ovh, spaceship, porkbun, and desec. We’ve also added command provider for custom DNS update code.
Finally, tls { ocsp { enabled true } } and basic_auth { brute_force_protection { enabled true } } are no longer effective and are replaced with tls { ocsp } and basic_auth { brute_force_protection } respectively, to improve consistency across configuration directives (that use flag syntax like cache false).
HTTP/3 stabilization
Ferron 3 now has HTTP/3 support no longer declared experimental (backed by our zincio-http implementation instead of experimental h3). We have now also enabled HTTP/3 by default during the stabilization.
HTTP/3 addresses head-of-line blocking by using QUIC, which is built on top of UDP (in comparison to HTTP/2, which uses TCP), improving website performance on unstable networks like mobile or satellite.
Also, after seeing a GitHub issue after HTTP/3 issues with curl, we fixed the HTTP/3 stream reset errors.
QUIC packet loss fixes
Going from HTTP/3 to QUIC, we found that the routing logic introduced in Ferron 3.0.0-beta.9 introduced packet loss due to improper routing of packets by the QUIC transport.
This has been fixed to improve packet routing (via IP hashing when initializing and connection ID hashing later on) and reduce packet loss.
This should improve reliability of QUIC and HTTP/3 connections.
Reverse proxy resilience
When using Ferron as a reverse proxy and then a backend fails while HTTP request is sent, if the request method is idempotent and body is not sent yet, Ferron will now retry the request (once by default) instead of bailing out.
You can configure this:
example.com
proxy {
upstream http://localhost:3000/
max_retries_per_upstream 2
}
}HTTP cache Vary correctness
We have found that a bug (which has been introduced in Ferron 3.0.0-beta.9) led to some header names in Vary header values (If-Match, If-Modified-Since, If-None-Match, If-Range, If-Unmodified-Since, Range) being ignored by the cache. This led to wrong 304 responses being served occasionally, which would be seen by website visitors as broken websites and blank pages.
This has been fixed by not ignoring the specified header values
h2c listener support
Ferron 3.0.0-beta.10 adds support for h2c (HTTP/2 cleartext) listeners on top of existing HTTP/1.x and HTTP/2 support.
This could be useful when hosting microservices or applications that use gRPC (built on top of HTTP/2) in some way.
We didn’t add h2c upgrade support (only h2c with prior knowledge), as this has been deprecated from the current HTTP/2 specification (RFC 9113).
This can be enabled using this configuration:
{
http {
protocols h2c # Note: HTTP/1.x cannot be used here
}
default_https_port false
}
api.example.com {
location /api/some {
proxy {
upstream http://somemicroservice:3000/
http2_only # Use HTTP/2 only to allow gRPC proxying
}
}
}Many correctness fixes
Ferron 3.0.0-beta.10 contains multiple correctness fixes, such as:
- IPv4 host blocks never matching: fixed IPv4 host never matching due to IP address canonicalization issues and IPv4-mapped IPv6 addresses.
- Stray
}fix: earlier, stray}characters inferron.conffiles could cause an infinite loop. These are now properly handled by erroring out. - High-cardinality metric removed: the
ferron.proxy.lb.selectionswith high-cardinalityferron.proxy.lb.scoreattribute has been removed to prevent exhaustion of metric storage. - Fixed
deny_ipsbypass using non-canonical IP representations: previously,deny_ipscould be bypassed using non-canonical IP address representations (such as0x7f.0.0.1or2130706433). This has been fixed to normalize the IP addresses first. - Ranges beyond the end correctness: the server now returns
416 Range Not Satisfiablewhen a range request start exceeds the available content length. - Configured HTTP responses after HTTP -> HTTPS redirects: HTTP responses configured to be served after the
https_redirectstage will now only be served after a successful HTTP-to-HTTPS redirection. This ensures that these responses are not served before the client is redirected, which could lead to unexpected behavior or security issues.
Looking ahead
Ferron 3 beta is still improving when it comes to correctness and stability for your web services. The remaining beta versions will focus on final polish, stabilizing the ecosystem, and preparing for our first release candidate.
As always, feedback, bug reports, and testing results are welcome.
Full changelog
You can see the complete changelog for Ferron 3.0.0-beta.10 in the release notes.
Try it
- Documentation: https://ferron.sh/docs/v3
- GitHub repo: https://github.com/ferronweb/ferron/tree/develop-3.x
Install Ferron 3 using the installer:
sudo bash -c "$(curl -fsSL https://get.ferron.sh/v3)"