release / release (push) Successful in 3m22s
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
122 lines
5.9 KiB
Markdown
122 lines
5.9 KiB
Markdown
<p align="center"><img src="artwork/banner.svg" width="340" alt="Steward: a key whose bow is a crown with network nodes, above the STEWARD wordmark"></p>
|
|
|
|
# Steward
|
|
|
|
*Every Hold has a steward at the door; this one gives each newcomer an address.*
|
|
|
|
Steward is a DHCPv4 server you configure through a web UI, a REST API and
|
|
a command line client, all three backed by the same API. It is the
|
|
companion of [Jarl](https://gitea.adbraun.lol/adam/jarl), the BIND manager,
|
|
and works the same way: every change is checked as a whole before it is
|
|
used, is recorded in a history where it can be undone, and is audited.
|
|
|
|
In Skyrim, a steward greets whoever comes to the door and sees to their
|
|
needs. Steward is the first thing a device meets when it joins your
|
|
network: it greets it, gives it an address, and tells it the way around
|
|
(the router, the DNS servers).
|
|
|
|
## What it does
|
|
|
|
* **Subnets per interface.** Each subnet names the network interface it is
|
|
served on (`eth0`, `eth0.20`, `br-iot`). Clients only get addresses from
|
|
the subnets of the interface their request came in on, so each VLAN gets
|
|
its own addresses, whatever its clients ask for.
|
|
* **Pools, reservations and options.** Pools are ranges handed out to any
|
|
client. Reservations fix a client's address, by MAC address or client
|
|
identifier, optionally with a host name and options of its own. Options
|
|
can be set for every subnet, per subnet and per reservation; the most
|
|
specific wins. The common options have names (`routers`,
|
|
`domain-name-servers`, `domain-search`, `ntp-servers`,
|
|
`classless-static-route`, …), and any other can be set by number.
|
|
* **Leases that survive.** Leases live in SQLite and are written before the
|
|
client gets its answer, so a crash or a restart never hands an address
|
|
out twice. A client that comes back gets the address it had.
|
|
* **Conflict checks.** An address is pinged before it is offered. One that
|
|
answers, or that a client declines, is held back for a day.
|
|
* **Changes you can trust.** Each change is validated as a whole, with
|
|
errors that say what is wrong and how to fix it. A dry run shows what a
|
|
change would do; the history shows every change, field by field, and
|
|
undoes any of them.
|
|
* **Easy to watch.** The dashboard shows each interface and whether it is
|
|
served, how full each subnet's pools are, and any problems. The Activity
|
|
page lists the latest DHCP messages, so you can see why a device didn't
|
|
get an address.
|
|
* **Moving from Kea.** `steward import kea` reads a `kea-dhcp4.conf` and
|
|
Kea's lease file, so clients keep their addresses ([docs/kea.md](docs/kea.md)).
|
|
* **Users and tokens.** Each user and API token gets permissions: an
|
|
administrator, or `config`, `leases` and `audit` access, read or write.
|
|
On the server itself, root needs no setup: the CLI uses stewardd's local
|
|
socket.
|
|
* **HTTPS on its own.** Give it a name and a Jarl token, and Steward gets its
|
|
web UI's certificate from Let's Encrypt and renews it, with Jarl
|
|
publishing the DNS-01 challenge. It checks the whole path first, so a
|
|
broken setup never wastes Let's Encrypt's rate limits
|
|
([docs/certificates.md](docs/certificates.md)).
|
|
* **One small service.** `stewardd` is one static binary, run by a
|
|
sandboxed systemd unit whose only privilege is binding port 67. Debian
|
|
packages and a daily backup timer are included.
|
|
|
|
Not yet: relays (`giaddr`), DHCPv6, failover, client classes, and
|
|
registering clients' names in DNS through Jarl ([docs/design.md](docs/design.md)).
|
|
|
|
## Quick start
|
|
|
|
On Debian or Ubuntu, from the package registry (see
|
|
[docs/install.md](docs/install.md) for other ways):
|
|
|
|
```sh
|
|
sudo apt install steward
|
|
sudo -u steward stewardd init # asks for the admin password
|
|
sudo systemctl enable --now steward
|
|
|
|
sudo steward subnet add 10.0.10.0/24 --interface eth0 --name office \
|
|
--pool 10.0.10.100-10.0.10.199 \
|
|
--option routers=10.0.10.1 --option domain-name-servers=10.0.10.2
|
|
sudo steward settings set --option domain-name=lan
|
|
sudo steward reservation add 10.0.10.20 aa:bb:cc:dd:ee:01 --hostname nas
|
|
sudo steward status
|
|
```
|
|
|
|
The web UI is on `http://127.0.0.1:8067/` (see `listen` in
|
|
`/etc/steward/steward.yaml`).
|
|
|
|
Coming from Kea:
|
|
|
|
```sh
|
|
sudo steward import kea /etc/kea/kea-dhcp4.conf --leases /var/lib/kea/kea-leases4.csv -n # look first
|
|
sudo steward import kea /etc/kea/kea-dhcp4.conf --leases /var/lib/kea/kea-leases4.csv
|
|
sudo systemctl disable --now kea-dhcp4-server
|
|
```
|
|
|
|
## Documentation
|
|
|
|
* [install.md](docs/install.md): packages, building from source, first steps
|
|
* [subnets.md](docs/subnets.md): subnets, interfaces, pools, reservations, options, leases, and how addresses are chosen
|
|
* [options.md](docs/options.md): the options Steward knows and how to write their values
|
|
* [kea.md](docs/kea.md): moving from Kea
|
|
* [certificates.md](docs/certificates.md): HTTPS with a certificate from Let's Encrypt, through Jarl
|
|
* [jarl.md](docs/jarl.md): connecting Steward to Jarl, and what its token may do
|
|
* [cli.md](docs/cli.md): the `steward` command line client
|
|
* [api.md](docs/api.md): the REST API
|
|
* [configuration.md](docs/configuration.md): `/etc/steward/steward.yaml`
|
|
* [permissions.md](docs/permissions.md): users, roles, grants and API tokens
|
|
* [operations.md](docs/operations.md): backups, logs, upgrades, troubleshooting
|
|
* [validation.md](docs/validation.md): every check and what it means
|
|
* [design.md](docs/design.md): how Steward is built, and what 0.1 leaves out
|
|
* [development.md](docs/development.md): building, testing, releasing
|
|
|
|
## Status
|
|
|
|
Version 0.1.0 is the current release: a DHCPv4 server with subnets per
|
|
interface, reservations (by MAC address, client ID or either, with their
|
|
own lease time), a web UI, REST API and CLI, Kea import, the web UI's
|
|
certificate through Jarl, clients' last-seen times and a choice of address
|
|
order per subnet and pool. 0.2.0 is in testing (0.2.0-rc.2):
|
|
allow and deny lists per subnet, every option of a DHCP message in
|
|
words in the activity log, and failed logins logged for Guard and
|
|
fail2ban.
|
|
|
|
## Licence
|
|
|
|
MIT, see [LICENSE](LICENSE).
|