# Changelog All notable changes to Steward are documented here. The format follows [Keep a Changelog](https://keepachangelog.com/en/1.1.0/), and versions follow [Semantic Versioning](https://semver.org/). ## [Unreleased] The first version of Steward, a DHCPv4 server with a web UI, a REST API and a CLI, built the way Jarl is. ### Added - **DHCPv4 server** (`stewardd serve`): - Answers DISCOVER, REQUEST (selecting, init-reboot, renewing, rebinding), DECLINE, RELEASE and INFORM, as RFC 2131 describes. - Serves each subnet on its own network interface, with a socket per interface bound to it, so a VLAN's clients only get that VLAN's addresses. - Several subnets on one interface are served together, as a shared network. - Opens an interface's socket when the interface appears, such as a VLAN that comes up later, and closes it when its last subnet goes. - **Address choice**, in this order: 1. the client's reservation; 2. the address it had before; 3. the address it asks for; 4. a pool address never handed out, else the one free the longest. - **Reserved addresses** are never handed out to anyone else, even inside a pool. - **Leases** are kept in SQLite and saved before the ACK is sent. Ended ones stay 30 days, so returning clients get their address again. - **Conflict checks:** - An address is pinged before it is offered, and one that answers is held back. - An address a client declines is held back for a day. - Both use the `decline_hold` setting. - **Authority:** a request for an address that doesn't belong on the interface gets a NAK, so the client starts over at once. This can be turned off when another server shares a network. - **Options:** - 27 by name (`routers`, `domain-name-servers`, `domain-search`, `ntp-servers`, `classless-static-route`, …), and any other by number with a type. - Set globally, per subnet and per reservation, the most specific winning. - When a client sends a parameter request list, it gets what it asked for, in that order. - **Configuration changes:** - Validated as a whole, with stable problem codes (docs/validation.md). - Saved with a history entry, and can be undone after a check that nothing changed since. - `?dry_run=1` (or `steward -n`) previews a change. - **REST API** (docs/api.md): - users, sessions with CSRF protection, and API tokens limited by role or grant (`config`, `leases`, `audit`); - an audit log; - a local unix socket where root needs no token. - **CLI** `steward` (docs/cli.md): - commands: status, subnet, reservation, lease, activity, settings, option, interface, history (with undo), import kea, user, token, password, audit, config; - output as tables, JSON, YAML or IDs. - **Web UI:** - a dashboard of interfaces, pool use, problems and recent messages; - subnets with their leases, reservations and settings; - leases, with reserve and delete; - reservations; - live DHCP activity; - settings and global options; - history with undo, the audit log, users and tokens. - A new subnet suggests its network and a pool from the interface's address. - **Kea import:** `steward import kea` (`POST /import/kea`) reads a `kea-dhcp4.conf` and its lease files (docs/kea.md): - global, shared-network and subnet options, pools, lease times and reservations; - each subnet's interface: Kea's, else the host's interface with an address in the subnet, else `--interface PREFIX=IFACE`. - It lists what it doesn't support instead of dropping it silently. - Importing again keeps subnets' and reservations' IDs and Steward's subnet names. - **`stewardd`** commands: `init` (asks for the administrator's name), `user add|password|token`, `check`, `backup` (with pruning), `restore`, `config --example`. - **The web UI's certificate from Let's Encrypt, through Jarl** (docs/certificates.md, docs/jarl.md): - `tls.acme` in `steward.yaml` names the certificate, and `jarl:` the Jarl server and a token that may only write the challenge record. - Steward gets the certificate with the DNS-01 challenge, writing the record through Jarl's API into every view that has the zone. - It renews with a third of the lifetime left, and swaps the new certificate in without a restart. - A check runs before every order, and on demand: Jarl, the zone, the token's permission, a test record, the zone's public name servers and public resolvers, clean-up. Each step says what to fix. - It starts with Let's Encrypt's staging service by default. - `steward cert`, `cert check`, `cert renew`; Server → Certificate in the web UI; `GET /certificate`, `POST /certificate/check|renew`. - Dashboard problems: `certificate_failed`, `certificate_expiring`, `certificate_staging`. - **HTTPS and plain HTTP on one port:** with a certificate, plain HTTP is redirected to HTTPS, except from the server itself (also for `tls.cert_file`). - **Disabled reservations** (`steward reservation disable|enable`, Disable in the web UI): kept but ignored, so the client gets a pool address like any other. Subnets get Disable/Enable buttons in the web UI too. - **Hidden interfaces:** `interfaces.exclude` in `steward.yaml` (names or shell patterns such as `docker*`) leaves interfaces out of the web UI's interface picker, `steward interface list` and `GET /interfaces`. - **Last seen:** with the ping check on, active leases' addresses are pinged every minute, and a client that answers gets a last-seen time (Leases page, reservations' online badge, `steward lease list|show`, `steward reservation list|show`, `last_seen` in the API). A client that blocks pings stays online for as long as its lease lasts, without one. - **The Reservations page refreshes itself** every 15 seconds, so online and last seen stay current. - **Activity by subnet:** `steward activity --subnet`, a subnet filter on the Activity page, `GET /events?subnet=` (ID, name or prefix). - **Token rotation** (`steward token rotate`, `POST /tokens/{id}/rotate`, Rotate in the web UI): a new secret for a token, with an optional grace period for the old one, as in Jarl. - **Packaging:** - a sandboxed systemd unit (`steward.service`, also `stewardd.service`) whose only privilege is `CAP_NET_BIND_SERVICE`; - a daily backup timer, and sysusers and tmpfiles files; - Debian packages `steward` and `steward-cli`, and a Gitea release workflow. - **The Steward logo:** a key whose bow is a crown with Jarl's network nodes, in Jarl's blue and white, with a STEWARD wordmark in Jarl's letters.