rpxy: a Rust reverse proxy that terminates TLS and refuses domain fronting
A simple and ultrafast http reverse proxy serving multiple domain names and terminating TLS for http/1.1, 2 and 3, written in Rust
At a glance
- What is it?
- rpxy is a Layer 7 reverse proxy written in Rust that routes several domain names to their backends while terminating TLS for HTTP/1.1, HTTP/2 and HTTP/3, with ACME issuance, mutual TLS, post-quantum key exchange and load balancing. The README is unusually candid that it is a work in progress and makes no performance ranking claims.
- Who is it for?
- Adopt rpxy if you want a single small binary to terminate TLS for several domain names, run HTTP/3, obtain certificates automatically and stop domain fronting at the edge. Do not adopt it for TCP or UDP workloads, because the README says so explicitly and points to a separate Layer 4 project, and do not adopt it in an environment that needs a hardened proxy with a long support history.
- Can I use it commercially?
- Yes. MIT is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
- Is it still maintained?
- Yes. The repository last received commits 1 day ago.
- What is it written in?
- Mainly Rust, according to GitHub's language statistics.
Answers come from the project's GitHub data, last synced on October 24, 2026, and from our analysis. They are not legal advice.
Editorial analysis
A Layer 7 proxy, not a Layer 4 one
rpxy is a simple and ultrafast HTTP reverse proxy that serves multiple domain names and terminates TLS for HTTP/1.1, HTTP/2 and HTTP/3, written in Rust. The README states it plainly as a work-in-progress project that is being evolved.
The first thing to establish is the layer, because the README puts a note about it immediately. This is an HTTP, that is Layer 7, reverse proxy. If you are looking for a TCP or UDP, that is Layer 4, reverse proxy, the README points to a separate project called rpxy-l4. The distinction is not pedantic, because a Layer 7 proxy reads and rewrites requests and can route on host and path, while a Layer 4 proxy only forwards byte streams and routes on address and port.
The implementation rests on hyper, rustls and tokio, and the project describes itself as written in Rust. The footnote attached to that claim is worth reading, because it is unusually honest: it says it is questionable whether this can be claimed to be written in pure Rust, since the current rpxy is based on aws-lc-rs for cryptographic operations. aws-lc-rs is a C library with a Rust binding, so the cryptography in the TLS stack is not pure Rust even though the rest of the stack is.
The project is also open about where it stands. The README says it is already working in some production environments and serving a number of domain names, while also saying plainly that it is still work in progress.
HTTP/3, mutual TLS, ACME and post-quantum key exchange
The supported features list is where this project is more ambitious than the word simple might suggest.
On protocols, HTTP/1.1, HTTP/2 and HTTP/3 are all supported, and gRPC works as well. HTTP/3 is enabled through quinn, s2n-quic and hyperium/h3, and the footnote explains that the HTTP/3 libraries are mutually exclusive, so you have to specify s2n-quic explicitly with the --no-default-features flag, and that a build with s2n-quic requires openssl just for building the package. The default build uses quinn.
On certificates, mutual TLS with client certificates is supported, and certificate issuance and renewal is automated through the TLS-ALPN-01 mechanism of the ACME protocol, using the rustls-acme library.
On the cryptography, the project supports the hybridised post-quantum key exchange X25519MLKEM768 for both TLS and QUIC, incoming and outgoing, using the aws-lc-rs crypto provider with the prefer-post-quantum feature, which the README says is already a default feature. It also notes that X25519MLKEM768 is still a draft version, while being widely used on the internet.
That combination of post-quantum key exchange, HTTP/3 and automatic ACME issuance in one small binary is the actual pitch. Each of those is a configuration problem in a conventional deployment, and here they are defaults.
TLS connection sanitization against domain fronting
The feature with the clearest security argument is TLS connection sanitization, which the README describes as a way to avoid domain fronting.
The mechanism is a binding between the certificate and the backend application. By default rpxy maintains consistency between the SNI server name indication given in the ClientHello of the underlying TLS connection and the domain name given by the overlaid HTTP HOST header, or the URL in the request line. If a client presents one name in the TLS handshake and sends a different name in the HTTP request, the proxy rejects the mismatch rather than forwarding it.
The comparison the README draws is telling: NGINX does not guarantee such consistency by default, and to achieve it in NGINX you have to add an if statement in the configuration file. Domain fronting is the technique where a client uses a certificate for a domain it controls to reach a different domain hosted on the same edge, and it defeats origin-level host based access control.
So the feature is not a performance item, it is a policy item, and the implementation is the kind of thing that is much easier to get right when it is the default behaviour of the proxy rather than a configuration snippet somebody has to remember.
Load balancing, sticky sessions and recovering the client address
The remaining operational features fall into two groups.
The first is load balancing, with round-robin, random and sticky sessions supported. Sticky sessions are the interesting one for anyone running more than one backend: with a session affinity mechanism you can keep a user on the same backend, which matters when the backend holds session state in memory.
The second is the HAProxy PROXY Protocol, supported inbound in both v1 and v2. Its purpose is to recover the original client IP when rpxy sits behind a Layer 4 proxy, and the README names the sibling project rpxy-l4 as the typical example of that arrangement. The reason it is needed is straightforward: once the connection is proxied at the transport layer, the address the Layer 7 proxy sees is the address of the proxy in front of it, so the real client address is lost unless the layer below passes it along.
Together these two features are what turns a single process into something you can put in front of a fleet of backends and still get useful logs and sensible session behaviour out of it.
Building it, and the platforms that cannot build it
The build instructions are short, and the sequence matters because the project vendors its dependencies as submodules.
% git clone https://github.com/junkurihara/rust-rpxy
% cd rust-rpxy
% git submodule update --init
% cargo build --releaseThe default build enables QUIC and HTTP/3 through quinn. If you want s2n-quic instead, the build is a different one, and the README warns that you may need several additional dependencies:
% cargo build --no-default-features --features http3-s2n --releaseEither way the result is an executable at rust-rpxy/target/release/rpxy.
The platform limits are stated as notes and they are specific. At this point it can be built only on Linux, macOS and some Unix-like operating systems, with issue 150 and pull request 478 referenced, and if you want to run rpxy on Windows the README suggests using the Docker image as a workaround.
There is also no installation via crates.io, that is no cargo install, at this point since some dependencies are not yet published, and the Docker image is offered as the easiest way for amd64 environments. The Cargo manifest backs this up: the workspace sets publish = false, so the crate is not meant to be consumed from the registry.
The release profile is tuned for a proxy: fat link time optimisation, one codegen unit, incremental compilation off, panic set to abort, and symbols stripped.
Where to get a binary, and who to trust with it
The distribution story has three routes, and the README is careful about the difference between them.
The first is the Docker image, published as jqtype/rpxy, with a badge for its image size. The README calls it the easiest way for amd64 environments and the recommended workaround for Windows.
The second is the prebuilt binaries on the GitHub Releases page, and this is the one the README points at when you want to run the latest release.
The third is the RPM and DEB packages hosted at rpxy.gamerboy59.dev, provided by a third party, with the build scripts in the .build directory of the repository. The warning attached to them is worth reading in full: these packages are built and distributed by a third party, they may lag behind the latest release of rpxy, sometimes by several versions, and since new releases often include security-related fixes and improvements, you should check the packaged version before installation.
That warning is the reason to prefer the GitHub binaries or the Docker image for anything that is not a throwaway test environment. A reverse proxy sitting in front of several domains is a component where being a few versions behind is a security decision you have to make consciously.
For running the proxy itself, the README says rpxy always refers to a configuration file in TOML format, and an example called config-example.toml is in the repository.
Where rpxy is the wrong tool
Three cases point elsewhere.
The first is TCP and UDP traffic. The README says so at the top of the document and points to rpxy-l4, and that is the right answer for a database port or a game server that speaks its own protocol.
The second is a deployment that needs the long tail of a mature proxy. rpxy covers HTTP/1.1, HTTP/2, HTTP/3, gRPC, mutual TLS, ACME, load balancing and PROXY protocol, and the README even marks the work in progress. What it does not describe is the operational surface of the incumbent: a large plugin ecosystem, a configuration language with a long history of subtle behaviour, and a decade of people who know how to debug it. For a public facing edge, that accumulated knowledge has value.
The third is a Windows host. The build does not work there, so the Docker route is the only option, and if your infrastructure does not run containers for the edge, that is a disqualifier rather than an inconvenience.
One more caution, on the project rather than the software. The bench directory contains a reverse-proxy benchmarking harness that you can run on your own target, and the README is explicit that reverse-proxy performance is highly dependent on hardware, configuration and environment, so it makes no performance-ranking claim. That is the right thing to say, and it also means the word ultrafast in the project description is a design goal rather than a measurement you can rely on. Benchmark it on your own traffic before you make an architecture decision.
Editorial conclusion
Adopt rpxy if you want a single small binary to terminate TLS for several domain names, run HTTP/3, obtain certificates automatically and stop domain fronting at the edge. Do not adopt it for TCP or UDP workloads, because the README says so explicitly and points to a separate Layer 4 project, and do not adopt it in an environment that needs a hardened proxy with a long support history. Verify three things first: that you can build it on your platform, since the README states it can currently be built only on Linux, macOS and some Unix-like systems and that Windows users should use the Docker image; which HTTP/3 implementation you want, since the quinn and s2n-quic backends are mutually exclusive and s2n-quic needs an explicit feature flag and openssl at build time; and how you obtain packages, because there is no crates.io install yet, the RPM and DEB builds come from a third party who warns they may lag by several versions, and the GitHub release binaries are the ones that are current. The licence is MIT, the last push was on 2026-10-15, and the newest release is 0.14.0 dated 2026-07-19.
Frequently asked questions
What is rpxy and what layer does it operate at?
It is a simple and lightweight reverse proxy written in Rust that routes multiple hostnames to backend servers while terminating TLS, for HTTP/1.1, HTTP/2 and HTTP/3 with gRPC support. The README states it is an HTTP, that is Layer 7, reverse proxy, and points to a separate project for TCP or UDP, Layer 4, workloads.
How does rpxy handle certificates?
It supports automated certificate issuance and renewal through the TLS-ALPN-01 mechanism of the ACME protocol using the rustls-acme library, and it supports mutual TLS authentication with client certificates.
What is TLS connection sanitization in rpxy?
It is the default behaviour that binds the certificate used for the TLS channel to the backend application, keeping the SNI name in the ClientHello consistent with the HTTP HOST header or the URL in the request line. The README notes that NGINX does not guarantee this by default and needs an if statement in its configuration to achieve it.
How do I build rpxy from source?
Clone the repository, run git submodule update --init and then cargo build --release, which enables QUIC and HTTP/3 through quinn. For s2n-quic you build with --no-default-features --features http3-s2n --release. The binary ends up at rust-rpxy/target/release/rpxy, and the build currently works on Linux, macOS and some Unix-like systems only.
Can I install rpxy with cargo install?
Not at the moment. The README says there is no installation option via crates.io since some dependencies are not yet published, and the Cargo manifest sets publish = false. The Docker image or the prebuilt binaries on the GitHub Releases page are the alternatives, and the third party RPM and DEB packages may lag several versions behind.
Official sources
Add this badge to your README
If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.
[](https://hysenlabs.com/projects/junkurihara-rust-rpxy)Was this useful?