RealM
RealM copied to clipboard
A network relay tool
RealM
A network relay tool
A simple, high performance relay server written in rust.

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 Guides
Install nightly 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
Enter the directory and build:
cd realm && cargo build --release
Pass target_cpu=native to allow more possible optimizations:
RUSTFLAGS='-C target_cpu=native' cargo build --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.
- multi-thread: enable tokio's multi-threaded IO scheduler.
- mi-malloc: custom memory allocator.
- jemalloc: custom memory allocator.
Default: hook + proxy + balance + transport + multi-thread.
See also: Cargo.toml.
Examples:
# simple tcp
cargo build --release --no-default-features
# enable other options
cargo build --release --features 'brutal-shutdown,jemalloc'
安装脚本
脚本根据 seal0207 版修改
国外
wget -N --no-check-certificate https://raw.githubusercontent.com/xOS/RealM/master/realm.sh && chmod +x realm.sh && ./realm.sh
国内
wget -N --no-check-certificate https://cdn.jsdelivr.net/gh/xOS/RealM@master/realm.sh && chmod +x realm.sh && ./realm.sh
Usage
Realm 2.4.0 [hook][proxy][balance][transport][multi-thread]
A high efficiency relay tool
USAGE:
realm [FLAGS] [OPTIONS]
FLAGS:
-h, --help show help
-v, --version show version
-d, --daemon run as a unix daemon
-u, --udp force enable udp forward
-t, --ntcp force disable tcp forward
-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> bind to 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 protocol header
--send-proxy-version <version> send proxy protocol version
--accept-proxy accept proxy protocol header
--accept-proxy-timeout <second> accept proxy protocol timeout
TIMEOUT OPTIONS:
--tcp-timeout <second> override tcp timeout
--udp-timeout <second> override udp timeout
SUBCOMMANDS:
convert convert your legacy configuration into an advanced one
Start from command line arguments:
realm -l 0.0.0.0:5000 -r 1.1.1.1:443
Start with a config file:
# use toml
realm -c config.toml
# use json
realm -c config.json
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 = "/var/log/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"
JSON Example
{
"log": {
"level": "warn",
"output": "/var/log/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"
}
]
}
See more examples here.
Overview
├── log
│ ├── level
│ └── output
├── dns
│ ├── mode
│ ├── protocol
│ ├── nameservers
│ ├── min_ttl
│ ├── max_ttl
│ └── cache_size
├── network
│ ├── no_tcp
│ ├── use_udp
│ ├── tcp_timeout
│ ├── udp_timeout
│ ├── send_proxy
│ ├── send_proxy_version
│ ├── accept_proxy
│ └── accept_proxy_timeout
└── endpoints
├── listen
├── remote
├── extra_remotes
├── balance
├── through
├── 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 interface.
endpoint.listen_transport: string
Require transport feature.
See Kaminari Options.
endpoint.remote_transport: string
Require transport feature.
See Kaminari Options.
endpoint.network
The same as network, override global options.
log
log.level: string
values:
- off
- error
- warn
- info
- debug
- trace
default: off
log.output: string
values:
- stdout
- stderr
- path (e.g.
/var/log/realm.log)
default: stdout
dns
Require trust-dns feature.
dns.mode: string
Dns resolve strategy.
values:
- ipv4_only
- ipv6_only
- ipv4_then_ipv6
- ipv6_then_ipv4
- ipv4_and_ipv6
default: ipv4_and_ipv6
dns.protocol: string
Dns transport protocol.
values:
- tcp
- udp
- tcp_and_udp
default: tcp_and_udp
dns.nameservers: string array
Custom upstream servers.
format: ["server1", "server2" ...]
default:
If on unix/windows, read from the default location.(e.g. /etc/resolv.conf).
Otherwise, use google's public dns(8.8.8.8:53, 8.8.4.4:53 and 2001:4860:4860::8888:53, 2001:4860:4860::8844:53).
dns.min_ttl: unsigned int
The minimum lifetime of a positive dns cache.
default: 0
dns.max_ttl: unsigned int
The maximum lifetime of a positive dns cache.
default: 86400 (1 day)
dns.cache_size: unsigned int
The maximum count of dns cache.
default: 32
network
network.no_tcp: bool
Do not start a tcp relay.
default: false
network.use_udp: bool
~~Require udp feature~~
Start listening on a udp endpoint and forward packets to the remote peer.
It will dynamically allocate local endpoints and establish udp associations. Once timeout, the endpoints will be deallocated and the association will be terminated. See also: network.udp_timeout.
Due to the receiver side not limiting access to the association, the relay works like a full-cone NAT.
default: false
~~network.zero_copy: bool~~ deprecated
~~Require zero-copy feature.~~
~~Use splice instead of send/recv while handing tcp connection. This will save a lot of memory copies and context switches.~~
~~default: false~~
~~network.fast_open: bool~~ deprecated
~~Require fast-open feature.~~
~~It is not recommended to enable this option, see The Sad Story of TCP Fast Open.~~
~~default: false~~
network.tcp_tomeout: unsigned int
This is connect timeout. An attempt to connect to a remote peer fails after waiting for a period of time.
To disable timeout, you need to explicitly set timeout value to 0.
default: 5
network.udp_timeout: unsigned int
Terminate udp association after timeout.
The timeout value must be properly configured in case of memory leak. Do not use a large timeout!
default: 30
network.send_proxy: bool
Require proxy feature.
Send haproxy PROXY header once the connection established. Both v1 and v2 are supported, see send_proxy_version.
You should make sure the remote peer also speaks proxy-protocol.
default: false
network.send_proxy_version: unsigned int
Require proxy feature.
This option has no effect unless send_proxy is enabled.
value:
- 1
- 2
default: 2
network.accept_proxy: bool
Require proxy feature.
Wait for a PROXY header once the connection established.
If the remote sender does not send a v1 or v2 header before other contents, the connection will be closed.
default: false
network.accept_timeout: unsigned int
Require proxy feature.
Wait for a PROXY header within a period of time, otherwise close the connection.
default: 5.