{
    "product": "Cenvero Stratum",
    "generated_at": "2026-08-03T07:18:08+00:00",
    "format": "cenvero-docs-v1",
    "document_count": 1,
    "documents": [
        {
            "slug": "networking/services",
            "title": "Network Services Control",
            "category": "Networking",
            "url": "https://www.stratum.cenvero.com/docs/networking/services",
            "headings": [
                {
                    "level": 1,
                    "text": "Network Services Control"
                },
                {
                    "level": 2,
                    "text": "The `service` command group"
                },
                {
                    "level": 3,
                    "text": "Seeing what is running"
                },
                {
                    "level": 3,
                    "text": "Turning a service on or off"
                },
                {
                    "level": 2,
                    "text": "Configuring DNS"
                },
                {
                    "level": 3,
                    "text": "Listen address"
                },
                {
                    "level": 3,
                    "text": "Allowed clients (recursion ACL)"
                },
                {
                    "level": 3,
                    "text": "Zones, records, and forwarders"
                },
                {
                    "level": 2,
                    "text": "Configuring DHCP"
                },
                {
                    "level": 3,
                    "text": "Scopes"
                },
                {
                    "level": 3,
                    "text": "Reservations and leases"
                },
                {
                    "level": 2,
                    "text": "Quick reference"
                },
                {
                    "level": 2,
                    "text": "See also"
                }
            ],
            "word_count": 1437,
            "markdown": "# Network Services Control\n\nThe agent runs a small set of **network services** alongside the data plane — among them the built-in DNS resolver and the DHCP server. Each one is independently switchable, so an operator can turn DNS or DHCP on or off, see whether it is actually listening, and tune how it binds and who may talk to it. This page covers the `service` command group, the DNS and DHCP configuration knobs, and the `dns …` / `dhcp …` operator commands. For zone and pool concepts, see [DHCP & DNS](/docs/networking/dhcp-dns).\n\n## The `service` command group\n\n`cenvero-str-ctl service` shows and toggles the agent's switchable network services: the REST, gRPC and WebSocket management APIs, the Prometheus metrics endpoint, **DNS**, and **DHCP**. The local control socket that `cenvero-str-ctl` itself rides is always up and is deliberately *not* a toggleable service — it cannot be turned off.\n\n### Seeing what is running\n\n```bash\ncenvero-str-ctl service status\n```\n\n```text\nNetwork services\n================\nSERVICE        ENABLED  ADDRESS            STATE      NOTE\nREST API       on       0.0.0.0:7070       listening\ngRPC API       on       0.0.0.0:7071       listening\nWebSocket API  on       0.0.0.0:7072       listening\nMetrics        on       127.0.0.1:9090     listening\nDNS            on       10.0.0.1:53        listening\nDHCP           on       :67                listening\n\nENABLED reflects the operator switch (applied at next restart); STATE is a live listen probe.\nApply a change with:  systemctl restart cenvero-stratum\n```\n\nThe two columns mean different things:\n\n- **ENABLED** is the operator switch — what the agent *would* start on its next restart.\n- **STATE** is a live probe of the address: `listening` (something is bound there now), `down` (nothing is), or `unknown` (the address could not be probed).\n\n`status` also answers to `list`, `top`, `ls`, and `ps`, and a bare `cenvero-str-ctl service` prints the same table. Add `--format json` (or `yaml`) for machine-readable output.\n\n### Turning a service on or off\n\nBoth word orders work, as do the `enable`/`disable` aliases:\n\n```bash\n# Turn the DNS resolver off\nsudo cenvero-str-ctl service dns off\n\n# Turn the DHCP server back on (these are equivalent)\nsudo cenvero-str-ctl service dhcp on\nsudo cenvero-str-ctl service on dhcp\nsudo cenvero-str-ctl service enable dhcp\n```\n\nToggling a service records its enable flag in the agent's local override store — the same mechanism `config set` uses — so the change **persists across reboots**. It is *not* applied to the running process immediately: it takes effect on the next agent restart. The command reminds you how:\n\n```text\nService dns (DNS) disabled.\nVerify with:  cenvero-str-ctl service status\n```\n\n```bash\nsudo systemctl restart cenvero-stratum\n```\n\n> **DNS and DHCP only switch their network listeners.** With DHCP off, the agent stops binding UDP `:67` (it hands out no addresses) but the lease table and its expiry bookkeeping keep running, so existing leases are still tracked. With DNS off, the resolver does not bind a port; zone and record data is untouched and still served over the management API. Turning the service back on and restarting re-binds it.\n\nThe IPC control socket cannot be disabled — asking to turn off `ipc` (or `socket`) is refused with an explanation rather than silently accepted, because it is the channel this very command travels over.\n\n## Configuring DNS\n\nThe agent is **authoritative** for each network's internal zone (e.g. `app-net.internal`) and acts as a **recursive forwarder** for everything else. Two settings control where it listens and who may use it for recursion.\n\n### Listen address\n\nBy default the resolver binds the **management bridge's** IPv4 address (falling back to the user bridge, then loopback `127.0.0.1:53` before a bridge has an address). It is **never** bound to a wildcard such as `0.0.0.0:53`, so it is not exposed as an open forwarder on an untrusted NIC.\n\nTo pin it to a specific address, set `dns_listen_addr` to a bare IP or a `host:port`. `config set` takes the key and value positionally:\n\n```bash\nsudo cenvero-str-ctl config set dns_listen_addr 10.0.0.1\n```\n\nSetting it back to empty reverts to the bridge-address default:\n\n```bash\nsudo cenvero-str-ctl config set dns_listen_addr \"\"\n```\n\nThe address change is applied on the next agent restart; confirm the resulting bind with `service status`.\n\n### Allowed clients (recursion ACL)\n\nRecursion — forwarding a query for a name *outside* the local zones to an upstream resolver — is gated by a client ACL so the agent is never an open resolver. Set the allowed clients as a comma-separated list of IPs and/or CIDRs:\n\n```bash\nsudo cenvero-str-ctl config set dns_allowed_clients \"10.20.0.0/24,10.30.0.0/24\"\n```\n\nWhen the list is empty (the default) it falls back to the loopback and private ranges (`127.0.0.0/8`, `::1/128`, `10.0.0.0/8`, `172.16.0.0/12`, `192.168.0.0/16`, `fc00::/7`). A query from a client outside the allowed set is **refused**, not silently forwarded. Authoritative answers for the local zones are always returned regardless of the ACL.\n\n### Zones, records, and forwarders\n\nDay-to-day zone and record management uses the `dns` command group:\n\n| Command | Purpose |\n|---------|---------|\n| `dns zones` | List the authoritative zones with their ids |\n| `dns zone add <name>` | Create a zone |\n| `dns zone delete <zone_id>` | Delete a zone |\n| `dns records` / `dns list [zone_id]` | List records (all zones, or one zone) |\n| `dns record add <zone_id> <name> <type> <value> [ttl]` | Add a record to a zone |\n| `dns record delete <record_id>` | Remove a record |\n\nZones and records are addressed by their numeric ids, which `dns zones` and `dns list` report:\n\n```bash\n# List zones to find the zone id, then add and remove a record\ncenvero-str-ctl dns zones\nsudo cenvero-str-ctl dns record add 1 api A 10.20.0.55 300\ncenvero-str-ctl dns list 1\nsudo cenvero-str-ctl dns record delete 3\n```\n\n`dns add` and `dns delete` are shorthand aliases for `dns record add` and `dns record delete`.\n\n**Upstream forwarders** (the resolvers recursion is sent to) are managed live with the `dns forwarder list/set/add/remove` commands and take effect on the running agent; persist them across restarts with `config set dns_upstreams <ip,...>`. See [DHCP & DNS → Upstream forwarders](/docs/networking/dhcp-dns).\n\n## Configuring DHCP\n\nThe DHCP server leases addresses to each network's endpoints from that network's IPAM pool and binds UDP `:67` while it is enabled.\n\n### Scopes\n\nA **scope** binds a client subnet to its own IPAM pool and the reply parameters advertised to clients on that subnet — the server identity, gateway, subnet mask, DNS servers, and an optional per-scope lease length. A relayed request is matched to its scope by the relay's `giaddr`; a directly-attached one by the interface it arrived on. A network created with `network create` gets a scope automatically; multiple scopes let one agent serve several subnets (including relayed ones).\n\nScopes (`dhcp_scopes`) are part of the node's configuration rather than a live `config set` field — they are provisioned with the node config, not set on the node. Each scope carries:\n\n| Field | Meaning |\n|-------|---------|\n| `subnet` | The client subnet the scope serves (CIDR) |\n| `pool_id` | The IPAM pool addresses are leased from |\n| `server_ip` | The DHCP server identity advertised to clients |\n| `gateway` | The default gateway offered to clients |\n| `subnet_mask` | The subnet mask offered to clients |\n| `dns` | The DNS server(s) offered to clients |\n| `lease_seconds` | Optional per-scope lease length (0 = the server default) |\n\n### Reservations and leases\n\nUse the `dhcp` command group to inspect leases and to pin or release an address:\n\n| Command | Purpose |\n|---------|---------|\n| `dhcp leases` | List current leases (MAC, IP, hostname, expiry) |\n| `dhcp reserve` | Pin a specific IP to a MAC (a static lease) |\n| `dhcp release` | Release a lease/reservation early |\n\nThe reserved IP selects its own pool, so these commands identify a client by MAC rather than by network:\n\n```bash\n# Always hand db-primary the same address\nsudo cenvero-str-ctl dhcp reserve \\\n  --mac 52:54:00:de:ad:01 \\\n  --ip 10.30.0.10 \\\n  --hostname db-primary\n\n# Inspect what is leased, and what is pinned\ncenvero-str-ctl dhcp leases\ncenvero-str-ctl dhcp reservations\n\n# Release a reservation before re-provisioning a workload\nsudo cenvero-str-ctl dhcp release --mac 52:54:00:ab:01:02\n```\n\nA reservation pins the address only — it does not create a DNS record. To make the hostname resolve to the reserved IP, add a DNS record for it with `dns record add` (or the API). See [DHCP & DNS → Reservations](/docs/networking/dhcp-dns) for how reservations and the lease table behave in more depth.\n\n## Quick reference\n\n| Task | Command |\n|------|---------|\n| See every service's switch + live state | `cenvero-str-ctl service status` |\n| Turn DNS off / on | `sudo cenvero-str-ctl service dns off` / `… dns on` |\n| Turn DHCP off / on | `sudo cenvero-str-ctl service dhcp off` / `… dhcp on` |\n| Apply a service toggle | `sudo systemctl restart cenvero-stratum` |\n| Set the DNS listen address | `sudo cenvero-str-ctl config set dns_listen_addr <ip>` |\n| Set the DNS recursion allow-list | `sudo cenvero-str-ctl config set dns_allowed_clients <cidrs>` |\n| Reserve / release a DHCP address | `sudo cenvero-str-ctl dhcp reserve …` / `dhcp release …` |\n| Manage a DNS record | `sudo cenvero-str-ctl dns add …` / `dns delete …` |\n\n## See also\n\n- [DHCP & DNS](/docs/networking/dhcp-dns) — pools, leases, zones, and forwarders in depth.\n- [Networking Overview](/docs/networking/overview) — where DNS and DHCP sit in the data plane.\n- [Zero-Trust Firewall](/docs/networking/firewall) — DNS on port 53 must be explicitly allowed for cross-network queries.\n- [Configuration](/docs/configuration) — how settings reach a node and what lives in the node config.\n- [CLI Reference](/docs/cli) — the full command surface.\n"
        }
    ]
}