Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

0.9.3 #212

Merged
merged 21 commits into from
Nov 1, 2024
Merged

0.9.3 #212

Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
21 commits
Select commit Hold shift + click to select a range
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
30 changes: 30 additions & 0 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,16 @@ jobs:
platform: linux/arm64
tags-suffix: "-slim"

- target: "musl"
build-feature: "-slim-pq"
platform: linux/amd64
tags-suffix: "-slim-pq"

- target: "musl"
build-feature: "-slim-pq"
platform: linux/arm64
tags-suffix: "-slim-pq"

- target: "gnu"
build-feature: "-s2n"
platform: linux/amd64
Expand All @@ -44,6 +54,26 @@ jobs:
platform: linux/arm64
tags-suffix: "-s2n"

- target: "gnu"
build-feature: "-pq"
platform: linux/amd64
tags-suffix: "-pq"

- target: "gnu"
build-feature: "-pq"
platform: linux/arm64
tags-suffix: "-pq"

- target: "gnu"
build-feature: "-s2n-pq"
platform: linux/amd64
tags-suffix: "-s2n-pq"

- target: "gnu"
build-feature: "-s2n-pq"
platform: linux/arm64
tags-suffix: "-s2n-pq"

- target: "gnu"
build-feature: "-webpki-roots"
platform: linux/amd64
Expand Down
37 changes: 37 additions & 0 deletions .github/workflows/release_docker.yml
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,17 @@ jobs:
jqtype/rpxy:latest
ghcr.io/junkurihara/rust-rpxy:latest

- target: "default-pq"
dockerfile: ./docker/Dockerfile
platforms: linux/amd64,linux/arm64
build-args: |
"CARGO_FEATURES=--no-default-features --features=http3-quinn,cache,rustls-backend,acme,post-quantum"
tags-suffix: "-pq"
# Aliases must be used only for release builds
aliases: |
jqtype/rpxy:pq
ghcr.io/junkurihara/rust-rpxy:pq

- target: "default-slim"
dockerfile: ./docker/Dockerfile-slim
build-contexts: |
Expand All @@ -42,6 +53,20 @@ jobs:
jqtype/rpxy:slim
ghcr.io/junkurihara/rust-rpxy:slim

- target: "default-slim-pq"
dockerfile: ./docker/Dockerfile-slim
build-args: |
"CARGO_FEATURES=--no-default-features --features=http3-quinn,cache,rustls-backend,acme,post-quantum"
build-contexts: |
messense/rust-musl-cross:amd64-musl=docker-image://messense/rust-musl-cross:x86_64-musl
messense/rust-musl-cross:arm64-musl=docker-image://messense/rust-musl-cross:aarch64-musl
platforms: linux/amd64,linux/arm64
tags-suffix: "-slim-pq"
# Aliases must be used only for release builds
aliases: |
jqtype/rpxy:slim-pq
ghcr.io/junkurihara/rust-rpxy:slim-pq

- target: "s2n"
dockerfile: ./docker/Dockerfile
build-args: |
Expand All @@ -54,6 +79,18 @@ jobs:
jqtype/rpxy:s2n
ghcr.io/junkurihara/rust-rpxy:s2n

- target: "s2n-pq"
dockerfile: ./docker/Dockerfile
build-args: |
"CARGO_FEATURES=--no-default-features --features=http3-s2n,cache,rustls-backend,acme,post-quantum"
"ADDITIONAL_DEPS=pkg-config libssl-dev cmake libclang1 gcc g++"
platforms: linux/amd64,linux/arm64
tags-suffix: "-s2n-pq"
# Aliases must be used only for release builds
aliases: |
jqtype/rpxy:s2n-pq
ghcr.io/junkurihara/rust-rpxy:s2n-pq

- target: "webpki-roots"
dockerfile: ./docker/Dockerfile
platforms: linux/amd64,linux/arm64
Expand Down
4 changes: 4 additions & 0 deletions .gitmodules
Original file line number Diff line number Diff line change
Expand Up @@ -4,3 +4,7 @@
[submodule "submodules/rustls-acme"]
path = submodules/rustls-acme
url = [email protected]:junkurihara/rustls-acme.git
[submodule "submodules/s2n-quic"]
path = submodules/s2n-quic
url = [email protected]:junkurihara/s2n-quic.git
branch = rustls-pq
4 changes: 4 additions & 0 deletions .rustfmt.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
edition = "2021"
newline_style = "Unix"
tab_spaces = 2
max_width = 130
10 changes: 10 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,16 @@

## 0.10.0 (Unreleased)

## 0.9.3

### Improvement

