Crates.io | odd-box |
lib.rs | odd-box |
version | 0.1.8 |
source | src |
created_at | 2023-09-10 14:36:32.485084 |
updated_at | 2024-10-21 18:25:37.702586 |
description | dead simple reverse proxy server |
homepage | |
repository | https://github.com/OlofBlomqvist/odd-box |
max_upload_size | |
id | 968845 |
size | 2,288,271 |
A simple, cross-platform reverse proxy server tailored for local development and tinkering. Think of it as a lightweight (and more streamlined) alternative to something like IIS, but with a key difference: configuration is primarily done declaratively through structured files, rather than a graphical user interface.
It allows you to configure a list of processes to run and host them behind their own custom hostnames. Self-signed certificates for HTTPS are automatically generated when accessing a site thru the terminating proxy service the first time (cached in .odd-box-cache dir). As with most reverse-proxy servers, odd-box also supports targetting remote backend servers.
As configuration is done thru basic files (toml format) which are easy to share, it's very easy to reproduce a particular setup.
Pre-built binaries are available in the release section.
You can also build it yourself, or install it using brew, cargo, nix or devbox; see the installation section for guidance.
Cross platform (win/lin/osx)
Easy to configure (toml files)
Keep a list of specified binaries running
Uses PORT environment variable for routing
Allows for setting proc specific and global env vars
Remote target proxying
Terminating proxy that supports both HTTP/1.1 & HTTP2
TCP tunnelling for HTTP/1
TCP tunnelling for HTTPS/1 & HTTP2 via SNI sniffing
TCP tunnelling for HTTP/2 over HTTP/1 (h2c upgrade)
H2C via terminating proxy
Automatic self-signed certs for all hosted processes
Basic round-robin loadbalancing for remote targets
Terminating proxy supports automaticly generating lets-encrypt certificates
While the goal of this project is not to provide a state-of-the-art level performing proxy server for production environments, but rather a tool for simplifying local development scenarios, we do try to keep performance in mind be blazingly fast :-) Seriously though, performance is actually pretty good but it is not a priority (yet).
The TUI is fairly simple basic; it provides an easy way to see which sites are running, the log outputs and all currently active connections. It is possible to opt-out of TUI mode by supplying the argument: "--tui=false" when starting odd-box.
There is a basic administration API that can be enabled by adding "admin_api_port = n" to the configuration file. At some point a web-interface might be added for controlling odd-box thru this API..
odd-box v0.1.2:
Pre-built binaries are available in the release section, but there are more ways to install odd-box if you so wish :-)
Recommended for Mac users. Brew lets you easily install odd-box globally and use brew for managing updates; it also works on Linux and Windows (wsl2).
brew tap OlofBlomqvist/repo
brew install oddbox
cargo install odd-box
{
"name": "example devbox config",
"packages": [
// select rev of whichever version you need, this is for v0.1.2
"github:OlofBlomqvist/odd-box?rev=043fe0abd9da1d4a1e0fa0bfcc300c71971e26ce"
// ...
],
// ...
}
nix build github:OlofBlomqvist/odd-box
{
description = "example flake with oddbox";
inputs = {
... # select rev of whichever version you need, this is for v0.1.2
oddbox.url = "github:OlofBlomqvist/odd-box?rev=043fe0abd9da1d4a1e0fa0bfcc300c71971e26ce";
};
...
}
If you are hosting a local project that you are currently working on, and want to do a rebuild without having to manually start and stop your site - you may want to consider having a pre-build step that does it for you:
You can enable or disable all sites or specific ones using the http://localhost:port/START and http://localhost:port/STOP endpoints, optionally using query parameter "?proc=my_site" to stop or start a specific site. Sites start automatically again on the next request. The same can be acomplished thru the admin-api if you enable it.
As all the routing is based on hostnames, your client machine(s) must of course be able to resolve those names correctly to the proxy server IP. If you are working on a local machine this can be configured either by adding entries to your host file pointing each domain to 127.0.0.1 or by using something like localtest.me.me, eg. my-first-site.localtest.me when configuring hosted sites. More advanced users might use their own DNS servers to set up these domains however they like.
Since odd-box spawns your defined binaries, you should be careful not to run odd-box in elevated/admin mode. To be safe, use a non-restricted port so that you do not need root access or follow the section for your OS below!
MacOS does not require super-user access when binding to 0.0.0.0 / ::1 on ports 1-1024. The easiest way to get started is to just set the ip and tls_ip to bind to 0.0.0.0:80 and 0.0.0.0:443.
Should you want to bind specifically to 127.0.0.1; do not run this application using sudo. Instead configure a redirect to a non-restricted port such as 8080, and configure odd-box to use that (port=8080):
rdr pass on lo0 inet proto tcp from 127.0.0.1 to 127.0.0.1 port 80 -> 127.0.0.1 port 8080
sudo pfctl -ef pf-rules.conf
Do not run this application using sudo. Instead allow odd-box to listen to restricted ports directly.
sudo setcap CAP_NET_BIND_SERVICE=+eip /path/to/odd-box
# (alternatively you could set up a redirect in your fw, similar to the MacOS section)
Do not run the application as admin (elevated mode), instead you can allow your own account to use restricted ports.
netsh http add urlacl url=http://+:80/ user=DOMAIN\user
# (alternatively you could set up a redirect in your fw, similar to the MacOS section)
To configure the odd-box
proxy server, create a configuration file following the format provided in the example configuration file. The configuration file uses the TOML format and is designed to define both remote targets (sites that odd-box
proxies traffic to) and hosted processes (sites or services managed directly by odd-box
).
Running odd-box without any arguments it will first try to read from odd-box.toml, then Config.toml. You can supply a custom config path using: ./odd-box "/tmp/my-file.toml"
It is also possible to update the active configuration at runtime thru an administration API which fully documents the possible settings.
Variable | Description |
---|---|
$root_dir | Resolves to whatever you set it to in the global configuration section. |
$cfg_dir | Resolves to the directory which the configuration toml file was read from. |
$port | Resolves to whatever port has been specified in the configuration. Only used for hosted processes. |
Tip: if you are editing the confguration file using vs-code you should try the "even better toml" extension, which will provide you not only with syntax highlighting but also intellisense based on the configuration files '#:schema ...' tag.
There are more options than the ones shown here; these are the most commonly used ones. See the example configuration or schema.json file for a list of all possible options.
Global Settings: Set the global properties like http_port
, tls_port
, ip
, log_level
, port_range_start
, and env_vars
. These settings control the overall behavior of odd-box
.
#:schema https://raw.githubusercontent.com/OlofBlomqvist/odd-box/main/odd-box-schema-v2.json
version = "V2"
http_port = 8080
tls_port = 4343
ip = "127.0.0.1"
log_level = "Trace"
port_range_start = 4242
env_vars = []
lets_encrypt_account_email = "example@example.com"
version
: Must be "V2"http_port
: TCP Port for the server to use. Defaults to 8080 if not specified.tls_port
: TCP Port for the server to buse. Defaults to 4343 if not specified.ip
: IP Address for the server to use. Defaults to 127.0.0.1 if not specified.log_level
: info/warn/err/debug/trace - defaults to info of not specified.port_range_start
: Must be specified - used for automatically assign the PORT env var to hosted sites (if not set explicity for a site).env_vars
: List of environment variables that all hosted processes should have.lets_encrypt_account_email
: (Optional) Set email to use if you wish to use lets-encrypt.Adding Remote Targets: Define remote targets to forward traffic to external servers. Each remote_target requires a host_name (the incoming domain) and a list of backends (the target servers). To add a new remote site:
[[remote_target]]
host_name = "example.com"
backends = [
# hints are optional and used for specifying if server requires for example H2C.
{ https = true, address="example.com", port=443, hints = [] }
]
host_name
: The incoming domain that odd-box will listen for.backends
: A list of backend servers to forward traffic to. The https property specifies if TLS is used.Adding Hosted Processes: Define hosted processes that odd-box will manage. These are services that odd-box can start, stop, and restart. Each hosted_process requires a host_name
, dir
, bin
, and args
:
[[hosted_process]]
host_name = "myapp.local"
dir = "/home/kalle/" # variables like $root_dir or $config_dir are allowed here
bin = "/usr/bin/python3" # variables like $root_dir or $config_dir are allowed here
args = ["-m", "http.server", "$port"] # variables like $port, $root_dir & $config_dir are allowed here
auto_start = true
hints = ["NOH2","H2C","H2"]
https = false
env_vars = [
{ key = "some-environment-variable", value = "example-value" },
]
host_name
: The incoming domain that odd-box will listen for.
dir
: Directory where the process will be executed.
bin
: Executable path to a binary file (absolute, relative to dir, or in pwd)
args
: Arguments to pass to the binary.
auto_start
: (Optional) Set to true to automatically start the process with odd-box.
hints
: (Optional) Not normally needed but can be set to specify that a server requires for example H2C.
https
: (Optional) Set to true if the process uses HTTP (TLS)
enable_lets_encrypt
: (Optional) Set to true to enable lets-encrypt to be used for this site.
To get started quickly, simply copy the minimal example configuration file, modify the relevant sections to add your remote targets or hosted processes, and run odd-box with your configuration file.
If you are not using a package manager such as homebrew to manage your odd-box installation, you can either manually download new versions from the github release section or use the built in command for doing the same:
odd-box --update
Note: Should you have an older configuration file than V2, you can upgrade it automatically thru the odd-box --upgrade-config ./my-config-file.toml
.