The host says what filters the machine, with owners, and keeps the found firewall retired on every converged apply (hq ADR 0168)
Every table and chain that refuses traffic is reported with whose it is: the mesh's, the found firewall's, the container runtime's own, a ban, or other — the runtime's user chain is other, which is where both predecessors kept their rules, in the legacy filter on one machine and invisible to the mesh. Adoption's threshold does not move; a converged machine's report grows by its filters and its found firewall's state. Convergence is a state the host keeps: a found firewall enabled again is retired again and said; a reconcile that finds it inactive records that it was found so, never that the mesh did it; a step skipped after a failed apply is said. A retirement the mesh began and did not finish is finished. Fixtures are rulesets captured from three machines of the first mesh.
This commit is contained in:
+41
-12
@@ -54,20 +54,43 @@ func foundFirewall(ctx context.Context, d *declaration.Declaration, known *store
|
||||
return kind, nil
|
||||
}
|
||||
|
||||
// retireFirewall disables the found firewall once a converged declaration has applied cleanly,
|
||||
// which is when the mesh's derived filter has taken its place. Disabled, never flushed: its
|
||||
// configuration stays on disk for a return to adopted, and the container runtime's rules are not
|
||||
// its to take.
|
||||
// retireFirewall keeps the found firewall retired on a converged machine (novox/hq ADR 0100, ADR
|
||||
// 0168): disabled, never flushed, its configuration left on disk for a return to adopted, and the
|
||||
// container runtime's rules not its to take.
|
||||
//
|
||||
// **Convergence is a state the host keeps, not a step it takes once.** Every converged apply reads
|
||||
// whether the front end is in force; enabled again by a package, a boot or a hand, it is retired
|
||||
// again and said. The record says how it came to be inactive — the mesh disabled it, or a reconcile
|
||||
// found it so — and the two are never confused: a flip that did not take, followed by a hand that
|
||||
// did, used to be recorded as the mesh's doing (issue 143).
|
||||
//
|
||||
// Only a declaration from the mesh converges a node. A carried bundle never says a node is adopted
|
||||
// — it cannot — so its silence is not the controller's word that the node was converged, and an
|
||||
// adopted node re-applying its bundle keeps the firewall it was found with.
|
||||
//
|
||||
// Returned is what this apply did about the found firewall, for the report; empty when the machine
|
||||
// has none or is not converged.
|
||||
func retireFirewall(ctx context.Context, d *declaration.Declaration, origin string, known *store.State,
|
||||
run Runner, log func(string)) error {
|
||||
run Runner, log func(string)) (string, error) {
|
||||
rec := known.Firewall
|
||||
if origin != store.OriginDeclared || d.Adoption != nil || rec == nil || rec.Kind != string(firewall.UFW) || !rec.WasActive ||
|
||||
rec.DisabledByMesh {
|
||||
return nil
|
||||
if origin != store.OriginDeclared || d.Adoption != nil || rec == nil || rec.Kind != string(firewall.UFW) || !rec.WasActive {
|
||||
return "", nil
|
||||
}
|
||||
active := firewall.Active(ctx, run)
|
||||
if !active && !(rec.Forward != nil && !rec.DisabledByMesh) {
|
||||
// Inactive, and either the mesh's doing already or nobody's recorded here: said as found,
|
||||
// never as done (issue 143's second fault). A retirement the mesh began and did not finish —
|
||||
// the forward policy recorded, ufw down, the restore failed — is the one inactive state that
|
||||
// is still the mesh's to complete, below.
|
||||
if rec.RetiredBy == "" {
|
||||
if rec.DisabledByMesh {
|
||||
rec.RetiredBy = firewall.RetiredByMesh
|
||||
} else {
|
||||
rec.RetiredBy = firewall.RetiredFoundSo
|
||||
log(" ufw is inactive on this converged node, and not by the mesh; recorded as found so")
|
||||
}
|
||||
}
|
||||
return "", nil
|
||||
}
|
||||
// **Nothing is retired until what replaces it is in force** (novox/hq ADR 0100). The flip
|
||||
// loads the mesh's derived filter in ufw's place; disabling ufw before that table is actually
|
||||
@@ -75,10 +98,10 @@ func retireFirewall(ctx context.Context, d *declaration.Declaration, origin stri
|
||||
// no filter at all.
|
||||
loaded, err := firewall.MeshTableLoaded(ctx, run)
|
||||
if err != nil {
|
||||
return err
|
||||
return "", err
|
||||
}
|
||||
if !loaded {
|
||||
return fmt.Errorf("this node is converged and the mesh's own filter (table %s) is not loaded on "+
|
||||
return "", fmt.Errorf("this node is converged and the mesh's own filter (table %s) is not loaded on "+
|
||||
"this machine, so ufw was left in force: retiring it would leave the machine filtering "+
|
||||
"nothing. Assign a filter module to this node, or return it to adopted", firewall.MeshTable)
|
||||
}
|
||||
@@ -88,11 +111,17 @@ func retireFirewall(ctx context.Context, d *declaration.Declaration, origin stri
|
||||
rec.Forward = firewall.ForwardPolicies(ctx, run)
|
||||
}
|
||||
if err := firewall.Disable(ctx, run, rec.Forward); err != nil {
|
||||
return err
|
||||
return "", err
|
||||
}
|
||||
again := rec.DisabledByMesh || rec.RetiredBy != ""
|
||||
rec.DisabledByMesh = true
|
||||
rec.RetiredBy = firewall.RetiredByMesh
|
||||
if again {
|
||||
log(" disabled ufw again: it had been enabled since the mesh retired it; this node is converged and filtered by the mesh")
|
||||
return "disabled again: ufw had been enabled since the mesh retired it", nil
|
||||
}
|
||||
log(" disabled ufw: this node is converged and filtered by the mesh; ufw's configuration is left on disk")
|
||||
return nil
|
||||
return "disabled: this node is converged and filtered by the mesh; ufw's configuration is left on disk", nil
|
||||
}
|
||||
|
||||
// applyOpening makes one opening true through the firewall found here.
|
||||
|
||||
Reference in New Issue
Block a user