Steward 0.1.0 (in development): a DHCPv4 server with a web UI, API and CLI
Subnets served per interface, pools, reservations, options at three levels, leases in SQLite saved before the ACK, ping and decline conflict checks, validated changes with history and undo, users and tokens, an audit log, a Kea importer, a sandboxed systemd unit and Debian packages. Tested with real udhcpc and dhcpcd clients in Docker (scripts/e2e.sh). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
commit
3c0808591f
111 files changed
+17851
No files matched your search
@@ -0,0 +1,93 @@
|
||||
# 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`, `user add|password|token`, `check`,
|
||||
`backup` (with pruning), `restore`, `config --example`.
|
||||
- **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.
|
||||
Reference in new issue
Block a user