Giter VIP home page Giter VIP logo

rust-rpxy's Introduction

rpxy: A simple and ultrafast reverse-proxy serving multiple domain names with TLS termination, written in Rust

License: MIT Unit Test Docker ShiftLeft Scan Docker Image Size (latest by date)

WIP Project

Introduction

rpxy [ahr-pik-see] is an implementation of simple and lightweight reverse-proxy with some additional features. The implementation is based on hyper, rustls and tokio, i.e., written in Rust 1. Our rpxy routes multiple host names to appropriate backend application servers while serving TLS connections.

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) 2. Additionally, as a somewhat unstable feature, our rpxy can handle the brand-new HTTP/3 connection thanks to quinn, s2n-quic and hyperium/h3.3 Furthermore, rpxy supports the automatic issuance and renewal of certificates via TLS-ALPN-01 (RFC8737) of ACME protocol (RFC8555) thanks to rustls-acme.

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 directory).

Installing/Building an Executable Binary of rpxy

You can build an executable binary yourself by checking out this Git repository.

# Cloning the git repository
% git clone https://github.com/junkurihara/rust-rpxy
% cd rust-rpxy

# Update submodules
% git submodule update --init

# Build (default: QUIC and HTTP/3 is enabled using `quinn`)
% cargo build --release

# If you want to use `s2n-quic`, build as follows. You may need several additional dependencies.
% cargo build --no-default-features --features http3-s2n --release

Then you have an executive binary rust-rpxy/target/release/rpxy.

Note that we do not have an option of installation via crates.io, i.e., cargo install, at this point since some dependencies are not published yet. Alternatively, you can use docker image (see below) as the easiest way for amd64 environment.

Usage

rpxy always refers to a configuration file in TOML format, e.g., config.toml. You can find an example of the configuration file, config-example.toml, in this repository.

You can run rpxy with a configuration file like

% ./target/release/rpxy --config config.toml

If you specify -w option along with the config file path, rpxy tracks the change of config.toml in the real-time manner and apply the change immediately without restarting the process.

The full help messages are given follows.

usage: rpxy [OPTIONS] --config <FILE>

Options:
  -c, --config <FILE>  Configuration file path like ./config.toml
  -w, --watch          Activate dynamic reloading of the config file via continuous monitoring
  -h, --help           Print help
  -V, --version        Print version

That's all!

Basic Configuration

First Step: Cleartext HTTP Reverse Proxy

The most basic configuration of config.toml is given like the following.

listen_port = 80

[apps.app1]
server_name = 'app1.example.com'
reverse_proxy = [{ upstream = [{ location = 'app1.local:8080' }] }]

In the above setting, rpxy listens on port 80 (TCP) and serves incoming cleartext HTTP request including a app1.example.com in its HOST header or URL in its Request line. For example, request messages like the followings.

GET http://app1.example.com/path/to HTTP/1.1\r\n

or

GET /path/to HTTP/1.1\r\n
HOST: app1.example.com\r\n

Otherwise, say, a request to other.example.com is simply rejected with the status code 40x.

If you want to host multiple and distinct domain names in a single IP address/port, simply create multiple app."<app_name>" entries in config file like

default_app = "app1"

[apps.app1]
server_name = "app1.example.com"
#...

[apps.app2]
server_name = "app2.example.org"
#...

Here we note that by specifying default_app entry, HTTP requests will be served by the specified application if HOST header or URL in Request line doesn't match any server_names in reverse_proxy entries. For HTTPS requests, it will be rejected since the secure connection cannot be established for the unknown server name.

HTTPS to Backend Application

The request message will be routed to the backend application specified with the domain name app1.localdomain:8080 or IP address over cleartext HTTP. If the backend channel needs to serve TLS like forwarding to https://app1.localdomain:8080, you need to enable a tls option for the location.

revese_proxy = [
  { location = 'app1.localdomain:8080', tls = true }
]

Load Balancing

You can specify multiple backend locations in the reverse_proxy array for load-balancing with an appropriate load_balance option. Currently it works in the manner of round-robin, in the random fashion, or round-robin with session-persistance using cookie. if load_balance is not specified, the first backend location is always chosen.

