-
Notifications
You must be signed in to change notification settings - Fork 0
Configuration
Everything is one TOML file. The GUI writes it for you; you rarely need to edit it by hand, but it is plain text and you can.
| Mode | Path |
|---|---|
| Normal (GUI or console) | %APPDATA%\proxyforward\config.toml |
| Windows service | %ProgramData%\proxyforward\config.toml |
Override with --config <path> on any command — handy for testing a second setup without
touching your real one.
Alongside it in the same directory: gateway.crt / gateway.key (gateway only),
analytics.db, avatars\, and logs\.
Notes on behaviour:
- A missing config file is not an error. First run starts from defaults and writes the file once it has something worth saving.
- A malformed file is an error, and so is one that fails validation — proxyforward refuses to start rather than run with a setting you didn't mean.
- Saves are atomic (write to a temp file in the same directory, then rename), so a crash mid-save can't leave you with a truncated config.
- The directory is created with restrictive permissions. It contains your auth token in plain text — treat it accordingly.
| Key | Type | Default | Meaning |
|---|---|---|---|
role |
"agent" | "gateway" | unset |
unset | Which side this machine is. An unset role is valid — that's the state the wizard starts from. Only the matching section is validated. |
| Key | Type | Default | Meaning |
|---|---|---|---|
agent_id |
hex string | generated on first run | Persistent identity. A reconnect with the same ID supersedes the old session; a different ID on the same token is rejected. This is what stops two agents flapping. |
gateway_host |
string | — | Gateway hostname or IP. Prefer a DNS name — it is re-resolved on every reconnect. |
gateway_port |
int | 8474 |
The gateway's control port. |
token |
hex string | — | Shared auth token. Comes from the pairing code. |
cert_fingerprint |
sha256:<64 hex> |
— | The gateway certificate you pinned. Comes from the pairing code. |
transport |
"mux" | "per-conn"
|
"mux" |
per-conn does nothing. The value is accepted and stored, but the agent never reads it and the gateway rejects non-multiplexed connections. Leave it alone. See Not Yet Implemented. |
tunnels |
array of tables | [] |
See Tunnels. |
gateway_host, token and cert_fingerprint are all required for the agent role, and all
three are set for you by proxyforward pair or the wizard.
Full detail, including the options, on the Tunnels page.
[[agent.tunnels]]
id = "…" # unique, generated
name = "Minecraft"
type = "tcp" # TCP is the only type that works
local_addr = "127.0.0.1:25565" # where YOUR server actually listens
public_port = 25565 # where PLAYERS connect on the gateway
enabled = true
[agent.tunnels.options]
minecraft_aware = false # passive login sniffing — see Tunnels
proxy_protocol_v2 = false # real player IPs for Paper/Velocity — see Tunnels
offline_motd = "" # ⚠️ does nothing
bandwidth_limit_mbps = 0 # ⚠️ does nothing| Key | Type | Default | Meaning |
|---|---|---|---|
bind_addr |
IP | 0.0.0.0 |
Interface for the control listener and every public tunnel listener. 0.0.0.0 = all. |
control_port |
int | 8474 |
Where agents connect. |
token |
hex string | generated on first gateway start | The shared secret. Rotating it (Settings → Security) disconnects every agent until they re-pair. |
public_host |
string | — | The hostname baked into pairing codes. Optional, but set it — otherwise codes carry a placeholder. |
port_allowlist |
list of int | [] |
Which public ports an agent may request. Empty means any port. Set it if you don't fully trust whoever holds the pairing code. |
max_conns_global |
int | 4096 |
Hard cap on concurrent public connections. |
max_conns_per_ip |
int | 32 |
Per-source-IP cap. |
auth_attempts_per_min |
int | 10 |
Failed auth attempts allowed per IP per minute. Successes never count, so a legitimately flapping agent is never locked out. |
See Analytics and Privacy for what is actually stored.
| Key | Type | Default | Meaning |
|---|---|---|---|
retention_days |
int, 1–3650 | 180 |
How long individual player sessions are kept. Daily rollups are kept forever. |
mojang_lookups |
bool | true |
Resolve player names → UUIDs and skins via Mojang. This is the only feature that sends player names off your machine. Turn it off for offline-mode ("cracked") servers, where the names are unauthenticated anyway. |
geoip_city_path |
path | — | Your own MaxMind GeoLite2 City .mmdb. Nothing is bundled and no geo service is contacted; leave empty and geography is simply off. |
geoip_asn_path |
path | — | Your own GeoLite2 ASN .mmdb. |
A missing .mmdb file is reported in the UI as unavailable — it is not a config error and it
will not stop the engine.
| Key | Type | Default | Meaning |
|---|---|---|---|
level |
debug|info|warn|error
|
info |
|
file_enabled |
bool | true |
Writes logs\proxyforward.log, rotating at 10 MiB, 3 files kept. |
| Key | Type | Default | Meaning |
|---|---|---|---|
theme |
dark|light|system
|
dark |
|
minimize_to_tray |
bool | true |
|
autostart |
bool | false |
/metrics
endpoint. See Not Yet Implemented.
| Key | Type | Default |
|---|---|---|
prometheus_enabled |
bool | false |
prometheus_addr |
host:port | 127.0.0.1:9464 |
Gateway:
role = "gateway"
[gateway]
public_host = "mc.example.com"
control_port = 8474
port_allowlist = [25565, 25566]
[logging]
level = "info"Agent:
role = "agent"
[agent]
agent_id = "…"
gateway_host = "mc.example.com"
gateway_port = 8474
token = "…"
cert_fingerprint = "sha256:…"
[[agent.tunnels]]
id = "…"
name = "Minecraft"
type = "tcp"
local_addr = "127.0.0.1:25565"
public_port = 25565
enabled = true
[agent.tunnels.options]
proxy_protocol_v2 = true
minecraft_aware = true
[analytics]
mojang_lookups = true
retention_days = 180Timeouts, frame caps, buffer sizes, backoff curves and the rest are not configurable — they
are compile-time constants, chosen together, and documented in one place:
docs/agent/architecture.md → "The numbers".
This wiki deliberately doesn't restate them, so it can't drift out of date.
proxyforward · Issues · GPL-3.0 — Windows only, TCP only. Check Not Yet Implemented before filing a bug.