-
Steward v0.1.0-rc.1 Pre-release
released this
2026-10-18 18:15:02 +01:00 | -8 commits to main since this releaseThe 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.
- Answers DISCOVER, REQUEST (selecting, init-reboot, renewing,
- Address choice, in this order:
- the client's reservation;
- the address it had before;
- the address it asks for;
- 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_holdsetting.
- An address is pinged before it is offered, and one that answers is
- 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.
- 27 by name (
- 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(orsteward -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.
- users, sessions with CSRF protection, and API tokens limited by role
- 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.
- commands: status, subnet, reservation, lease, activity, settings,
- 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.confand 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.
- global, shared-network and subnet options, pools, lease times and
stewarddcommands: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.acmeinsteward.yamlnames the certificate, andjarl: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.excludeinsteward.yaml(names or
shell patterns such asdocker*) leaves interfaces out of the web UI's
interface picker,steward interface listandGET /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_seenin 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). - Address order (docs/subnets.md): which never-used pool address a
new client gets,sequential(the lowest, as before),reverseor
random, in the settings, a subnet (--address-order) or a single
pool (--pool 10.0.10.200-10.0.10.250:random). A subnet's pools are
used in the order listed, or one at random (--pool-order random),
weighted by its never-used addresses. Pools now keep the order they are
given in. Kea'sallocator: randomis imported. - 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, alsostewardd.service)
whose only privilege isCAP_NET_BIND_SERVICE; - a daily backup timer, and sysusers and tmpfiles files;
- Debian packages
stewardandsteward-cli, and a Gitea release
workflow.
- a sandboxed systemd unit (
- 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.
Downloads
-
Source code (ZIP)
0 downloads
-
Source code (TAR.GZ)
0 downloads
- DHCPv4 server (