release / release (push) Successful in 5m53s
- A disabled reservation is kept but ignored: the client gets a pool address like any other (steward reservation disable|enable, buttons and a checkbox in the web UI). Schema migration 3. - Subnets get Disable/Enable buttons on their page and in the list. - A rule left without its selector in style.css broke the page heading's layout, so the New ... buttons sat cramped under the description. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
165 lines
7.1 KiB
Markdown
165 lines
7.1 KiB
Markdown
# Subnets, pools, reservations and leases
|
|
|
|
## Subnets and interfaces
|
|
|
|
A subnet is an IPv4 network Steward hands addresses out in, served on
|
|
one network interface:
|
|
|
|
```sh
|
|
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
|
|
```
|
|
|
|
**The interface decides.** stewardd opens one socket on port 67 per
|
|
interface that has a subnet, bound to that interface. A request is
|
|
answered only from the subnets of the interface it came in on. A client on
|
|
`eth0.20` never gets an `eth0` address, even if it asks for one. It gets a
|
|
NAK, then an address of its own VLAN.
|
|
|
|
For VLANs, give the server an interface on each, such as `eth0.20`, or a
|
|
bridge such as `br-iot`, each with an address in its subnet. That address
|
|
is the server identifier clients see, and the one they renew their lease
|
|
with. `steward interface list` shows the server's interfaces with their
|
|
addresses and subnets.
|
|
|
|
An interface that doesn't exist yet is fine. The subnet gets a warning
|
|
(`interface_unknown`), and stewardd starts serving it within 30 seconds of
|
|
the interface appearing. `steward status` and the dashboard show each
|
|
interface's state; when one isn't served, they say why.
|
|
|
|
**Several subnets on one interface** form a shared network: two networks
|
|
on the same wire, the server with an address in each. Addresses come from
|
|
the first subnet's pools, then the next. Clients of every subnet are
|
|
answered from the interface's address in their own subnet, or its first
|
|
address.
|
|
|
|
A subnet can be **disabled**: its configuration and leases stay, but its
|
|
clients get no answers (`steward subnet disable NAME`, or Disable in the
|
|
web UI).
|
|
|
|
## Pools
|
|
|
|
Pools are the ranges handed out to any client: `FIRST-LAST`, or a prefix,
|
|
`10.0.10.128/25`. A subnet may have several pools, or none if only clients
|
|
with a reservation should get addresses. Pools must be inside the subnet,
|
|
must not overlap, and can't include the network or broadcast address.
|
|
|
|
Pool sizes are shown as the addresses that can really be handed out.
|
|
Reserved addresses inside a pool don't count, since nobody else gets them.
|
|
|
|
## Reservations
|
|
|
|
A reservation fixes a client's address:
|
|
|
|
```sh
|
|
steward reservation add 10.0.10.20 aa:bb:cc:dd:ee:01 --hostname nas
|
|
steward lease reserve 10.0.10.57 # the address a client has now
|
|
```
|
|
|
|
* **The client** is known by its MAC address, or by its client identifier
|
|
(option 61) when the reservation has one (`--client-id`; give `-` as the
|
|
MAC). Some devices change their identifier but not their MAC address,
|
|
and others the other way round. When unsure, use the MAC address.
|
|
* **The address picks the subnet**: the subnet whose network holds it. It
|
|
may be inside a pool or outside one; either way, nobody else gets it.
|
|
* **The host name** is sent to the client (option 12).
|
|
* **Options** set on the reservation are for that client only, and win
|
|
over the subnet's and the settings'.
|
|
* **A device on two VLANs** can have a reservation in each subnet. Within
|
|
one subnet, a client has at most one.
|
|
|
|
A reservation can be **disabled** (`steward reservation disable RES`, or
|
|
Disable in the web UI). It is kept but ignored: the client gets a pool
|
|
address like any other, and the reserved address, if it is inside a pool,
|
|
may go to someone else. The client keeps the address it has until its
|
|
lease runs out. While it is disabled, another reservation may use its
|
|
address or client; enabling it again is then refused until one of them
|
|
moves.
|
|
|
|
A client with a reservation always gets that address, not a pool address.
|
|
If it asks for another one, for example after the reservation was added,
|
|
it gets a NAK that names its reserved address, and then the reservation.
|
|
|
|
## Options
|
|
|
|
Options are set at three levels. A reservation's win over its subnet's,
|
|
and a subnet's over the settings' (the options every subnet gets):
|
|
|
|
```sh
|
|
steward settings set --option domain-name-servers=10.0.10.2 --option domain-name=lan
|
|
steward subnet update office --option routers=10.0.10.1 --option ntp-servers=10.0.10.2
|
|
steward reservation update nas --option domain-name-servers=1.1.1.1
|
|
```
|
|
|
|
`--option NAME=VALUE` sets one and keeps the others; `--unset-option NAME`
|
|
removes one. [options.md](options.md) lists the names, and how to write
|
|
each kind of value. Any other option can be set by number, with its type:
|
|
`--option 224:string=hello`.
|
|
|
|
Every reply carries the subnet mask, the server identifier and, for a
|
|
lease, the lease time and the times to renew (half of it) and rebind (7/8
|
|
of it). With a parameter request list (most clients send one), the client
|
|
gets the options it asked for, in its order. The subnet mask, routers, DNS
|
|
servers, domain name and host name are sent even if it didn't ask. Without
|
|
a list, it gets every option set for it.
|
|
|
|
## Lease times
|
|
|
|
The settings have the default (12 hours, `steward settings set
|
|
--lease-time 1d`); a subnet can have its own (`--lease-time 1h`). Clients
|
|
renew halfway through. Short times let changes reach clients sooner;
|
|
long ones keep clients working longer if Steward is down.
|
|
|
|
## How an address is chosen
|
|
|
|
For a DISCOVER, Steward offers, in this order:
|
|
|
|
1. the client's reservation in a subnet of the interface;
|
|
2. the address the client had before, from its last lease, even if that
|
|
ended, as long as it is still free and in a pool;
|
|
3. the address the client asks for (option 50), if it is free and in a
|
|
pool;
|
|
4. a free pool address: one never handed out before, else the one that has
|
|
been free the longest.
|
|
|
|
An address is free when no other client has an active lease on it, it
|
|
isn't held back, and it isn't offered to someone else in the last minute.
|
|
The server's own addresses are never offered. A fresh pool address is
|
|
pinged first: if something answers, it is held back and the next one is
|
|
tried.
|
|
|
|
When the client confirms with a REQUEST, the lease is saved, and only
|
|
then is the ACK sent.
|
|
|
|
## Leases
|
|
|
|
| State | Meaning |
|
|
|---|---|
|
|
| active | the client holds the address until the lease ends |
|
|
| expired | the lease ran out; the client gets the address back if it returns while it is free |
|
|
| released | the client gave the address back |
|
|
| held back | a client declined the address because another device answered for it, or it answered Steward's ping. It isn't handed out until the hold ends (a day; `--decline-hold`) |
|
|
|
|
`steward lease list` shows active and held-back leases; `--all` shows
|
|
the others too. Leases that ended more than 30 days ago are deleted.
|
|
|
|
`steward lease delete IP` frees an address at once. A client still using
|
|
it gets a NAK when it next renews, then asks for a new address.
|
|
|
|
## Authority
|
|
|
|
Steward is **authoritative** for its interfaces. A client that asks to
|
|
keep an address that doesn't belong on its interface, or that someone
|
|
else holds, gets a NAK and starts over at once, rather than keeping a
|
|
wrong address until its lease runs out. Turn this off (`steward settings
|
|
set --authoritative off`) only when another DHCP server serves the same
|
|
network. Requests for addresses Steward knows nothing about then get no
|
|
answer.
|
|
|
|
## Not in 0.1
|
|
|
|
Relayed requests (with `giaddr`) are ignored and logged once an hour: a
|
|
subnet must be on one of the server's own interfaces. DHCPv6, failover,
|
|
client classes and DNS names through Jarl are planned
|
|
([design.md](design.md)).
|