[apps."app_name"]
server_name = 'app1.example.com'
reverse_proxy = [
  { location = 'app1.local:8080' },
  { location = 'app2.local:8000' }
]
load_balance = 'round_robin' # or 'random' or 'sticky'

Second Step: Terminating TLS

First of all, you need to specify a port listen_port_tls listening the HTTPS traffic, separately from HTTP port (listen_port). Then, serving an HTTPS endpoint can be easily done for your desired application just by specifying TLS certificates and private keys in PEM files.

listen_port = 80
listen_port_tls = 443

[apps."app_name"]
server_name = 'app1.example.com'
tls = { tls_cert_path = 'server.crt',  tls_cert_key_path = 'server.key' }
reverse_proxy = [{ upstream = [{ location = 'app1.local:8080' }] }]

In the above setting, both cleartext HTTP requests to port 80 and ciphertext HTTPS requests to port 443 are routed to the backend app1.local:8080 in the same fashion. If you don't need to serve cleartext requests, just remove listen_port = 80 and specify only listen_port_tls = 443.

We should note that the private key specified by tls_cert_key_path must be in PKCS8 format. (See TIPS to convert PKCS1 formatted private key to PKCS8 one.)

Redirecting Cleartext HTTP Requests to HTTPS

In the current Web, we believe it is common to serve everything through HTTPS rather than HTTP, and hence https redirection is often used for HTTP requests. When you specify both listen_port and listen_port_tls, you can enable an option of such redirection by making https_redirection true.

tls = { https_redirection = true, tls_cert_path = 'server.crt', tls_cert_key_path = 'server.key' }

If it is true, rpxy returns the status code 301 to the cleartext request with new location https://<requested_host>/<requested_query_and_path> served over TLS.

Third Step: More Flexible Routing Based on URL Path

rpxy can serves, of course, routes requests to multiple backend destination according to the path information. The routing information can be specified for each application (server_name) as follows.

listen_port_tls = 443

[apps.app1]
server_name = 'app1.example.com'
tls = { https_redirection = true, tls_cert_path = 'server.crt', tls_cert_key_path = 'server.key' }

[[apps.app1.reverse_proxy]]
upstream = [
  { location = 'default.backend.local' }
]

[[apps.app1.reverse_proxy]]
path = '/path'
upstream = [
  { location = 'path.backend.local' }
]

[[apps.app1.reverse_proxy]]
path = '/path/another'
replace_path = '/path'
upstream = [
  { location = 'another.backend.local' }
]

In the above example, a request to https://app1.example.com/path/to?query=ok matches the second reverse_proxy entry in the longest-prefix-matching manner, and will be routed to path.backend.local with preserving path and query information, i.e., served as http://path.backend.local/path/to?query=ok.

On the other hand, a request to https://app1.example.com/path/another/xx?query=ng matching the third entry is routed with being rewritten its path information specified by replace_path option. Namely, the matched /path/another part is rewritten with /path, and it is served as http://another.backend.local/path/xx?query=ng.

Requests that doesn't match any paths will be routed by the first entry that doesn't have the path option, which means the default destination. In other words, unless every reverse_proxy entry has an explicit path option, rpxy rejects requests that don't match any paths.

Simple Path-based Routing

This path-based routing option would be enough in many cases. For example, you can serve multiple applications with one domain by specifying unique path to each application. More specifically, see an example below.

[apps.app]
server_name = 'app.example.com'
#...

[[apps.app.reverse_proxy]]
path = '/subapp1'
replace_path = '/'
upstream = [ { location = 'subapp1.local' } ]

[[apps.app.reverse_proxy]]
path = '/subapp2'
replace_path = '/'
upstream = [ { location = 'subapp2.local' } ]

[[apps.app.reverse_proxy]]
path = '/subapp3'
replace_path = '/'
upstream = [ { location = 'subapp3.local' } ]

This example configuration explains a very frequent situation of path-based routing. When a request to app.example.com/subappN routes to sbappN.local by replacing a path part /subappN to /.

More Options

Since it is currently a work-in-progress project, we are frequently adding new options. We first add new option entries in the config-example.toml as examples. So please refer to it for up-to-date options. We will prepare a comprehensive documentation for all options.

Using Docker Image

You can also use docker image hosted on Docker Hub and GitHub Container Registry instead of directly executing the binary. See ./docker directory for more details.

