The firewall opens the port the mesh itself runs on
Rules are derived from what modules declare they listen on, and the substrate is not a module. So the broker's port — the one every machine dials to enrol and to receive every declaration it is ever sent — appeared in no ruleset the mesh has ever generated. Nothing caught it because a mesh of one never dials its own broker across the network: the ruleset looks complete right up until a second machine tries to join a firewalled anchor and is refused by the packet filter, during enrolment, before the mesh can report anything about it. Assigning the firewall before joining machines is both the natural order and the one that breaks. It is a floor for the same reason ssh is. A machine nobody can reach cannot be repaired; a machine the mesh cannot reach cannot be managed. Neither is a thing any module asks for and neither may be derived away. From anywhere rather than from the private network, deliberately: a node enrols BEFORE it has an address on that network, so narrowing the rule to it would close the door being knocked on. The port is read from the broker this control plane was told about, so the address handed out in a token and the port a machine must accept on stay one fact. A mesh never told about a broker gets no such rule, rather than a broken one — and cannot issue tokens either, which is where that surfaces. Closes novox/hq 04-ISSUES/052. Claude-Session: https://claude.ai/code/session_01D6qtiYU3P9jk3pnAXyAFyx
This commit is contained in:
@@ -9,9 +9,12 @@ import (
|
||||
"sort"
|
||||
"strings"
|
||||
|
||||
"github.com/novox/mesh-control/internal/broker"
|
||||
"github.com/novox/mesh-control/internal/catalogue"
|
||||
"github.com/novox/mesh-control/internal/inventory"
|
||||
"github.com/novox/mesh-control/internal/licences"
|
||||
"net"
|
||||
"strconv"
|
||||
)
|
||||
|
||||
// working out what one machine should be.
|
||||
@@ -447,9 +450,22 @@ func declarationWith(ctx context.Context, open *stores, node string,
|
||||
names[name] = at
|
||||
}
|
||||
|
||||
// The ports the mesh itself needs open, which no module declares. Read from the broker this
|
||||
// control plane was told about rather than written down twice: the address a node is handed in
|
||||
// its token and the port its machine must accept on are the same fact.
|
||||
var substrate []int
|
||||
if b, err := broker.FromEnvironment(); err == nil {
|
||||
if _, port, err := net.SplitHostPort(b.Address); err == nil {
|
||||
if n, err := strconv.Atoi(port); err == nil {
|
||||
substrate = append(substrate, n)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return plan.Declaration(catalogue.Rendering{
|
||||
Settings: settings, Generators: gens, Grants: grants, Needed: needed, Ports: ports,
|
||||
Certificate: certificate, Authority: authority, Mesh: private, Names: names})
|
||||
Certificate: certificate, Authority: authority, Mesh: private, Names: names,
|
||||
Substrate: substrate})
|
||||
}
|
||||
|
||||
// routeNamesInTheMesh is every routed name and the address of the node that serves it (novox/hq
|
||||
|
||||
Reference in New Issue
Block a user