- Feat: Support post-quantum `X25519Kyber768Draft00` for incoming and outgoing TLS initiation. This is non-default feature [feature: `post-quantum`].
- Feat: emit WARN messages if there exist unused and unsupported options specified in configuration file.
- Docs: `rpxy.io` is now available for the official website of `rpxy`.
- Refactor: lots of minor improvements
- Deps

## 0.9.2

### Improvement
Expand Down
2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
[workspace.package]
version = "0.9.2"
version = "0.9.3"
authors = ["Jun Kurihara"]
homepage = "https://github.com/junkurihara/rust-rpxy"
repository = "https://github.com/junkurihara/rust-rpxy"
Expand Down
4 changes: 3 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,10 +14,12 @@

[^pure_rust]: Doubtfully can be claimed to be written in pure Rust since current `rpxy` is based on `aws-lc-rs` for cryptographic operations.

By default, `rpxy` provides the *TLS connection sanitization* by correctly binding a certificate used to establish a secure channel with the backend application. Specifically, it always keeps the consistency between the given SNI (server name indication) in `ClientHello` of the underlying TLS and the domain name given by the overlaid HTTP HOST header (or URL in Request line) [^1]. Additionally, as a somewhat unstable feature, our `rpxy` can handle the brand-new HTTP/3 connection thanks to [`quinn`](https://github.com/quinn-rs/quinn), [`s2n-quic`](https://github.com/aws/s2n-quic) and [`hyperium/h3`](https://github.com/hyperium/h3).[^h3lib] Furthermore, `rpxy` supports the automatic issuance and renewal of certificates via [TLS-ALPN-01 (RFC8737)](https://www.rfc-editor.org/rfc/rfc8737) of [ACME protocol (RFC8555)](https://www.rfc-editor.org/rfc/rfc8555) thanks to [`rustls-acme`](https://github.com/FlorianUekermann/rustls-acme).
By default, `rpxy` provides the *TLS connection sanitization* by correctly binding a certificate used to establish a secure channel with the backend application. Specifically, it always keeps the consistency between the given SNI (server name indication) in `ClientHello` of the underlying TLS and the domain name given by the overlaid HTTP HOST header (or URL in Request line) [^1]. Additionally, as a somewhat unstable feature, our `rpxy` can handle the brand-new HTTP/3 connection thanks to [`quinn`](https://github.com/quinn-rs/quinn), [`s2n-quic`](https://github.com/aws/s2n-quic) and [`hyperium/h3`](https://github.com/hyperium/h3).[^h3lib] Furthermore, `rpxy` supports the automatic issuance and renewal of certificates via [TLS-ALPN-01 (RFC8737)](https://www.rfc-editor.org/rfc/rfc8737) of [ACME protocol (RFC8555)](https://www.rfc-editor.org/rfc/rfc8555) thanks to [`rustls-acme`](https://github.com/FlorianUekermann/rustls-acme), and the hybridized post-quantum key exchange [`X25519Kyber768Draft00`](https://datatracker.ietf.org/doc/draft-tls-westerbaan-xyber768d00/)[^kyber] for TLS incoming and outgoing initiation thanks to [`rustls-post-quantum`](https://docs.rs/rustls-post-quantum/latest/rustls_post_quantum/).

[^h3lib]: HTTP/3 libraries are mutually exclusive. You need to explicitly specify `s2n-quic` with `--no-default-features` flag. Also note that if you build `rpxy` with `s2n-quic`, then it requires `openssl` just for building the package.

[^kyber]: This is not yet a default feature. You need to specify `--features post-quantum` when building `rpxy`. Also note that `X25519Kyber768Draft00` is a draft version yet this is widely used on the Internet. We will update the feature when the newest version (`X25519MLKEM768` in [`ECDHE-MLKEM`](https://www.ietf.org/archive/id/draft-kwiatkowski-tls-ecdhe-mlkem-02.html)) is available.

This project is still *work-in-progress*. But it is already working in some production environments and serves a number of domain names. Furthermore it *significantly outperforms* NGINX and Caddy, e.g., *1.5x faster than NGINX*, in the setting of a very simple HTTP reverse-proxy scenario (See [`bench`](./bench/) directory).

[^1]: We should note that NGINX doesn't guarantee such a consistency by default. To this end, you have to add `if` statement in the configuration file in NGINX.
Expand Down
4 changes: 2 additions & 2 deletions config-example.toml
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,8 @@ listen_port = 8080
listen_port_tls = 8443

# Optional. If you listen on a custom port like 8443 but redirect with firewall to 443
# When you specify this, the server sends a redirection response 301 with specified port to the client for plaintext http request.
# Otherwise, the server sends 301 with the same port as `listen_port_tls`.
# When you specify this, the server uses this port in an "Alt-SVC" header for e.g. indicating support for HTTP/3 and also sends a redirection response 301 with specified port to the client for plaintext http request
# Otherwise, the server sends Alt-SVC and 301 with the same port as `listen_port_tls`.
# https_redirection_port = 443

# Optional for h2 and http1.1
Expand Down
2 changes: 2 additions & 0 deletions docker/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -32,12 +32,14 @@ Differences among tags are summarized as follows.
- `latest`: Built from the `main` branch with default features, running on Ubuntu.
- `latest-slim`, `slim`: Built by `musl` from the `main` branch with default features, running on Alpine.
- `latest-s2n`, `s2n`: Built from the `main` branch with the `http3-s2n` feature, running on Ubuntu.
- `*-pq`: Built with the `post-quantum` feature. This feature supports the post-quantum key exchange using `rustls-post-quantum` crate.

### Nightly Builds

- `nightly`: Built from the `develop` branch with default features, running on Ubuntu.
- `nightly-slim`: Built by `musl` from the `develop` branch with default features, running on Alpine.
- `nightly-s2n`: Built from the `develop` branch with the `http3-s2n` feature, running on Ubuntu.
- `*-pq`: Built with the `post-quantum` feature. This feature supports the hybridized post-quantum key exchange using `rustls-post-quantum` crate.

## Caveats

Expand Down
10 changes: 7 additions & 3 deletions rpxy-acme/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -10,25 +10,29 @@ readme.workspace = true
edition.workspace = true
publish.workspace = true

[features]
post-quantum = ["rustls-post-quantum"]

[dependencies]
url = { version = "2.5.2" }
rustc-hash = "2.0.0"
thiserror = "1.0.64"
thiserror = "1.0.66"
tracing = "0.1.40"
async-trait = "0.1.83"
base64 = "0.22.1"
aws-lc-rs = { version = "1.10.0", default-features = false, features = [
"aws-lc-sys",
] }
blocking = "1.6.1"
rustls = { version = "0.23.14", default-features = false, features = [
rustls = { version = "0.23.16", default-features = false, features = [
"std",
"aws_lc_rs",
] }
rustls-platform-verifier = { version = "0.3.4" }
rustls-acme = { path = "../submodules/rustls-acme/", default-features = false, features = [
"aws-lc-rs",
] }
tokio = { version = "1.40.0", default-features = false }
rustls-post-quantum = { version = "0.1.0", optional = true }
tokio = { version = "1.41.0", default-features = false }
tokio-util = { version = "0.7.12", default-features = false }
tokio-stream = { version = "0.1.16", default-features = false }
3 changes: 3 additions & 0 deletions rpxy-acme/src/manager.rs
Original file line number Diff line number Diff line change
Expand Up @@ -37,8 +37,11 @@ impl AcmeManager {
domains: &[String],
runtime_handle: Handle,
) -> Result<Self, RpxyAcmeError> {
#[cfg(not(feature = "post-quantum"))]
// Install aws_lc_rs as default crypto provider for rustls
let _ = rustls::crypto::CryptoProvider::install_default(rustls::crypto::aws_lc_rs::default_provider());
#[cfg(feature = "post-quantum")]
let _ = rustls::crypto::CryptoProvider::install_default(rustls_post_quantum::provider());

let acme_registry_dir = acme_registry_dir
.map(|v| v.to_ascii_lowercase())
Expand Down
10 changes: 7 additions & 3 deletions rpxy-bin/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@ publish.workspace = true
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html

[features]
# default = ["http3-quinn", "cache", "rustls-backend", "acme", "post-quantum"]
# default = ["http3-s2n", "cache", "rustls-backend", "acme", "post-quantum"]
default = ["http3-quinn", "cache", "rustls-backend", "acme"]
# default = ["http3-s2n", "cache", "rustls-backend", "acme"]
http3-quinn = ["rpxy-lib/http3-quinn"]
Expand All @@ -22,17 +24,18 @@ rustls-backend = ["rpxy-lib/rustls-backend"]
webpki-roots = ["rpxy-lib/webpki-roots"]
cache = ["rpxy-lib/cache"]
acme = ["rpxy-lib/acme", "rpxy-acme"]
post-quantum = ["rpxy-lib/post-quantum"]

[dependencies]
rpxy-lib = { path = "../rpxy-lib/", default-features = false, features = [
"sticky-cookie",
] }

mimalloc = { version = "*", default-features = false }
anyhow = "1.0.89"
anyhow = "1.0.91"
rustc-hash = "2.0.0"
serde = { version = "1.0.210", default-features = false, features = ["derive"] }
tokio = { version = "1.40.0", default-features = false, features = [
serde = { version = "1.0.214", default-features = false, features = ["derive"] }
tokio = { version = "1.41.0", default-features = false, features = [
"net",
"rt-multi-thread",
"time",
Expand All @@ -47,6 +50,7 @@ futures-util = { version = "0.3.31", default-features = false }
clap = { version = "4.5.20", features = ["std", "cargo", "wrap_help"] }
toml = { version = "0.8.19", default-features = false, features = ["parse"] }
hot_reload = "0.1.6"
serde_ignored = "0.1.10"

# logging
tracing = { version = "0.1.40" }
Expand Down
17 changes: 16 additions & 1 deletion rpxy-bin/src/config/toml.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
use crate::{
constants::*,
error::{anyhow, ensure},
log::warn,
};
use rpxy_lib::{reexports::Uri, AppConfig, ProxyConfig, ReverseProxyConfig, TlsConfig, UpstreamUri};
use rustc_hash::FxHashMap as HashMap;
Expand Down Expand Up @@ -229,7 +230,21 @@ impl ConfigToml {
pub fn new(config_file: &str) -> std::result::Result<Self, anyhow::Error> {
let config_str = fs::read_to_string(config_file)?;

toml::from_str(&config_str).map_err(|e| anyhow!(e))
// Check unused fields during deserialization
let t = toml::de::Deserializer::new(&config_str);
let mut unused = rustc_hash::FxHashSet::default();

let res = serde_ignored::deserialize(t, |path| {
unused.insert(path.to_string());
})
.map_err(|e| anyhow!(e));

if !unused.is_empty() {
let str = unused.iter().fold(String::new(), |acc, x| acc + x + "\n");
warn!("Configuration file contains unsupported fields. Check typos:\n{}", str);
}

res
}
}

Expand Down
8 changes: 5 additions & 3 deletions rpxy-certs/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -12,16 +12,17 @@ publish.workspace = true

[features]
default = ["http3"]
post-quantum = ["rustls-post-quantum"]
http3 = []

[dependencies]
rustc-hash = { version = "2.0.0" }
tracing = { version = "0.1.40" }
derive_builder = { version = "0.20.2" }
thiserror = { version = "1.0.64" }
thiserror = { version = "1.0.66" }
hot_reload = { version = "0.1.6" }
async-trait = { version = "0.1.83" }
rustls = { version = "0.23.14", default-features = false, features = [
rustls = { version = "0.23.16", default-features = false, features = [
"std",
"aws_lc_rs",
] }
Expand All @@ -30,10 +31,11 @@ rustls-webpki = { version = "0.102.8", default-features = false, features = [
"std",
"aws_lc_rs",
] }
rustls-post-quantum = { version = "0.1.0", optional = true }
x509-parser = { version = "0.16.0" }

[dev-dependencies]
tokio = { version = "1.40.0", default-features = false, features = [
tokio = { version = "1.41.0", default-features = false, features = [
"rt-multi-thread",
"macros",
] }
7 changes: 5 additions & 2 deletions rpxy-certs/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ mod log {
use crate::{error::*, log::*, reloader_service::DynCryptoSource};
use hot_reload::{ReloaderReceiver, ReloaderService};
use rustc_hash::FxHashMap as HashMap;
use rustls::crypto::{aws_lc_rs, CryptoProvider};
use rustls::crypto::CryptoProvider;
use std::sync::Arc;

/* ------------------------------------------------ */
Expand Down Expand Up @@ -44,8 +44,11 @@ where
T: CryptoSource<Error = RpxyCertError> + Send + Sync + Clone + 'static,
{
info!("Building certificate reloader service");
#[cfg(not(feature = "post-quantum"))]
// Install aws_lc_rs as default crypto provider for rustls
let _ = CryptoProvider::install_default(aws_lc_rs::default_provider());
let _ = CryptoProvider::install_default(rustls::crypto::aws_lc_rs::default_provider());
#[cfg(feature = "post-quantum")]
let _ = CryptoProvider::install_default(rustls_post_quantum::provider());

let source = crypto_source_map
.iter()
Expand Down
3 changes: 3 additions & 0 deletions rpxy-certs/src/server_crypto.rs
Original file line number Diff line number Diff line change
Expand Up @@ -179,7 +179,10 @@ mod tests {

#[tokio::test]
async fn test_server_crypto_base_try_into() {
#[cfg(not(feature = "post-quantum"))]
let _ = CryptoProvider::install_default(rustls::crypto::aws_lc_rs::default_provider());
#[cfg(feature = "post-quantum")]
let _ = CryptoProvider::install_default(rustls_post_quantum::provider());

let mut server_crypto_base = ServerCryptoBase::default();

Expand Down
Loading
Loading