Read a machine's iptables rules when it has no nft, instead of calling it unfiltered (hq ADR 0100)
This commit is contained in:
@@ -119,11 +119,20 @@ type fakeUFW struct {
|
||||
// after it is disabled; empty is a machine without iptables. forward is a policy set since.
|
||||
iptablesActive, iptablesInactive string
|
||||
forward string
|
||||
// noNft is a machine with no nft binary; iptablesRules is what `iptables -S` prints there.
|
||||
noNft bool
|
||||
iptablesRules string
|
||||
}
|
||||
|
||||
// iptables answers `iptables -S FORWARD` from the captured output for ufw's state, and records
|
||||
// a forward policy set with -P.
|
||||
func (f *fakeUFW) iptables(name string, args []string) (string, error) {
|
||||
if f.iptablesRules != "" && len(args) == 1 && args[0] == "-S" {
|
||||
if name == "ip6tables" {
|
||||
return "", nil
|
||||
}
|
||||
return f.iptablesRules, nil
|
||||
}
|
||||
if f.iptablesActive == "" {
|
||||
return "", &exec.Error{Name: name, Err: exec.ErrNotFound}
|
||||
}
|
||||
@@ -189,6 +198,9 @@ func (f *fakeUFW) run(_ context.Context, name string, args ...string) (string, e
|
||||
}
|
||||
return "", &exec.Error{Name: name, Err: exec.ErrNotFound}
|
||||
case "nft":
|
||||
if f.noNft {
|
||||
return "", &exec.Error{Name: name, Err: exec.ErrNotFound}
|
||||
}
|
||||
return f.ruleset, nil
|
||||
case "iptables-legacy", "ip6tables-legacy":
|
||||
return "", &exec.Error{Name: name, Err: exec.ErrNotFound}
|
||||
@@ -756,3 +768,22 @@ func TestIncomingIsUfwsDefaultDirection(t *testing.T) {
|
||||
t.Error("an incoming refusal ufw would merge was not refused")
|
||||
}
|
||||
}
|
||||
|
||||
func TestAMachineWithIptablesRulesAndNoNftIsNotReadAsUnfiltered(t *testing.T) {
|
||||
// nft is not installed, and iptables-nft holds a firewall of somebody's. Read as "nothing
|
||||
// filters here" the mesh would adopt it, open nothing, and be unreachable (novox/hq ADR 0100).
|
||||
rules := "-P INPUT DROP\n-P FORWARD DROP\n-P OUTPUT ACCEPT\n-A INPUT -p tcp -m tcp --dport 22 -j ACCEPT\n"
|
||||
f := &fakeUFW{noNft: true, iptablesRules: rules}
|
||||
kind, what, err := Detect(context.Background(), f.run)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if kind != Unsupported {
|
||||
t.Errorf("a machine filtered by iptables with no nft read as %s (%s)", kind, what)
|
||||
}
|
||||
// And a machine with nothing but the runtime's own rules and no nft is still unfiltered.
|
||||
docker := "-P INPUT ACCEPT\n-P FORWARD DROP\n-P OUTPUT ACCEPT\n-N DOCKER\n-A DOCKER -i docker0 -j DROP\n"
|
||||
if kind, _, err := Detect(context.Background(), (&fakeUFW{noNft: true, iptablesRules: docker}).run); err != nil || kind != None {
|
||||
t.Errorf("a machine with only the runtime's rules read as %s: %v", kind, err)
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user