Skip to content

Configuration

xeri edited this page Jul 14, 2026 · 1 revision

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.

Where it lives

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.

Top level

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.

[agent]

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.

[[agent.tunnels]]

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

[gateway]

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.

[analytics]

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.

[logging]

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.

[ui]

Key Type Default Meaning
theme dark|light|system dark
minimize_to_tray bool true ⚠️ Does nothing. There is no tray icon.
autostart bool false ⚠️ Does nothing. Use the Windows service instead.

[metrics]

⚠️ This entire section is inert. The keys are parsed and validated, and the Settings toggle exists, but no metrics server is implemented — nothing listens, and there is no /metrics endpoint. See Not Yet Implemented.

Key Type Default
prometheus_enabled bool false
prometheus_addr host:port 127.0.0.1:9464

A complete example

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 = 180

Tuned constants

Timeouts, 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.

Clone this wiki locally