Example

./bench directory could be a very simple example of configuration of rpxy. This can also be an example of an example of docker use case.

Experimental Features and Caveats

HTTP/3

rpxy can serves HTTP/3 requests thanks to quinn, s2n-quic and hyperium/h3. To enable this experimental feature, add an entry experimental.h3 in your config.toml like follows. Any values in the entry like alt_svc_max_age are optional.

[experimental.h3]
alt_svc_max_age = 3600
request_max_body_size = 65536
max_concurrent_connections = 10000
max_concurrent_bidistream = 100
max_concurrent_unistream = 100
max_idle_timeout = 10

Client Authentication via Client Certificates

Client authentication is enabled when apps."app_name".tls.client_ca_cert_path is set for the domain specified by "app_name" like

[apps.localhost]
server_name = 'localhost' # Domain name
tls = { https_redirection = true, tls_cert_path = './server.crt', tls_cert_key_path = './server.key', client_ca_cert_path = './client_cert.ca.crt' }

However, currently we have a limitation on HTTP/3 support for applications that enables client authentication. If an application is set with client authentication, HTTP/3 doesn't work for the application.

Hybrid Caching Feature with Temporary File and On-Memory Cache

If [experimental.cache] is specified in config.toml, you can leverage the local caching feature using temporary files and on-memory objects. An example configuration is as follows.

# If this specified, file cache feature is enabled
[experimental.cache]
cache_dir = './cache'                # optional. default is "./cache" relative to the current working directory
max_cache_entry = 1000               # optional. default is 1k
max_cache_each_size = 65535          # optional. default is 64k
max_cache_each_size_on_memory = 4096 # optional. default is 4k if 0, it is always file cache.

A storable (in the context of an HTTP message) response is stored if its size is less than or equal to max_cache_each_size in bytes. If it is also less than or equal to max_cache_each_size_on_memory, it is stored as an on-memory object. Otherwise, it is stored as a temporary file. Note that max_cache_each_size must be larger or equal to max_cache_each_size_on_memory. Also note that once rpxy restarts or the config is updated, the cache is totally eliminated not only from the on-memory table but also from the file system.

Automated Certificate Issuance and Renewal via TLS-ALPN-01 ACME protocol

This is a brand-new feature and maybe still unstable. Thanks to the rustls-acme, the automatic issuance and renewal of certificates are finally available in rpxy. To enable this feature, you need to specify the following entries in config.toml.

# ACME enabled domain name.
# ACME will be used to get a certificate for the server_name with ACME tls-alpn-01 protocol.
# Note that acme option must be specified in the experimental section.
[apps.localhost_with_acme]
server_name = 'example.org'
reverse_proxy = [{ upstream = [{ location = 'example.com', tls = true }] }]
tls = { https_redirection = true, acme = true } # do not specify tls_cert_path and/or tls_cert_key_path

For the ACME enabled domain, the following settings are referred to acquire a certificate.

# Global ACME settings. Unless specified, ACME is disabled.
[experimental.acme]
dir_url = "https://localhost:14000/dir" # optional. default is "https://acme-v02.api.letsencrypt.org/directory"
email = "[email protected]"
registry_path = "./acme_registry"       # optional. default is "./acme_registry" relative to the current working directory

The above configuration is common to all ACME enabled domains. Note that the https port must be open to the public to verify the domain ownership.

TIPS

Using Private Key Issued by Let's Encrypt

If you obtain certificates and private keys from Let's Encrypt, you have PKCS1-formatted private keys. So you need to convert such retrieved private keys into PKCS8 format to use in rpxy.

The easiest way is to use openssl by

% openssl pkcs8 -topk8 -nocrypt \
    -in yoru_domain_from_le.key \
    -inform PEM \
    -out your_domain_pkcs8.key.pem \
    -outform PEM

Client Authentication using Client Certificate Signed by Your Own Root CA

First, you need to prepare a CA certificate used to verify client certificate. If you do not have one, you can generate CA key and certificate by OpenSSL commands as follows. Note that rustls accepts X509v3 certificates and reject SHA-1, and that rpxy relys on Version 3 extension fields of KeyIDs of Subject Key Identifier and Authority Key Identifier.

  1. Generate CA key of secp256v1, CSR, and then generate CA certificate that will be set for tls.client_ca_cert_path for each server app in config.toml.
