Delete a forwarded opening the way ufw accepts it, and read a fresh machine's resolver as not in use — both measured on a lab machine (hq ADR 0100)

This commit is contained in:
2026-09-22 17:37:01 +02:00
parent 5e3dd3f59c
commit 3e0e6e6b7e
9 changed files with 699 additions and 17 deletions
+9 -11
View File
@@ -10,13 +10,11 @@ import (
"github.com/novox/mesh-host/internal/store"
)
// quietUDP are processes whose UDP sockets every fresh machine has — name resolution, address
// configuration, time — and which serve nobody. ss names a process by its first fifteen characters,
// so both spellings are here.
//
// **Still to be measured** (novox/hq ADR 0100): this list is what a fresh machine is expected to
// hold, and it must be checked against a freshly installed lab machine before it is trusted.
var quietUDP = map[string]bool{
// quiet are the processes every fresh machine runs that serve nobody: name resolution (whose
// link-local resolver listens on TCP as well as UDP, on every address), address configuration and
// time. ss names a process by its first fifteen characters, so both spellings are here. Measured
// on a freshly installed lab machine (testdata/fresh-machine-listeners.txt): these and nothing else.
var quiet = map[string]bool{
"systemd-resolved": true, "systemd-resolve": true,
"systemd-networkd": true, "systemd-network": true,
"systemd-timesyncd": true, "systemd-timesyn": true,
@@ -24,8 +22,8 @@ var quietUDP = map[string]bool{
}
// InUse says what makes this machine a machine in use (novox/hq ADR 0100): every running container
// no host made, and every socket listening on an address other than loopback that is not ssh's — a
// UDP one only when it is held by something other than what every fresh machine runs. ours names
// no host made, and every socket listening on an address other than loopback that is neither ssh's
// nor held by what every fresh machine runs. ours names
// what the mesh itself runs, which a re-run of genesis finds and does not count.
func InUse(ctx context.Context, run Runner, ours func(name string) bool) ([]string, []reachable.Reach, error) {
var containers []string
@@ -61,9 +59,9 @@ func counts(r reachable.Reach) bool {
}
switch r.Protocol {
case "tcp":
return r.By != "sshd" && !(r.By == "" && r.Port == 22)
return r.By != "sshd" && !(r.By == "" && r.Port == 22) && !quiet[r.By]
case "udp":
return !quietUDP[r.By]
return !quiet[r.By]
}
return false
}
+25 -2
View File
@@ -2,6 +2,7 @@ package bootstrap
import (
"context"
"os"
"path/filepath"
"strings"
"testing"
@@ -13,8 +14,8 @@ import (
// and listener it counted.
// Lines as `ss -Hltunp` prints them. The ssh, samba, loopback and proxy lines are captured from a
// real machine; the resolver, DHCP and time lines are written in the same shape for the processes a
// fresh machine runs, and still need measuring against one.
// real machine; the resolver, DHCP and time lines are written in the same shape. What a fresh machine
// actually runs is measured in testdata/fresh-machine-listeners.txt.
const inUseSockets = `tcp LISTEN 0 128 0.0.0.0:22 0.0.0.0:* users:(("sshd",pid=1188536,fd=6))
tcp LISTEN 0 128 [::]:22 [::]:* users:(("sshd",pid=1188536,fd=7))
tcp LISTEN 0 32 127.0.0.1:53 0.0.0.0:* users:(("dnsmasq",pid=1189392,fd=7))
@@ -97,3 +98,25 @@ func TestARerunOfGenesisIsNotAMachineInUse(t *testing.T) {
t.Errorf("what an earlier genesis raised was counted as a machine in use: %v", err)
}
}
func TestAFreshlyInstalledMachineAsMeasuredIsNotInUse(t *testing.T) {
// Captured with `ss -Hltunp` on a freshly installed lab machine: its resolver listens on TCP on
// every address, which the record's words alone would count.
raw, err := os.ReadFile("testdata/fresh-machine-listeners.txt")
if err != nil {
t.Fatal(err)
}
run := func(ctx context.Context, name string, args ...string) (string, error) {
if name == "ss" {
return string(raw), nil
}
return "", nil
}
containers, listeners, err := InUse(context.Background(), run, func(string) bool { return false })
if err != nil {
t.Fatal(err)
}
if len(containers) != 0 || len(listeners) != 0 {
t.Errorf("a fresh machine read as in use: containers %v, listeners %v", containers, listeners)
}
}
+12
View File
@@ -0,0 +1,12 @@
udp UNCONN 0 0 0.0.0.0:5353 0.0.0.0:* users:(("systemd-resolve",pid=262,fd=17))
udp UNCONN 0 0 0.0.0.0:5355 0.0.0.0:* users:(("systemd-resolve",pid=262,fd=13))
udp UNCONN 0 0 127.0.0.54:53 0.0.0.0:* users:(("systemd-resolve",pid=262,fd=24))
udp UNCONN 0 0 127.0.0.53%lo:53 0.0.0.0:* users:(("systemd-resolve",pid=262,fd=22))
udp UNCONN 0 0 [::]:5353 [::]:* users:(("systemd-resolve",pid=262,fd=18))
udp UNCONN 0 0 [::]:5355 [::]:* users:(("systemd-resolve",pid=262,fd=15))
udp UNCONN 0 0 [fe80::1266:6aff:fe24:628d]%enp5s0:546 [::]:* users:(("systemd-network",pid=272,fd=36))
tcp LISTEN 0 4096 127.0.0.1:39473 0.0.0.0:* users:(("containerd",pid=394,fd=14))
tcp LISTEN 0 4096 0.0.0.0:5355 0.0.0.0:* users:(("systemd-resolve",pid=262,fd=14))
tcp LISTEN 0 4096 127.0.0.53%lo:53 0.0.0.0:* users:(("systemd-resolve",pid=262,fd=23))
tcp LISTEN 0 4096 127.0.0.54:53 0.0.0.0:* users:(("systemd-resolve",pid=262,fd=25))
tcp LISTEN 0 4096 [::]:5355 [::]:* users:(("systemd-resolve",pid=262,fd=16))