Merge pull request 'The hub relays the mesh passing through it (hq issue 196)' (#209) from jschoubben/the-hub-relays-the-mesh into main
This commit was merged in pull request #209.
This commit is contained in:
@@ -444,6 +444,18 @@ func AsNftables(rules []Rule, mesh []string, outward bool, foundation []int,
|
|||||||
b.WriteString("\t\t# this machine's own guests reaching outward: not a port opened to anybody\n")
|
b.WriteString("\t\t# this machine's own guests reaching outward: not a port opened to anybody\n")
|
||||||
b.WriteString(fmt.Sprintf("\t\tiifname != { %s } accept\n", inward))
|
b.WriteString(fmt.Sprintf("\t\tiifname != { %s } accept\n", inward))
|
||||||
}
|
}
|
||||||
|
// **The mesh passing through, not arriving.** A machine the mesh routes through — the hub, for
|
||||||
|
// every path between machines that are not co-located (novox/hq ADR 0007) — relays a packet that
|
||||||
|
// came in on the tunnel and leaves on it again, addressed to another machine of the mesh. That is
|
||||||
|
// no port of this machine's: the machine it is for filters it against its own rules. Without
|
||||||
|
// this, the chain below judged a relayed packet by this machine's own published ports, so two
|
||||||
|
// machines behind the hub reached each other only on ports the hub happened to publish for itself
|
||||||
|
// (novox/hq issue 196). In and out on the tunnel both: a packet off the tunnel for this machine's
|
||||||
|
// own containers leaves by a bridge, and still meets the rules below.
|
||||||
|
if tunnel != "" {
|
||||||
|
b.WriteString("\t\t# the mesh passing through to another of its machines, which filters it itself\n")
|
||||||
|
b.WriteString(fmt.Sprintf("\t\tiifname %q oifname %q accept\n", tunnel, tunnel))
|
||||||
|
}
|
||||||
|
|
||||||
if len(rules) > 0 {
|
if len(rules) > 0 {
|
||||||
b.WriteString("\n")
|
b.WriteString("\n")
|
||||||
|
|||||||
@@ -887,3 +887,34 @@ func TestAPublicPortNeedsNoGuestLine(t *testing.T) {
|
|||||||
t.Fatalf("a public port was given a guest line it does not need:\n%s", nft)
|
t.Fatalf("a public port was given a guest line it does not need:\n%s", nft)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// **The hub relays the mesh** (novox/hq ADR 0007, issue 196). Two machines that are not co-located
|
||||||
|
// reach each other through the hub, so the hub forwards a packet that arrives on the tunnel and
|
||||||
|
// leaves on it. The forward chain judged that packet by the hub's own published ports, and two
|
||||||
|
// machines behind the hub reached each other only on the ports the hub happened to publish.
|
||||||
|
//
|
||||||
|
// Measured: from one home machine to another through the hub, 17 of 55 ports answered, and they
|
||||||
|
// were exactly the hub's own; the SYN for the rest never left the hub.
|
||||||
|
func TestTheMeshPassingThroughIsRelayedNotJudgedAsThisMachines(t *testing.T) {
|
||||||
|
nft := AsNftables(nil, []string{"10.42.0.1", "10.42.0.2"}, false, nil, []string{"eth0"}, "mesh0")
|
||||||
|
relay := `iifname "mesh0" oifname "mesh0" accept`
|
||||||
|
if !strings.Contains(chainBody(t, nft, "forward"), relay) {
|
||||||
|
t.Errorf("the forward chain does not relay the mesh through this machine:\n%s", chainBody(t, nft, "forward"))
|
||||||
|
}
|
||||||
|
// Relaying is not receiving: nothing in the input chain opens because of it.
|
||||||
|
if strings.Contains(chainBody(t, nft, "input"), "oifname") {
|
||||||
|
t.Errorf("the input chain names an outgoing interface, which no packet for this machine has:\n%s",
|
||||||
|
chainBody(t, nft, "input"))
|
||||||
|
}
|
||||||
|
// And off the tunnel into this machine's own containers is still judged: the tunnel is not
|
||||||
|
// accepted wholesale, only in and out on it.
|
||||||
|
if strings.Contains(chainBody(t, nft, "forward"), `iifname "mesh0" accept`) {
|
||||||
|
t.Errorf("the forward chain accepts everything off the tunnel:\n%s", chainBody(t, nft, "forward"))
|
||||||
|
}
|
||||||
|
|
||||||
|
// A machine with no tunnel relays nothing, and names no interface it does not have.
|
||||||
|
alone := AsNftables(nil, nil, false, nil, []string{"eth0"}, "")
|
||||||
|
if strings.Contains(alone, "oifname") {
|
||||||
|
t.Errorf("a machine with no tunnel was given a relay rule:\n%s", alone)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user