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,76 @@
|
||||
# Running Steward
|
||||
|
||||
## The service
|
||||
|
||||
```sh
|
||||
systemctl status steward # or stewardd
|
||||
journalctl -u steward -f
|
||||
systemctl reload steward # reread the TLS certificate
|
||||
```
|
||||
|
||||
stewardd logs each configuration change, interfaces it starts or stops
|
||||
serving (and why it can't), addresses that answered the ping check or were
|
||||
declined, and full pools. DHCP messages themselves aren't logged: see
|
||||
them with `steward activity` or on the Activity page (the last 1000 are
|
||||
kept in memory).
|
||||
|
||||
## When a device gets no address
|
||||
|
||||
1. `steward status`: is its interface served? It may say:
|
||||
* `there is no interface eth0.20 on this server (yet)`: the VLAN
|
||||
interface doesn't exist. Steward serves it within 30 seconds of it
|
||||
appearing.
|
||||
* `address already in use`: another DHCP server holds port 67 on it.
|
||||
Stop it.
|
||||
* `permission denied`: stewardd lacks `CAP_NET_BIND_SERVICE`. Check the
|
||||
installed unit (`systemctl cat steward`).
|
||||
2. `steward activity --mac MAC -f`, then reconnect the device:
|
||||
* no DHCPDISCOVER at all: the request doesn't reach the server (a
|
||||
firewall, the wrong VLAN, or a relay, which 0.1 doesn't serve);
|
||||
* `NO ADDRESS`: the pools on that interface are full
|
||||
(`steward subnet list` shows how full);
|
||||
* `DHCPNAK` with a reason, then a new DISCOVER: the device asked for an
|
||||
address that doesn't belong there. That is normal after it moved
|
||||
networks.
|
||||
3. `steward lease list --search NAME` and `steward reservation show MAC`.
|
||||
|
||||
## Backups
|
||||
|
||||
`steward-backup.timer` runs `stewardd backup` daily. It writes a
|
||||
consistent copy of the database to `backup.dir`
|
||||
(`/var/backups/steward/steward-<time>.db`), and deletes those older than
|
||||
`backup.retention` (30 days), keeping at least `backup.keep_at_least` (7).
|
||||
A backup holds everything: configuration, leases, history, users, tokens
|
||||
(hashed) and the audit log.
|
||||
|
||||
```sh
|
||||
sudo -u steward stewardd backup # now
|
||||
sudo -u steward stewardd backup /tmp/s.db # to a file of your choice
|
||||
sudo systemctl disable --now steward-backup.timer # no daily backups
|
||||
```
|
||||
|
||||
To **restore**, stop stewardd first; restore refuses to replace the
|
||||
database under it:
|
||||
|
||||
```sh
|
||||
sudo systemctl stop steward
|
||||
sudo -u steward stewardd restore /var/backups/steward/steward-20261014T020000Z.db
|
||||
sudo systemctl start steward
|
||||
```
|
||||
|
||||
The old database is kept next to it as `steward.db.before-restore-<time>`.
|
||||
Leases handed out after the backup are missing from the restored one:
|
||||
the ping check stops those addresses from being handed out twice, and
|
||||
clients renewing them get a NAK and ask again.
|
||||
|
||||
## Upgrades
|
||||
|
||||
`apt upgrade` restarts a running stewardd. A new version upgrades the
|
||||
database when it starts, and an older one refuses a database a newer one
|
||||
has upgraded: restore a backup to go back.
|
||||
|
||||
## Checks
|
||||
|
||||
`stewardd check` validates the configuration in the database against
|
||||
this machine's interfaces, the same checks as `steward status` shows
|
||||
([validation.md](validation.md)).
|
||||
Reference in new issue
Block a user