Watch
0
0
Fork
You've already forked hyperhive
0

egress anti-spoof: renewals from the leased address pass, a stale lease delete is skipped

This commit is contained in:
atlas 2026-11-14 20:55:07 +01:00 • committed by mara
commit 1cef99e992

View file

@ -810,10 +810,11 @@ source check lives in that table and the host-side filtering stays in
`inet hive_egress`.
- **What a port may send.** The frame's MAC is the one bound to the port.
Then, by protocol: IPv4 from an address leased to that MAC, or DHCP from
`0.0.0.0` to `255.255.255.255`; ARP whose sender is the port's MAC and an
address leased to it, or an ARP probe from `0.0.0.0`; IPv6 from a link-local
address (and from `::` in neighbour solicitations and listener reports, which
Then, by protocol: IPv4 from an address leased to that MAC, or a DHCP client
message (UDP 68 to 67) to `255.255.255.255` or the bridge address, from any
source address, as long as its `chaddr` is the port's MAC; ARP whose sender is the
port's MAC and an address leased to it, or an ARP probe from `0.0.0.0`; IPv6
from a link-local address (and from `::` in neighbour solicitations and listener reports, which
precede an address). A message to UDP port 67 must carry the port's own MAC as
its `chaddr`, so a container can't lease, renew or release an address for
another. The table refuses a VLAN tag, and everything else counts as a spoof.
@ -841,6 +842,18 @@ source check lives in that table and the host-side filtering stays in
dnsmasq run it on every renewal too, which loads the pair again with the
new remaining time; without it a pair would leave the table when the first
lease ended, while dnsmasq kept renewing the lease.
A client whose pair has left the set can still renew or rebind: the DHCP
client message passes from the leased address too, and dnsmasq's reply puts
the pair back.
dnsmasq counts lease time on the wall clock, and the pair's timeout and the
container's own lease count awake time. After a suspend dnsmasq expires every
lease at once and runs `egress-lease del` for each; a `del` whose
`DNSMASQ_LEASE_EXPIRES` lies in the past does nothing, and the pair leaves the
table at its own timeout, as the container's lease ends. A `del` for a lease
that hasn't expired (a release) deletes the pair at once, as does one without
a readable expiry. `egress-lease` logs each `add`, `old` and `del` to dnsmasq's
log with the prefix `egress-lease:`, the MAC, address, port, expiry, and for
`del` whether it was `applied` or `skipped (stale)`.
- **The window.** The binding takes the MAC the container's link has when the
command first looks, normally within a second of the veth appearing. Until
then root in the container could change its own MAC, but in that time only
@ -870,7 +883,9 @@ source check lives in that table and the host-side filtering stays in
A binding that failed shows as `hive-egress-pin` errors in the journal and
`IN=` lines for that port.
- **What it doesn't cover.** A container can still send from any IPv6
link-local address and answer DHCP as a server on its own leased address.
link-local address and answer DHCP as a server on its own leased address. A
DHCP client message to the broadcast or bridge address carries any IPv4 source
address; the table looks only at its `chaddr`.
Enforcement comes with later changes in the same series: the log only shows
what such a change would cut.