% openssl genpkey -algorithm EC -pkeyopt ec_paramgen_curve:prime256v1 -out client.ca.key

% openssl req -new -key client.ca.key -out client.ca.csr
...
-----
Country Name (2 letter code) []: ...
State or Province Name (full name) []: ...
Locality Name (eg, city) []: ...
Organization Name (eg, company) []: ...
Organizational Unit Name (eg, section) []: ...
Common Name (eg, fully qualified host name) []: <Should not input CN>
Email Address []: ...

% openssl x509 -req -days 3650 -sha256 -in client.ca.csr -signkey client.ca.key -out client.ca.crt -extfile client.ca.ext
  1. Generate a client key of secp256v1 and certificate signed by CA key.
% openssl genpkey -algorithm EC -pkeyopt ec_paramgen_curve:prime256v1 -out client.key

% openssl req -new -key client.key -out client.csr
...
-----
Country Name (2 letter code) []:
State or Province Name (full name) []:
Locality Name (eg, city) []:
Organization Name (eg, company) []:
Organizational Unit Name (eg, section) []:
Common Name (eg, fully qualified host name) []: <Should not input CN>
Email Address []:

% openssl x509 -req -days 365 -sha256 -in client.csr -CA client.ca.crt -CAkey client.ca.key -CAcreateserial -out client.crt -extfile client.ext

Now you have a client key client.key and certificate client.crt (version 3). pfx (p12) file can be retrieved as

% openssl pkcs12 -export -inkey client.key -in client.crt -certfile client.ca.crt -out client.pfx

Note that on MacOS, a pfx generated by OpenSSL 3.0.6 cannot be imported to MacOS KeyChain Access. We generated the sample pfx using LibreSSL 2.8.3 instead OpenSSL.

All of sample certificate files are found in ./example-certs/ directory.

(Work Around) Deployment on Ubuntu 22.04LTS using docker behind ufw

Basically, docker automatically manage your iptables if you use the port-mapping option, i.e., --publish for docker run or ports in docker-compose.yml. This means you do not need to manually expose your port, e.g., 443 TCP/UDP for HTTPS, using ufw-like management command.

However, we found that if you want to use the brand-new UDP-based protocol, HTTP/3, on rpxy, you need to explicitly expose your HTTPS port by using ufw-like command.

% sudo ufw allow 443
% sudo ufw enable

Your docker container can receive only TCP-based connection, i.e., HTTP/2 or before, unless you manually manage the port. We see that this is weird and expect that it is a kind of bug (of docker? ubuntu? or something else?). But at least for Ubuntu 22.04LTS, you need to handle it as above.

Managing rpxy via web interface

Check a third party project Gamerboy59/rpxy-webui to manage rpxy via web interface.

Other TIPS

todo!

License

rpxy is free, open-source software licensed under MIT License.

You can open issues for bugs you've found or features you think are missing. You can also submit pull requests to this repository.

Contributors are more than welcome!

Footnotes

  1. Doubtfully can be claimed to be written in pure Rust since current rpxy is based on aws-lc-rs for cryptographic operations.

  2. 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.

  3. 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.

rust-rpxy's People

Contributors

dependabot[bot] avatar junkurihara avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar

rust-rpxy's Issues

How to set the customized header for response?

In caddy, for example, we can add some headers to response

example.com {
    header {
      Cache-Control "no-cache, no-store, must-revalidate"
   }
}

I didn't find a way to configure the header in rpxy. Moreover, how do I enable gzip for an application?

Can't apply the updated config by hot-reloading option

I found a bug that can be reproduced as follows:

  • Update some entries, e.g., adding force_http11_upstream in upstream_options, in config.toml. I confirmed this was correctly applied internally to the rpxy's state
  • curl to the app, but the upstream option is NOT applied (still HTTP/2.0)

I also found that this was reproduced: when listen_port is updated, the previous port is still accesible.

Honestly, this cannot be solved shortly. So I am planning to revert rpxy-bin without continuous watching option.

[Breaking changes] Update rustls from 0.21 to 0.23

