The filter constrains what arrives from outside, and names no network
The forward chain blocked everything passing through the machine and then allowed the machine's own containers back by naming their address ranges: 172.16.0.0/12 and 192.168.128.0/17 fixed here, the rest recorded per machine by 0043. Every way of keeping that list correct fails — a constant describes one machine, a recorded range goes stale in silence and cannot tell a network the mesh made from one a predecessor left behind, and generating it from the modules would put half the rule set on the machine. The mesh has no position on a container reaching outward: that is not a port opened to anybody. So both chains are written around the links traffic arrives on. What did not arrive from outside is accepted in one line; what did meets the declared rules. The tunnel is named beside the outward links rather than treated as inside, or a port nothing declares would be reachable from every machine in the mesh. A machine that has not reported an outward link is sent no filter and keeps the one it has, refused where a person reads it rather than as a rule set that will not load. Removes the two constants, `node networks`, and the column behind it. novox/hq ADR 0140, superseding 0137 and 0139.
This commit is contained in:
+25
-34
@@ -9,7 +9,6 @@ import (
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"fmt"
|
||||
"net"
|
||||
"sort"
|
||||
"strings"
|
||||
"time"
|
||||
@@ -519,37 +518,28 @@ func (i *Inventory) PublicDomainOf(ctx context.Context, name string) (string, er
|
||||
return *domain, nil
|
||||
}
|
||||
|
||||
// SetRoutedNetworks records the networks this machine routes for what it hosts, beyond the
|
||||
// container runtime's own default pools.
|
||||
// RecordOutwardLinks keeps the links a machine reported as facing outside it.
|
||||
//
|
||||
// A node-level fact (novox/hq ADR 0137), beside the node's public domain: the machine routes them,
|
||||
// not whichever module loads the filter, so swapping that module must not lose them. Added to the
|
||||
// runtime's defaults rather than replacing them, so a machine that says one range does not lose the
|
||||
// ranges its containers were already using. An empty list clears it.
|
||||
// A reported fact, not a setting (novox/hq ADR 0140). It replaces the networks a machine used to be
|
||||
// told to say it routes: the filter blocked everything passing through and then allowed the machine's
|
||||
// own containers back by naming their address ranges, and every way of keeping that list correct
|
||||
// failed — a constant describes one machine, and a recorded range goes stale in silence. The filter
|
||||
// now constrains what arrives from outside and says nothing about what did not, and the one thing it
|
||||
// needs is which links "outside" arrives on. The machine reads that from its own routing table on
|
||||
// every apply, so it cannot go stale and nobody types it.
|
||||
//
|
||||
// Each entry is checked as a CIDR here rather than at render time: an address that does not parse
|
||||
// becomes a line nftables refuses, and a refused ruleset is a machine that filters nothing while
|
||||
// its service reports a configuration fault.
|
||||
func (i *Inventory) SetRoutedNetworks(ctx context.Context, name string, networks []string) error {
|
||||
node, err := i.NodeByName(ctx, name)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
// An empty list clears it, which is what a machine with no route off itself reports. The mesh then
|
||||
// composes no filter for that machine at all.
|
||||
func (i *Inventory) RecordOutwardLinks(ctx context.Context, id string, links []string) error {
|
||||
var kept []string
|
||||
for _, n := range networks {
|
||||
n = strings.TrimSpace(n)
|
||||
if n == "" {
|
||||
continue
|
||||
for _, name := range links {
|
||||
if name = strings.TrimSpace(name); name != "" {
|
||||
kept = append(kept, name)
|
||||
}
|
||||
if _, _, err := net.ParseCIDR(n); err != nil {
|
||||
return fmt.Errorf("%q is not a network in CIDR form (10.0.0.0/8, 192.168.0.0/16): %w",
|
||||
n, err)
|
||||
}
|
||||
kept = append(kept, n)
|
||||
}
|
||||
if len(kept) == 0 {
|
||||
_, err = i.store.Pool().Exec(ctx,
|
||||
`update node set routed_networks = null where id = $1`, node.ID)
|
||||
_, err := i.store.Pool().Exec(ctx,
|
||||
`update node set outward_links = null where id = $1`, id)
|
||||
return err
|
||||
}
|
||||
body, err := json.Marshal(kept)
|
||||
@@ -557,15 +547,16 @@ func (i *Inventory) SetRoutedNetworks(ctx context.Context, name string, networks
|
||||
return err
|
||||
}
|
||||
_, err = i.store.Pool().Exec(ctx,
|
||||
`update node set routed_networks = $2 where id = $1`, node.ID, string(body))
|
||||
`update node set outward_links = $2 where id = $1`, id, string(body))
|
||||
return err
|
||||
}
|
||||
|
||||
// RoutedNetworksOf is the networks a machine routes for what it hosts, empty when it has named none.
|
||||
func (i *Inventory) RoutedNetworksOf(ctx context.Context, name string) ([]string, error) {
|
||||
// OutwardLinksOf is the links a machine reported as facing outside it, empty when it has reported
|
||||
// none — which is a machine the mesh composes no filter for.
|
||||
func (i *Inventory) OutwardLinksOf(ctx context.Context, name string) ([]string, error) {
|
||||
var body []byte
|
||||
err := i.store.Pool().QueryRow(ctx,
|
||||
`select routed_networks from node where name = $1`, name).Scan(&body)
|
||||
`select outward_links from node where name = $1`, name).Scan(&body)
|
||||
if errors.Is(err, pgx.ErrNoRows) {
|
||||
return nil, fmt.Errorf("%w: %s", ErrNoSuchNode, name)
|
||||
}
|
||||
@@ -575,11 +566,11 @@ func (i *Inventory) RoutedNetworksOf(ctx context.Context, name string) ([]string
|
||||
if len(body) == 0 {
|
||||
return nil, nil
|
||||
}
|
||||
var networks []string
|
||||
if err := json.Unmarshal(body, &networks); err != nil {
|
||||
return nil, fmt.Errorf("the networks recorded for %s are not a list: %w", name, err)
|
||||
var links []string
|
||||
if err := json.Unmarshal(body, &links); err != nil {
|
||||
return nil, fmt.Errorf("the outward links recorded for %s are not a list: %w", name, err)
|
||||
}
|
||||
return networks, nil
|
||||
return links, nil
|
||||
}
|
||||
|
||||
// RecordOverlayKey keeps the public half a node generated.
|
||||
|
||||
Reference in New Issue
Block a user