Configuration
The server reads wpg.toml from the working directory, or the file given with --config / WPG_CONFIG. Precedence, lowest first: built-in defaults, the file, environment variables WPG_<SECTION>__<KEY> (__ separates nesting levels, for example WPG_SERVER__BIND=0.0.0.0:8080 or WPG_TX__ALLOWED_IFACES='["eth1"]'), then command line options such as wpg serve --bind. Unknown keys are errors. wpg config init writes the commented example below, wpg config show prints the effective configuration, wpg config validate checks it and wpg config set-password stores the admin password hash. The admin password itself is not a key: wpg serve --password, --password-file and WPG_PASSWORD take precedence over auth.password_hash and auth.password_file. This page is generated from the configuration types.
Keys
Top level
| Key | Type | Default | Environment variable | Description |
|---|---|---|---|---|
data_dir | string | OS data directory (Linux: ~/.local/share/wpg) | WPG_DATA_DIR | Directory for server state: user templates, favourites, the SQLite database (users, sessions, job history), dry-run captures and the self-signed TLS certificate. |
[auth]
Authentication.
| Key | Type | Default | Environment variable | Description |
|---|---|---|---|---|
password_file | string | WPG_AUTH__PASSWORD_FILE | File holding the admin password: an argon2 PHC string, or plain text that is hashed at startup. | |
password_hash | string | WPG_AUTH__PASSWORD_HASH | argon2id PHC string of the admin password; wpg config set-password writes it. | |
session_ttl_secs | integer | 86400 | WPG_AUTH__SESSION_TTL_SECS | Session lifetime in seconds (sliding: every request extends it). |
[dhcp]
DHCP server tool (DHCPv4 / DHCPv6 on one interface; pools and options are edited on the DHCP screen).
| Key | Type | Default | Environment variable | Description |
|---|---|---|---|---|
enabled | boolean | true | WPG_DHCP__ENABLED | Enables the DHCP screen and the /api/dhcp endpoints. |
iface | string | "" | WPG_DHCP__IFACE | Interface the DHCP server answers on, e.g. eth1 (deploy.sh --dhcp-iface). Empty: chosen on the screen among tx.allowed_ifaces. |
[log]
Logging.
| Key | Type | Default | Environment variable | Description |
|---|---|---|---|---|
ansi | boolean | true | WPG_LOG__ANSI | Colour the console output when it is a terminal. |
file | string | WPG_LOG__FILE | Also write to this file (its directory is created). | |
format | "pretty" | "json" | "pretty" | WPG_LOG__FORMAT | Line format: pretty (human readable) or json (one object per line). |
level | string | "info" | WPG_LOG__LEVEL | Filter directives (RUST_LOG overrides them), for example info or wpg_tx=debug,info. |
max_files | integer | WPG_LOG__MAX_FILES | Keep at most this many rotated files (the oldest are deleted). | |
rotation | "never" | "hourly" | "daily" | "never" | WPG_LOG__ROTATION | Rotation of the file: never, hourly or daily. |
[protocols]
User-defined protocols.
| Key | Type | Default | Environment variable | Description |
|---|---|---|---|---|
dirs | string[] | [] | WPG_PROTOCOLS__DIRS | Directories of user-defined protocol files (*.yaml: new protocol definitions and bindings under existing protocols), loaded at startup in file name order. wpg serve --protocols-dir adds more. |
[server]
HTTP listener.
| Key | Type | Default | Environment variable | Description |
|---|---|---|---|---|
base_url | string | WPG_SERVER__BASE_URL | Public URL of the server behind a reverse proxy (https://wpg.example.net), used for absolute links. | |
bind | string | "127.0.0.1:8080" | WPG_SERVER__BIND | Listen address. Without a password (and no user created on the setup screen) only loopback addresses are accepted (--allow-insecure overrides). |
job_history | integer | 100 | WPG_SERVER__JOB_HISTORY | Finished jobs kept in memory and listed on the Jobs screen and by the API (1–100000). |
job_history_db | integer | 1000 | WPG_SERVER__JOB_HISTORY_DB | Finished jobs kept in the database; older ones are deleted (1–10000000). |
preview_max | integer | 256 | WPG_SERVER__PREVIEW_MAX | Most packets one preview request (POST /api/render) may render (1–100000). |
self_signed_tls | boolean | false | WPG_SERVER__SELF_SIGNED_TLS | Serve HTTPS with a self-signed certificate generated into <data_dir>/tls/ (reused on later starts); wpg serve --tls sets it. |
[server.tls]
TLS certificate chain and private key (PEM) to serve HTTPS with; takes precedence over self_signed_tls.
| Key | Type | Default | Environment variable | Description |
|---|---|---|---|---|
cert | string | WPG_SERVER__TLS__CERT | PEM certificate chain. | |
key | string | WPG_SERVER__TLS__KEY | PEM private key. |
[snmp]
SNMP manager tool (Get / Walk / Set / traps, MIB upload).
| Key | Type | Default | Environment variable | Description |
|---|---|---|---|---|
enabled | boolean | true | WPG_SNMP__ENABLED | Enables the SNMP tool screen and the /api/snmp endpoints. |
mib_dir | string | "" | WPG_SNMP__MIB_DIR | Directory of uploaded MIB files. Empty: <data_dir>/mibs. |
trap_listen | string | "" | WPG_SNMP__TRAP_LISTEN | Address the trap / inform receiver listens on from startup, e.g. 0.0.0.0:162 (ports below 1024 need root or CAP_NET_BIND_SERVICE). Empty: not started at boot (it can be started from the UI). |
[templates]
Template library.
| Key | Type | Default | Environment variable | Description |
|---|---|---|---|---|
library_paths | string[] | ["./templates"] | WPG_TEMPLATES__LIBRARY_PATHS | Read-only template libraries (Git checkouts, for example), scanned recursively for *.wpg.yaml / *.wpg.json and reloaded when files change. |
user_dir | string | WPG_TEMPLATES__USER_DIR | Writable directory for templates created or imported in the GUI; default <data_dir>/templates. |
[terminal]
Web terminal: SSH / Telnet sessions the server opens for logged-in users (see the web terminal guide).
| Key | Type | Default | Environment variable | Description |
|---|---|---|---|---|
allowed_targets | string[] | [] | WPG_TERMINAL__ALLOWED_TARGETS | Targets sessions may connect to: host, host:port, *.domain, an IP address or a CIDR block (10.0.0.0/8, [2001:db8::1]:830); empty = any target. |
enabled | boolean | false | WPG_TERMINAL__ENABLED | Enable the web terminal. Off by default. |
idle_timeout_secs | integer | 1800 | WPG_TERMINAL__IDLE_TIMEOUT_SECS | Close a session after this many seconds without input or output; 0 = never. |
max_sessions | integer | 8 | WPG_TERMINAL__MAX_SESSIONS | Maximum number of simultaneous sessions (all users). |
record_sessions | boolean | true | WPG_TERMINAL__RECORD_SESSIONS | Allow session logs (what the remote side sends) under <data_dir>/terminal-logs; false disables server-side logs. |
[tx]
Transmit policy and defaults.
| Key | Type | Default | Environment variable | Description |
|---|---|---|---|---|
allowed_ifaces | string[] | [] | WPG_TX__ALLOWED_IFACES | Interfaces jobs may send on; empty = all. The null backend and dry runs are not restricted. |
default_backend | string | WPG_TX__DEFAULT_BACKEND | Backend used when a job names none (null, pcapfile, afpacket, pcap, afxdp, dpdk); unset = afpacket on Linux, else pcap, else null. | |
dpdk_eal_args | string[] | [] | WPG_TX__DPDK_EAL_ARGS | DPDK EAL arguments for the dpdk backend, e.g. ["-a", "0000:00:04.0"]. wpg adds -l <first CPU> and --in-memory unless given. EAL starts once per process with the first dpdk job; changing them needs a restart. |
max_rate | string | WPG_TX__MAX_RATE | Highest rate a job may request (100kpps, 1Gbps); jobs without a rate are sent at this rate. | |
prerender_max_bytes | integer | 268435456 | WPG_TX__PRERENDER_MAX_BYTES | Pre-render a stream (build every frame before sending) only when packets × frame length is at most this many bytes; larger streams are built on the fly. 0 never pre-renders unless --plan prerender asks for it. Up to 1 TiB; wpg send --prerender-max-bytes overrides. |
prerender_max_packets | integer | 100000000 | WPG_TX__PRERENDER_MAX_PACKETS | Pre-render a stream only when it has at most this many packets. wpg send --prerender-max-packets overrides. |
ring_bytes | integer | 16777216 | WPG_TX__RING_BYTES | Memory of one afpacket TX ring or afxdp UMEM per worker, in bytes (1 MiB–1 GiB); the ring depth is reduced to fit. The memory is locked: raise ulimit -l for large values. --ring-bytes overrides. |
Example (wpg config init)
Every active line equals the built-in default, so the file changes nothing until edited; the commented lines show the optional keys.
# wpg.toml — Web Packet Generator configuration.
#
# Precedence (lowest first): built-in defaults < this file < environment variables
# (WPG_<SECTION>__<KEY>, e.g. WPG_SERVER__BIND=0.0.0.0:8080 or
# WPG_TX__ALLOWED_IFACES='["eth1"]') < command line options (wpg serve --bind ...).
# Unknown keys are rejected. Check a file with `wpg config validate`, print the
# effective configuration with `wpg config show`.
# Server state: user templates, favourites, job history, dry-run captures.
# Default: the OS data directory (Linux: ~/.local/share/wpg).
# data_dir = "/var/lib/wpg"
[server]
# Listen address. Without a password keep it on localhost.
bind = "127.0.0.1:8080"
# Public URL when running behind a reverse proxy.
# base_url = "https://wpg.example.net"
# Serve HTTPS with a self-signed certificate generated into <data_dir>/tls/
# (same as `wpg serve --tls`). Ignored when [server.tls] is set.
self_signed_tls = false
# Most packets one preview request may render (1-100000).
preview_max = 256
# Finished jobs listed on the Jobs screen (kept in memory, 1-100000) and kept in
# the database (1-10000000; older ones are deleted).
job_history = 100
job_history_db = 1000
# TLS certificate chain and private key (PEM) to serve HTTPS with.
# [server.tls]
# cert = "/etc/wpg/cert.pem"
# key = "/etc/wpg/key.pem"
[auth]
# Admin password. Without one (and without a user created on the first-run
# setup screen) the server only listens on localhost. Sources, highest first:
# `wpg serve --password`, `--password-file`, $WPG_PASSWORD, password_hash,
# password_file, the setup screen.
# argon2id hash of the admin password (`wpg config set-password` writes it):
# password_hash = "$argon2id$v=19$m=19456,t=2,p=1$..."
# Or a file holding the hash or the plain-text password:
# password_file = "/etc/wpg/password"
# Session lifetime in seconds (extended by every request).
session_ttl_secs = 86400
[templates]
# Read-only template libraries (Git checkouts etc.), scanned recursively for
# *.wpg.yaml / *.wpg.json and reloaded when files change.
library_paths = ["./templates"]
# Writable directory for templates created or imported in the GUI.
# Default: <data_dir>/templates
# user_dir = "/var/lib/wpg/templates"
[protocols]
# Directories of user-defined protocol files (*.yaml), loaded at startup.
# Changes need a restart.
# dirs = ["/etc/wpg/protocols.d"]
[tx]
# Interfaces jobs may send on; empty = all. The null backend and dry runs are
# not restricted.
allowed_ifaces = []
# Highest rate a job may request, e.g. "100kpps" or "1Gbps". Jobs without a rate
# are sent at this rate.
# max_rate = "100kpps"
# Backend when a job names none: null, pcapfile, afpacket, pcap, afxdp, dpdk.
# Default: afpacket on Linux, else pcap, else null.
# default_backend = "afpacket"
# DPDK EAL arguments for the dpdk backend (wpg adds "-l <first CPU>" and
# "--in-memory" unless given). EAL starts with the first dpdk job; changing them
# needs a restart.
# dpdk_eal_args = ["-a", "0000:00:04.0"]
# Streams are pre-rendered (every frame built before sending) when they have at
# most prerender_max_packets packets and packets * frame length is at most
# prerender_max_bytes (default 256 MiB, up to 1 TiB); larger ones are built on
# the fly. `wpg send --prerender-max-bytes / --prerender-max-packets` override.
prerender_max_bytes = 268435456
prerender_max_packets = 100000000
# Memory of one afpacket TX ring / afxdp UMEM per worker in bytes (1 MiB-1 GiB,
# default 16 MiB); --ring-depth is reduced to fit. Locked memory: raise
# `ulimit -l` / LimitMEMLOCK for large values.
ring_bytes = 16777216
[snmp]
# SNMP tool screen and API (Get / Walk / Set / traps, MIB upload).
enabled = true
# Trap / inform receiver started at boot, e.g. "0.0.0.0:162" (ports below 1024
# need root or CAP_NET_BIND_SERVICE). Empty: not started at boot (it can be
# started from the UI).
trap_listen = ""
# Directory of uploaded MIB files. Empty: <data_dir>/mibs
mib_dir = ""
[dhcp]
# DHCP screen and API (DHCPv4 / DHCPv6 server, Linux only). Pools and options
# are edited on the screen and kept in <data_dir>/dhcp.json.
enabled = true
# Interface the server answers on, e.g. "eth1". Empty: chosen on the screen
# among tx.allowed_ifaces. Ports 67 / 547 need root or CAP_NET_BIND_SERVICE.
iface = ""
[log]
# Filter directives (RUST_LOG overrides this), e.g. "info" or "wpg_tx=debug,info".
level = "info"
# "pretty" or "json".
format = "pretty"
# Also write to this file (its directory is created).
# file = "/var/log/wpg/wpg.log"
# Rotation of the file: "never", "hourly" or "daily".
rotation = "never"
# Keep at most this many rotated files.
# max_files = 7
# Colour the console output when it is a terminal.
ansi = true
[terminal]
enabled = false # Web terminal (SSH / Telnet)
allowed_targets = [] # "host", "host:port" or CIDR; empty = any target
record_sessions = true # keep session logs under <data_dir>/terminal-logs
idle_timeout_secs = 1800
max_sessions = 8