rpxy heavily relies on rustls and its dependents. to upgrade rpxy, we need to wait for updates of the following crates based on rustls.

- [x] hyper-rustls (waiting for rustls/hyper-rustls#234 with hyper-1.0 support, alternative: hyper-tls could be workaround)

reverse proxy to existing https application with self signed certificate

I am using rust-rpxy for my server & all of my web app reverse proxy connection through it. all of my unsecure apps reverse proxy without trouble. but one of my app in back end having self sign certificate. what should be syntax for reverse proxy with already having tls enable.
like this time for unsecure apps i write & working
[apps.homeassistant] server_name = 'homeassistant.xxx.zzz' tls = { https_redirection = true, tls_cert_path = '/mnt/my_userdata/rpxy/server.crt', tls_cert_key_path = '/mnt/my_userdata/rpxy/server.key' } reverse_proxy = [{ upstream = [{ location = 'localhost:8123' }] }]
home assistant on same machine so https://homeassistant.xxx.zzz >> http://localhost:8123
but for vaulwarden https://127.0.0.1:8001 available ( with self signed certificate in backend)
I want rust prxy forward https://vaultwarden.xxx.zzz >> https://localhost:8001

new update break rpxy functionality

Today i have updated rpxy to latest version. rpxy works but my webpage is showing me blank white screen. with htop linux command i am able to see rpxy works fine. i guess something need to change in my rpxy.toml file. please help me to translate my old rpxy.toml file to new rpxy version

how to connect http3/quic connection

Thanks for Rust-rpxy,
In my Toml file i have written "[experimental.h3]" block to enable http3/quic connection. but my connection is always consists of http2
Oct 17 11:50:57 wyse rpxy_active[470]: 2023-10-17T17:50:57.111242Z INFO rpxy rpxy_lib::log: homeassistant.xxx.zzz <- 192.168.1.93:58655 -- GET /frontend_latest/29968-bipxffWodxk.js HTTP/2.0 -- 200 OK -- https://homeassistant.xxx.zzz "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/115.0.0.0 Safari/537.36", "192.168.1.93" "http://localhost:8123/frontend_latest/29968-bipxffWodxk.js"

I am using debian 12 host machine & works within LAN without any firewall. is i have to finetune my host machine so that it can pick http3/quic connection. the result of following command is as below & my reverse proxy listening port is 8443

root@wyse:~# sudo ss -tulpn | grep 8443
udp   UNCONN 0      0            0.0.0.0:8443       0.0.0.0:*    users:(("rpxy_active",pid=470,fd=8))
tcp   LISTEN 0      1024         0.0.0.0:8443       0.0.0.0:*    users:(("rpxy_active",pid=470,fd=7)) 

How i can upgrade system so that system start using http3/quic (UDP) connection

Graphical Web UI

Hello,
I created a web user interface for managing the rpxy instance. It's made with Laravel and Bootstrap. I've included most configuration variations I guess. As a future feature, I thought of adding phpACME support for managing ssl certificates if this won't be of the domain of rpxy itself.
Maybe you can check it out and let me know what you think. We can further test and add/fix missing logic. Once you think it's good to share, maybe you can add a link to your readme so people will get to know it more easily.
https://github.com/Gamerboy59/rpxy-webui

Direct binary for download for rust-rpxy

Just want to request please put direct downloadable binary's for rust-rpxy. as rumqqtd developer maintained it " https://github.com/bytebeamio/rumqtt/releases " the reason for this is I know i can build rust binary with your already given procedure. but as i am using low hardware VM the building process take lot of resources & my system crash. if you allow direct downloadable your binary then i can easily downloads with wget command. I am running your rust-rpxy with systemd *.service file direct install method. thanks

Dynamic routing..

Would there be an interest in extending the product to support dynamic routing?

What I mean is that the routing table is external and dynamic to the running proxy application, and it periodically refreshes its internal lookup table without a restart.

In the NGINX world, this would require a new config and a SIGHUP.

We have a scenario where our routing data is actually in REDIS and used as a shared cache.

We'd like to run multiple copies of rust-rpxy as a proxy array to a set of origin servers. Each origin server has a specific piece of content, but this is not known beforehand.

The content is placed on the origin ad-hoc, and then a reference to the content pointing to the origin IP is stored in Redis.

So if I'm looking for content of /content/what, and "what" was uploaded into origin 192.168.1.2, then our redis would have some lookup table where "content/what" maps to "192.168.1.2".

This redis content is updating constantly, but you would only need to query it periodically to insure the routing is current.

We'd like to use rpxy in some way to load this dynamic lookup table so as requests come in, it knows the proper server IP to proxy to in order to serve the request.

We could build an application to query our Redis server and write a new .toml config file for each rpxy we have running, but this becomes cumbersome, and we'd still need the ability to update the config with a sighup to avoid downtime.

What would be better is if it could query the redis server directly, then we only have to configure the rpxy to pull it's configuration (which is the same for every instance) from a central place.

pull instead of push.

Let me know your thoughts.

Possible typo in documentation

Sorry to make another issue, really appreciate the quick handling.
On the front page most of the examples use the apps."name" format, but one example does not:

default_application = "app1"

[app.app1]
server_name = "app1.example.com"
#...

[app.app2]
server_name = "app2.example.org"
#...

Im not sure if this is different on purpose, but all others use apps.

Proxy cache option

Hello Jun, and thanks for your incredible library!

I currently use Nginx as HTTP(S) proxy, with proxy_cache enabled for improved performance (sometimes with order of magnitude faster responses), specifying rules about which base urls must skip the cache.

Considering the performance gains, I'm really interested in fully migrating to rust-rpxy, but today I would still be required to install Nginx behind it to provide the cache, invalidating the whole idea.

Do you have plans to create a cache feature?

[Breaking changes] Update hyper from 0.14 to 1.0

rust-rpxy currently depends on hyper of version 0.14.x. hyper project is planning to release version 1.0.x shortly and already released 1.0.0-rc.x.

The version up involves a lot of breaking changes, so we need to rethink the architecture of rpxy to support the brand new version of hyper.

Full script for getting LEGO SSL certificate for rpxy

Thanks for making rust-rpxy. I am using rust-rpxy & it is working blazing fast with my self signed certificate. Now I want to use actual ssl certificate through letenscrypt with the help of LEGO. As rpxy use rust format key(PK8) & letenscrypt give key in PK1. It should be very good if some expert person make a bash file which combined the LEGO commands for ssl certificate & convert key file into rust key format. Basically i want to merge creation of key & converting into rust format in one script.

https://go-acme.github.io/lego/usage/cli/obtain-a-certificate/

if some expert make this type of bash script file then we can run that file periodically by Linux Cron job.
thanks

compatibility with authelia type middle man authenticator

Just curiosity question, are we able to use rust-rpxy with authelia (https://www.authelia.com) type middle man authenicator. the end result i want to protect my bitwarden web page. I want when somebody call my https://bitwarden.zzz.xxx web page configured by rust-rpxy. first authelia authenticate it then if correct than allow to enter in bitwarden app else just discard user away. all these components are working via one combine docker-compose stack.

support of tlsoffloading between listen_port_tls and backbend

is it possible to add tlsoffloading feature?
adding tlsoffloading feature between listen_port_tls and the backend will make the server configuration more flexible.

for example,read the contents of data packet,evaluate based on the defined logic and then route it to a specific backend server as needed.

(suggestion) Use s2n-quic instead of quinn for better performance and stability

According to quic-interop-runner results (repo), the quiche HTTP/3 library from Cloudflare (also made in Rust), is faster than quinn.

In more than one test, quiche was more than 2x faster than quinn, and there were tests where quinn failed while quiche succeeded.

Not only that, quinn's maintainers already stated on quinn-rs/quinn#1320 (still open) that quinn is currently maintained by only two volunteers, and this makes difficult to improve quinn in the same pace of other more robust libraries, like quiche, maintained by Cloudflare.

Requests downgraded from HTTP/2 to 1.1?

It appears that requests are downgraded to HTTP 1.1, which doesn't work when the app server is running gRPC and tonic:

Request to be forwarded: Request { method: POST, uri: ..., version: HTTP/1.1, ... }

2023-08-06T06:04:07.863945Z  INFO rpxy rpxy_lib::log: localhost <- 127.0.0.1:51510 -- POST /grpc-redacted HTTP/2.0 -- 503 Service Unavailable -- https://localhost "user-agent-redacted", "127.0.0.1" "http://localhost:50051/grpc-redacted"

This is even when the following option is set (mentioned only in the "example" config):

listen_port_tls = 8443

[apps."localhost"]
server_name = 'localhost'
tls = { tls_cert_path = 'localhost.pem', tls_cert_key_path = 'localhost-key.pem' }

[[apps."localhost".reverse_proxy]]
upstream = [{ location = 'localhost:50051' }]
upstream_options = ["override_host", "convert_https_to_2"]

Good chance I'm just missing something about how to use this; will look into the repo tomorrow to see what that might be. If nothing else, this might merit a mention in the Readme.

Quick things I've verified:

  • The config file above is indeed the one being used
  • HTTP/2 header is indeed missing from the request upstream

Thanks!

Should we override HOST by default?

in the current implementation of 0.7.0-alpha.0, rpxy overrides the HOST header of HTTP request by the domain name of back end application by default. This can be disabled with keep_original_host option.

but I found that many application accepts only HTTP requests with original domain name in HOST header, like mastodon and misskey. So, should we make the option reversed? That is, the HOST is always kept as original.

If you have any opinion, please let us know!

[Feature] Rewrite Host header

This is useful when reverse proxying another vhosted reverse proxy. Also example.com doesn't work with Host: localhost:8080

git submodule update fail

$ git clone https://github.com/junkurihara/rust-rpxy.git
success

$ git submodule update --init

Cloning into '/Users/simon/rust-rpxy/h3'...
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
@    WARNING: REMOTE HOST IDENTIFICATION HAS CHANGED!     @
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
IT IS POSSIBLE THAT SOMEONE IS DOING SOMETHING NASTY!
Someone could be eavesdropping on you right now (man-in-the-middle attack)!
It is also possible that a host key has just been changed.
The fingerprint for the RSA key sent by the remote host is
SHA256:uNiVztksCsDhcc0u9e8BujQXVUpKZIDTMczCvj3tD2s.
Please contact your system administrator.
Add correct host key in /Users/simon/.ssh/known_hosts to get rid of this message.
Offending RSA key in /Users/simon/.ssh/known_hosts:4
Host key for github.com has changed and you have requested strict checking.
Host key verification failed.
fatal: Could not read from remote repository.

Please make sure you have the correct access rights
and the repository exists.
fatal: clone of '[email protected]:junkurihara/h3.git' into submodule path '/Users/simon/rust-rpxy/h3' failed
Failed to clone 'h3'. Retry scheduled`

ERROR main rpxy: Invalid configuration: Missing application spec

Error occurs trying to launch a simple configuration file like:
listen_port_tls = 9000

[app.rpxy1]
server_name = "rpxy1"
tls = { https_redirection = true, tls_cert_path = '/etc/rpxy/ssl/myserver.crt', tls_cert_key_path = '/etc/rpxy/ssl/myserver.key', client_ca_cert_path = '/etc/rpxy/ssl/MyOrg-RootCA.crt' }
reverse_proxy = [{ location = 'frontend1:9001' }]

Reverse proxy with combination of default web page plus folder location

I am using rust-rpxy in my home & reverse proxy home-assistant, plex, vaultwarden & photoprism. Rust-proxy running perfectly. Now I want to add new software SPIS ( https://github.com/gbbirkisson/spis ). This software need to reverse proxy default page of this software also the folder/file location for images & thumbnails. Upto this time I am using rust-proxy with reverse proxy app’s default page so now I confuse how to combine rust-proxy with SPIS. I am newbie to linux/reverse proxy mechanism. I just want to request if any expert translate this nginx configuration file (https://github.com/gbbirkisson/spis/blob/50ff25bc6a95ed3dcf098f35dfbcc0618da0cff4/docker/nginx.conf#L1-L35 ) into rust-proxy reverse proxy block (in TOML file) as it is beyond my knowledge how to configure it. This nginx file created by SPIS author & working on nigix perfectly. Please help me to use rust-proxy with SPIS software. The main background of this software is like it having a default webpage. In which hyperlink location of images & thumbnails. The end result I want if in browser I call “ http://spis.xxx.zzz/ “ it will show SPIS default page with thumbnails & image full functionality.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.