Configuration
The agent starts from sensible built-in defaults and, on top of those, loads
an optional node configuration file. If the file is absent the defaults are used,
so a freshly-installed node runs without any config at all. Point the agent at a
specific file with --config <path>.
# Run with the default config (if one is present)
cenvero-stratum
# Or an explicit path
cenvero-stratum --config /etc/cenvero-str/config.cenvero-stratum
This page is the full reference for every configuration field: what it is, its type, default, accepted values, and which command controls it. Use it alongside the CLI Reference.
How configuration is delivered and layered
There are three layers, applied in order — each later layer wins:
- Built-in defaults. Compiled into the agent (the table values marked
- The node config file (
config.cenvero-stratum). A signed configuration
- Operator local overrides (
config.local.cenvero-stratum). A small sidecar
cenvero-str-ctl config set / service. These
take precedence over the panel-delivered config and survive a panel re-sync
— see the Operator local overrides section below.
The provisioning installer writes the initial config file for you; you don't author it by hand. Day-to-day local adjustments go throughconfig setandservice, which write the override sidecar — never the main file.
How the config is signed and verified
The node config and the override sidecar are stored as signed configuration files the agent loads directly — they are not hand-written text.
For production, the panel cryptographically signs the config it delivers, and the agent verifies that signature on load so it refuses to boot from a forged or tampered file delivered over the network. The trust model is deliberately fail-closed where it matters and permissive where it can't hurt you:
- No file on disk — the agent boots on built-in defaults (a fresh node still
- A signed config (the normal panel-delivered case) — the signature must
- An unsigned local bootstrap config (what the installer writes on first
You inspect (never edit) the on-disk file with cenvero-str-ctl config show,
which decodes and prints it; secret values are redacted unless you add
--include-secrets.
sudo cenvero-str-ctl config show # decoded, secrets redacted
sudo cenvero-str-ctl config show --format json # machine-readable
Launch flags
A handful of settings can be overridden at process launch (these affect that one run; persistent changes belong in the config or the override sidecar):
| Flag | Type | Default | What it does |
|---|---|---|---|
--config <path> | path | (none) | Path to the node config file. If omitted, built-in defaults are used. |
--bind <addr> | IP | (from config) | Override the API bind address for this run. |
--log-level <level> | enum | info | Log verbosity: debug, info, warn, or error. |
--allow-unsigned-config | flag | false | Dev only, insecure. Load the config without verifying its signature. Never use in production. |
Identity and node fields
These describe the node itself. node_id and license_server are
panel/identity-owned: set at install or by the panel-signed config (and, where
noted, refused by config set — see Keys that cannot be set locally below).
log_level is the exception — it is operator-settable, per its row.
| Key | Type | Default | Accepted values | What it does | Controlled by |
|---|---|---|---|---|---|
node_id | string | (empty) | UUID | Stable node identity; binds the license. Also the VXLAN VTEP source fallback when it parses as an IP. | Install / panel |
license_server | string (URL) | https://license.cenvero.com | Base URL | License/activation server. Empty falls back to the built-in default. | Install / panel |
log_level | enum | info | debug, info, warn, error | Agent log verbosity. | config set log_level |
There is no node-mode setting any more. Older versions carried a
node_mode field that chose between a Compute node and a Gateway node. Every
node now routes, the field is gone, and a node updating from an older version
has its configuration migrated automatically — see
Nodes and Interfaces.
Paths
Filesystem locations the agent uses. These follow the standard cenvero-str
layout and are set by the installer; they are not adjusted with config set.
| Key | Type | Default | What it does |
|---|---|---|---|
data_dir | path | /var/lib/cenvero-str/ | Persistent state — the node's own records and supporting files. |
config_dir | path | /etc/cenvero-str/ | Configuration directory (holds the config file and the override sidecar). |
socket_path | path | /run/cenvero-str/cenvero-str.sock | Unix socket cenvero-str-ctl uses to talk to the agent. |
Ports
The agent listens on a fixed set of ports. The defaults rarely need changing; when they do, the five listen ports are settable via the local override sidecar. Open these between cluster members on the management network only.
| Key | Type | Default | Protocol | Purpose | Controlled by |
|---|---|---|---|---|---|
port_rest | int (1-65535) | 7070 | HTTPS | REST management API. | config set port_rest |
port_grpc | int (1-65535) | 7071 | TCP | gRPC management API (node-to-node control). | config set port_grpc |
port_websocket | int (1-65535) | 7072 | WebSocket | Live events / streaming. | config set port_websocket |
port_cluster | int (1-65535) | 7073 | TCP | Cluster state replication. | config set port_cluster |
port_ha_heartbeat | int (1-65535) | 7074 | UDP | Gateway HA heartbeat. | config set port_ha_heartbeat |
API
The local management API (REST / gRPC / WebSocket). The bind address, rate limits,
and allow-lists are settable locally; the bearer token is a credential and is
refused by config set (rotate it at install or via the panel).
| Key | Type | Default | Accepted values | What it does | Controlled by |
|---|---|---|---|---|---|
api_bind_address | IP | 0.0.0.0 | Any IP (use 0.0.0.0 / :: for all interfaces) | IP the REST/gRPC/WebSocket APIs listen on. A host:port or hostname is rejected — this is an IP only. | config set api_bind_address |
api_rate_limit | int (≥ 0) | 1000 | 0 disables the limiter | Requests per minute per key. | config set api_rate_limit |
api_rate_burst | int (≥ 0) | 100 | 0 or higher | Burst allowance above the per-minute rate. | config set api_rate_burst |
api_allowed_ips | list of IP/CIDR | (empty) | Comma-separated IPs/CIDRs; empty = allow all | IPs/CIDRs allowed to reach the API. | config set api_allowed_ips |
api_allowed_origins | list of string | (empty) | Comma-separated origins; empty = same-host only | Allowed WebSocket Origin values. | config set api_allowed_origins |
api_token | string (secret) | (empty) | Bearer token | Token required for protected REST/gRPC/WS endpoints. Empty means the local management API is disabled. | Install / panel (refused by config set) |
Set the API token at install time with
cenvero-str-ctl config encode --generate-api-token (mints a fresh random token
and enables the API). It is a credential, not an operational setting.
TLS
TLS material for the management API. Paths are managed by the certificate manager
(cenvero-str-ctl tls ...) — they are not set with config set.
| Key | Type | Default | What it does | Controlled by |
|---|---|---|---|---|
tls_auto_generate | bool | true | Auto-generate a self-signed certificate on first start. | Install / cert manager |
tls_cert_path | path | /etc/cenvero-str/tls/server.crt | TLS certificate. | Cert manager (refused by config set) |
tls_key_path | path | /etc/cenvero-str/tls/server.key | TLS private key. | Cert manager (refused by config set) |
tls_pubkey_path | path | /etc/cenvero-str/tls/server.pub | TLS public key file. | Cert manager (refused by config set) |
grpc_client_ca_dir | path | (empty) | When set, contains ca.pem used to require + verify gRPC client certificates (mTLS). | Provisioned (refused by config set) |
Cluster
Clustering identity and transport security. These are panel-orchestrated /
provisioned and are not set with config set. Cluster TLS material is
mandatory — clustering refuses to start without it (no plain-TCP downgrade).
| Key | Type | Default | What it does | Controlled by |
|---|---|---|---|---|
cluster_enabled | bool | false | Whether this node participates in a cluster. | Panel |
cluster_bind_addr | string | (empty) | Address the cluster transport binds. | Panel (refused by config set) |
cluster_bootstrap | bool | false | Whether this node bootstraps a new cluster. | Panel |
cluster_cert_dir | path | (empty) | Directory holding cert.pem, key.pem, and ca.pem for cluster mTLS. | Provisioned (refused by config set) |
Gateway and HA
These name the two interfaces the node's forwarding path is placed on, and
configure the HA pairing. Naming the interfaces is what puts NAT and routing on
them — there is no separate switch to turn the gateway path on. Leave them empty
and the node still hosts workloads and serves its networks; it simply forwards
nothing across an edge. The HA shared key is a cluster secret and is refused
by config set (it must match the peer).
| Key | Type | Default | What it does | Controlled by |
|---|---|---|---|---|
gateway_wan_interface | string | (empty) | The outward-facing interface the forwarding path (NAT + routing) uses. | Install / panel |
gateway_lan_interface | string | (empty) | The inward-facing interface the forwarding path uses. | Install / panel |
wan_dhcp | bool | false | Run the built-in DHCP client on the WAN interface to obtain the uplink address. When false, the WAN address is static/config. | Install / panel |
gateway_vip | string (IP) | (empty) | Virtual IP the HA pair owns; the ACTIVE node assumes it and announces it via gratuitous ARP, releasing it on losing ACTIVE. Empty registers no VIP. | Install / panel |
gateway_peer_addr | string | (empty) | HA peer address (host or host:port; the HA heartbeat port is appended when absent). Empty disables HA peering (solo gateway). | Install / panel |
gateway_priority | int | 0 | Biases which node becomes ACTIVE; higher wins. 0 leaves the manager default. | Install / panel |
gateway_shared_key | string (secret) | (empty) | Shared key authenticating the HA heartbeat; must match the peer. | Install / panel (refused by config set) |
Overlay (VXLAN) and load balancer
| Key | Type | Default | What it does | Controlled by |
|---|---|---|---|---|
vtep_local_ip | string (IP) | (empty) | Underlay source IP for VXLAN tunnels. Empty falls back to node_id only if it parses as an IP (a hostname node_id is rejected with a warning). | Install / panel |
lb_interface | string | (empty) | VIP-facing interface the L4 load balancer uses. Empty leaves the load balancer unattached. Must be a dedicated interface — not one already used by the bridge or gateway data plane. | Install / panel |
Intrusion detection (IDS)
Opt-in per-source scan/flood detection on an interface's ingress.
| Key | Type | Default | What it does | Controlled by |
|---|---|---|---|---|
ids_interface | string | (empty) | Interface whose ingress the IDS collector watches. Empty leaves IDS disabled. May be an interface already used by the data plane — typically the uplink/WAN or cnv-user-br0. | Install / panel |
ids_auto_block | bool | false | false = alert only (a detection raises an event but does not touch traffic). true adds a confirmed scanner/flooder's IPv4 source to the firewall blocklist with an auto-expiring TTL. Opt-in because a false positive would cut off a legitimate source. | Install / panel |
DNS
The built-in resolver. The listen address and client ACL are settable locally; DNSSEC is panel-managed.
| Key | Type | Default | Accepted values | What it does | Controlled by |
|---|---|---|---|---|---|
dns_listen_addr | string | (empty) | IP, or host:port, or empty | Address the DNS server binds. Empty binds the management bridge address only (not the WAN), so the resolver isn't exposed by default. | config set dns_listen_addr |
dns_allowed_clients | list of IP/CIDR | (empty) | Comma-separated IPs/CIDRs; empty = local/private ranges | Clients permitted to query the resolver. Empty falls back to local/private ranges — never an open resolver. | config set dns_allowed_clients |
dnssec_enabled | bool | false | true/false | Authoritative DNSSEC signing (per-zone keys, RRSIG/DNSKEY served when the client sets the DO bit). Default off = unsigned answers (back-compat). | Install / panel |
DHCP
The built-in DHCP server. Per-network scopes are panel-managed (set as
operational resources, not in the static config); the DHCP service itself is
toggled with service dhcp.
| Key | Type | Default | What it does | Controlled by |
|---|---|---|---|---|
dhcp_scopes | list | (empty = single default pool) | Per-network DHCP scopes: each binds a client subnet to its own IPAM pool and reply parameters (gateway / mask / DNS / lease length). Matched by giaddr (relayed) or the receiving interface (directly attached). | Panel / API |
Metrics
| Key | Type | Default | What it does | Controlled by |
|---|---|---|---|---|
metrics_bind_addr | string (host:port) | 127.0.0.1:9090 | Address the Prometheus /metrics endpoint binds. Defaults to loopback so it isn't exposed on 0.0.0.0; point it at a management address to scrape it off-box. The host must be an IP, not a hostname. | config set metrics_bind_addr |
Network services (on/off switches)
Each network service can be turned on or off. These are stored inverted as
*_disabled keys, so the default — every service running — is preserved for any
older config. The friendly front door is cenvero-str-ctl service <name> on|off;
the raw equivalent is config set <name>_disabled true|false, and the two
round-trip with config show. All default to enabled.
| Service name | config key | Default | What it gates |
|---|---|---|---|
rest | rest_disabled | enabled | The REST management API (also serves the operator/billing API). |
grpc | grpc_disabled | enabled | The gRPC management API. |
websocket | websocket_disabled | enabled | The WebSocket management API. |
metrics | metrics_disabled | enabled | The Prometheus /metrics endpoint. |
dns | dns_disabled | enabled | The built-in DNS server bind (on top of the listen-address gate). |
dhcp | dhcp_disabled | enabled | The built-in DHCP protocol server bind (the lease table still runs). |
# Toggle a service (writes the override sidecar; applies on restart)
sudo cenvero-str-ctl service dns off
sudo cenvero-str-ctl service status # ENABLED / ADDRESS / live STATE per service
# Equivalent raw form
sudo cenvero-str-ctl config set dns_disabled true
The IPC control socket is not a toggleable service — it is how
cenvero-str-ctl talks to the agent, so it can never be disabled. Disabling the
REST API is allowed but warns first, because it also carries the operator/billing
API.
Operator local overrides
config set and service never touch the main config.cenvero-stratum file.
They write a separate operator local-overrides sidecar
(config.local.cenvero-stratum, mode 0600) in the config directory. The agent
overlays this on top of its config at boot, so:
- A locally-set field takes effect on the next agent restart, and
- it survives a configuration re-sync from the panel (which rebuilds the main
# The general form is: config set <key> <value>
sudo cenvero-str-ctl config set api_rate_limit 2000
# Legacy shortcut flags for the three most common API keys
sudo cenvero-str-ctl config set --api-bind 10.0.0.5 --api-rate-limit 2000 --api-rate-burst 200
# Run with no value to list every settable key
sudo cenvero-str-ctl config set
# Apply the change
sudo systemctl restart cenvero-stratum
Settable keys (the local whitelist)
Only these safe operational keys can be set locally. Everything else is refused.
log_level, api_bind_address, api_rate_limit, api_rate_burst,
api_allowed_ips, api_allowed_origins, api_read_timeout_secs,
api_write_timeout_secs, api_idle_timeout_secs, port_rest, port_grpc,
port_websocket, port_cluster, port_ha_heartbeat, metrics_bind_addr,
dns_listen_addr, dns_allowed_clients, dns_upstreams,
heal_interval_seconds, heal_disabled_checks, and the six service switches
(rest_disabled, grpc_disabled, websocket_disabled, metrics_disabled,
dns_disabled, dhcp_disabled).
Keys that cannot be set locally
Identity, the license server, credentials, and signing / cluster-secret / TLS
material are refused by config set with an explanation — they are panel- or
identity-owned and must never come from a local edit:
| Refused key | Why |
|---|---|
node_id | Panel-assigned identity; binds the license. |
license_server | Panel-controlled (set at install / by the signed config). |
api_token | A credential — rotate it at install/panel, not via config set. |
gateway_shared_key | A cluster secret that must match the HA peer. |
cluster_bind_addr | Clustering identity/secret is panel-orchestrated. |
cluster_cert_dir | Cluster mTLS material is provisioned. |
grpc_client_ca_dir | gRPC client-mTLS CA material is provisioned. |
tls_cert_path | TLS material is managed by the cert manager. |
tls_key_path | TLS material is managed by the cert manager. |
tls_pubkey_path | TLS material is managed by the cert manager. |
What is not in this file
Operational resources — **networks, endpoints, IP pools, firewall rules, load
balancers, DNS/DHCP zones — are not** part of the node config. They are
managed at runtime through the agent's API and cenvero-str-ctl (and replicated
across a cluster), not baked into the static node config. Use the relevant
CLI command group for each.
Ports summary
Open these between cluster members on the management network only:
| Port | Protocol | Purpose |
|---|---|---|
| 7070 | HTTPS | Management API |
| 7071 | TCP | Node-to-node control |
| 7072 | WebSocket | Live events / streaming |
| 7073 | TCP | Cluster state replication |
| 7074 | UDP | Gateway HA |
A note on time
Stratum works in UTC everywhere and cross-checks the host clock against NTP.
Large time drift is treated as a tamper signal for licensing, so keep chronyd
or systemd-timesyncd running on every node.
Next steps
- CLI Reference — the full command surface.
- Clustering Overview — joining nodes into a cluster.
- Licensing — how enforcement interacts with the agent.