release / release (push) Failing after 17s
For Guard's steward preset and fail2ban: msg="login failed" ip=... user=... and msg="token refused" ip=..., beside the audit records. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
93 lines
3.6 KiB
Markdown
93 lines
3.6 KiB
Markdown
# 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.
|
|
|
|
## Failed logins in the journal
|
|
|
|
A failed login to the web UI or the API, and a refused API token, are
|
|
written to the journal as well as the audit log, with the address first:
|
|
|
|
```
|
|
level=WARN msg="login failed" ip=203.0.113.9 user=admin reason="wrong username or password"
|
|
level=WARN msg="token refused" ip=203.0.113.9 reason="wrong token secret"
|
|
```
|
|
|
|
Guard's `steward` preset, or a fail2ban filter, can ban such addresses at
|
|
the firewall (with Housecarl's ban lists). The address comes before the
|
|
user name, which a caller chooses, so a pattern anchored on
|
|
`msg="login failed" ip=` can't be fooled by a name. With `log.format:
|
|
json` they are JSON objects with the same fields in the same order.
|
|
|
|
## 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)).
|