Realm
A network relay tool
Install / Use
/learn @zhboner/RealmREADME
Realm
A simple, high performance relay server written in rust.
<p><img src="https://raw.githubusercontent.com/zhboner/realm/master/assets/realm.png"/></p> <!-- [中文说明](https://zhb.me/realm) -->Libs
| lib | doc |
| ----- | ----- |
| realm-core |
|
| realm-io |
|
| realm-lb |
|
| realm-hook |
|
| realm-syscall |
|
Features
- Zero configuration. Setup and run in one command.
- Concurrency. Bidirectional concurrent traffic leads to high performance.
- Low resources cost.
Container
Realm can be run in a container with OCI (like Docker, Podman, Kubernetes, etc), see guides here.
Build
Install rust toolchain with rustup:
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh
Clone this repository:
git clone https://github.com/zhboner/realm && cd realm
Build:
cargo build --release
You can also pass target_cpu=native to allow more possible optimizations:
RUSTFLAGS='-C target_cpu=native' cargo build --release
The realm binary will be available in target/release.
Build Options
- ~~udp: enable udp relay~~ builtin.
- ~~tfo: enable tcp-fast-open~~ deprecated.
- ~~trust-dns: enable trust-dns's async dns resolver~~ builtin.
- ~~zero-copy: enable zero-copy on linux~~ builtin.
- brutal-shutdown: see realm_io/brutal-shutdown.
- hook: see realm_hook.
- proxy: enable proxy-protocol.
- balance: enable load balance.
- transport: enable ws/tls/wss.
- transport-tls-ring: use ring as rustls backend.
- transport-tls-awslc: use aws-lc as rustls backend.
- batched-udp: enable more efficient udp on linux.
- multi-thread: enable tokio's multi-threaded IO scheduler.
- mi-malloc: custom memory allocator.
- jemalloc: custom memory allocator.
- page-alloc: custom memory allocator.
Default: proxy + balance + transport + transport-tls-awslc + batched-udp + brutal-shutdown + multi-thread.
Deafult-Slim: batched-udp + brutal-shutdown + multi-thread.
See also: Cargo.toml.
Examples:
# simple tcp
cargo build --release --no-default-features
# enable other options
cargo build --release --features 'jemalloc'
# fully customized
cargo build --release \
--no-default-features \
--features 'transport, multi-thread, jemalloc'
# (since v2.9) use ring as rustls backend
cargo build --release \
--no-default-features \
--features 'multi-thread, brutal-shutdown' \
--features 'proxy, balance, batched-udp' \
--features 'transport, transport-tls-ring'
# equals
cargo build --release --no-default-features --features default-ring
Cross Compile
Please refer to https://rust-lang.github.io/rustup/cross-compilation.html. You may need to install cross-compilers or other SDKs, and specify them when building the project.
Or have a look at Cross, it makes things easier.
Usage
A high efficiency relay tool
Usage: realm [FLAGS] [OPTIONS]
Commands:
convert convert your legacy configuration into an advanced one
FLAGS:
-h, --help show help
-v, --version show version
-d, --daemon run as a unix daemon
-u, --udp force enable udp forward
-m, --mtcp force enable mptcp protocol
-t, --ntcp force disable tcp forward
-6, --ipv6 force disable ipv6 mapped ipv4
-f, --tfo force enable tcp fast open -- deprecated
-z, --splice force enable tcp zero copy -- deprecated
OPTIONS:
-c, --config <path> use config file
-l, --listen <address> listen address
-r, --remote <address> remote address
-x, --through <address> send through ip or address
-i, --interface <device> send through interface
-e, --listen-interface <device> listen interface
-a, --listen-transport <options> listen transport
-b, --remote-transport <options> remote transport
SYS OPTIONS:
-n, --nofile <limit> set nofile limit
-p, --pipe-page <number> set pipe capacity
-j, --pre-conn-hook <path> set pre-connect hook
LOG OPTIONS:
--log-level <level> override log level
--log-output <path> override log output
DNS OPTIONS:
--dns-mode <mode> override dns mode
--dns-min-ttl <second> override dns min ttl
--dns-max-ttl <second> override dns max ttl
--dns-cache-size <number> override dns cache size
--dns-protocol <protocol> override dns protocol
--dns-servers <servers> override dns servers
PROXY OPTIONS:
--send-proxy <send_proxy> send proxy protocol header
--send-proxy-version <version> send proxy protocol version
--accept-proxy <accept_proxy> accept proxy protocol header
--accept-proxy-timeout <second> accept proxy protocol timeout
TIMEOUT OPTIONS:
--tcp-timeout <second> override tcp timeout(5s)
--udp-timeout <second> override udp timeout(30s)
--tcp-keepalive <second> override default tcp keepalive interval(15s)
--tcp-keepalive-probe <count> override default tcp keepalive count(3)
Start from command line arguments:
realm -l 0.0.0.0:5000 -r 1.1.1.1:443
Start with config file:
# use toml
realm -c config.toml
# use json
realm -c config.json
# use configs in folder (since v2.6.2)
# all toml and json files are recursively included (e.g.: config/log.toml, config/node/n1.toml)
# hidden ones are recursively excluded (e.g.: config/.hidden_file, config/.hidden_dir/)
realm -c config/
Start with environment variables:
REALM_CONF='{"endpoints":[{"local":"127.0.0.1:5000","remote":"1.1.1.1:443"}]}' realm
# or
export REALM_CONF=`cat config.json | jq -c `
realm
Convert a legacy config file:
realm convert old.json
Configuration
TOML Example
[log]
level = "warn"
output = "realm.log"
[network]
no_tcp = false
use_udp = true
[[endpoints]]
listen = "0.0.0.0:5000"
remote = "1.1.1.1:443"
[[endpoints]]
listen = "0.0.0.0:10000"
remote = "www.google.com:443"
<details>
<summary>JSON Example</summary>
<p>
{
"log": {
"level": "warn",
"output": "realm.log"
},
"network": {
"no_tcp": false,
"use_udp": true
},
"endpoints": [
{
"listen": "0.0.0.0:5000",
"remote": "1.1.1.1:443"
},
{
"listen": "0.0.0.0:10000",
"remote": "www.google.com:443"
}
]
}
</p>
</details>
Overview
├── log
│ ├── level
│ └── output
├── dns
│ ├── mode
│ ├── protocol
│ ├── nameservers
│ ├── min_ttl
│ ├── max_ttl
│ └── cache_size
├── network
│ ├── no_tcp
│ ├── use_udp
│ ├── ipv6_only
│ ├── tcp_timeout
│ ├── udp_timeout
│ ├── tcp_keepalive
│ ├── tcp_keepalive_probe
│ ├── send_mptcp
│ ├── accept_mptcp
│ ├── send_proxy
│ ├── send_proxy_version
│ ├── accept_proxy
│ └── accept_proxy_timeout
└── endpoints
├── listen
├── remote
├── extra_remotes
├── balance
├── through
├── interface
├── listen_interface
├── listen_transport
├── remote_transport
└── network->
You should provide at least endpoint.listen and endpoint.remote, the left fields will take their default values.
Option priority: cmd override > endpoint config > global config.
endpoint
endpoint.listen: string
Local address, supported formats:
- ipv4:port
- ipv6:port
endpoint.remote: string
Remote address, supported formats:
- ipv4:port
- ipv6:port
- example.com:port
endpoint.extra_remotes: string array
Extra remote address, same as endpoint.remote above.
endpoint.balance: string
Require balance feature.
Load balance strategy and weights of remote peers.
Format:
$strategy: $weight1, $weight2, ...
Where remote is used as default backend server, and extra_remotes are used as backups.
Available algorithms (provided by realm_lb):
-
iphash
-
roundrobin
Example:
[[endpoints]]
remote = "a:443"
extra_remotes = ["b:443", "c:443"]
balance = "roundrobin: 4, 2, 1"
The weight of [a, b, c] is [4, 2, 1] in turn.
endpoint.through: string
TCP: Bind a specific ip before opening a connection.
UDP: Bind a specific ip or address before sending packet.
Supported formats:
- ipv4/ipv6 (tcp/udp)
- ipv4/ipv6:port (udp)
endpoint.interface: string
Bind to a specific interfac
