Put back the forward policy ufw disable opens when the found firewall is retired, as measured on a lab machine (hq ADR 0100)
This commit is contained in:
@@ -114,6 +114,41 @@ type fakeUFW struct {
|
||||
ruleset string
|
||||
firewalld bool
|
||||
asked []string
|
||||
|
||||
// iptablesActive and iptablesInactive are what `iptables -S` prints with ufw active and
|
||||
// after it is disabled; empty is a machine without iptables. forward is a policy set since.
|
||||
iptablesActive, iptablesInactive string
|
||||
forward 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.iptablesActive == "" {
|
||||
return "", &exec.Error{Name: name, Err: exec.ErrNotFound}
|
||||
}
|
||||
if name == "ip6tables" {
|
||||
return "", &exec.Error{Name: name, Err: exec.ErrNotFound}
|
||||
}
|
||||
if len(args) == 3 && args[0] == "-P" && args[1] == "FORWARD" {
|
||||
f.forward = args[2]
|
||||
return "", nil
|
||||
}
|
||||
captured := f.iptablesInactive
|
||||
if f.active {
|
||||
captured = f.iptablesActive
|
||||
}
|
||||
var out []string
|
||||
for _, line := range strings.Split(captured, "\n") {
|
||||
fields := strings.Fields(line)
|
||||
if len(fields) >= 2 && fields[1] == "FORWARD" {
|
||||
if fields[0] == "-P" && f.forward != "" && !f.active {
|
||||
line = "-P FORWARD " + f.forward
|
||||
}
|
||||
out = append(out, line)
|
||||
}
|
||||
}
|
||||
return strings.Join(out, "\n") + "\n", nil
|
||||
}
|
||||
|
||||
func canonical(args []string) string {
|
||||
@@ -155,6 +190,8 @@ func (f *fakeUFW) run(_ context.Context, name string, args ...string) (string, e
|
||||
return f.ruleset, nil
|
||||
case "iptables-legacy", "ip6tables-legacy":
|
||||
return "", &exec.Error{Name: name, Err: exec.ErrNotFound}
|
||||
case "iptables", "ip6tables":
|
||||
return f.iptables(name, args)
|
||||
case "ufw":
|
||||
default:
|
||||
return "", fmt.Errorf("unexpected %s", name)
|
||||
@@ -179,6 +216,7 @@ func (f *fakeUFW) run(_ context.Context, name string, args ...string) (string, e
|
||||
return "Firewall is active and enabled on system startup\n", nil
|
||||
case args[0] == "disable":
|
||||
f.active = false
|
||||
f.forward = ""
|
||||
return "Firewall stopped and disabled on system startup\n", nil
|
||||
case args[0] == "delete" && len(args) > 1 && args[1] == "route":
|
||||
// As the real ufw answers it (captured in testdata/ufw-delete.txt): a route rule is
|
||||
@@ -424,3 +462,41 @@ func TestARealUfwRulesetIsUfw(t *testing.T) {
|
||||
t.Error("ufw's drop chains, with ufw not known to be active, read as refusing nothing")
|
||||
}
|
||||
}
|
||||
|
||||
func TestRetiringUfwKeepsTheMachineFromRoutingForOthers(t *testing.T) {
|
||||
// Captured on a lab machine running the container runtime with a published port: ufw active,
|
||||
// then `ufw disable`. Disabling set the forward policy the runtime had set to drop to accept.
|
||||
before, err := os.ReadFile("testdata/ufw-disable-iptables-before.txt")
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
after, err := os.ReadFile("testdata/ufw-disable-iptables-after.txt")
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if !strings.Contains(string(before), "-P FORWARD DROP") || !strings.Contains(string(after), "-P FORWARD ACCEPT") {
|
||||
t.Fatal("the captures no longer show ufw disable opening the forward policy")
|
||||
}
|
||||
f := &fakeUFW{installed: true, active: true, iptablesActive: string(before), iptablesInactive: string(after)}
|
||||
if err := Disable(context.Background(), f.run); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if f.active {
|
||||
t.Fatal("ufw is still active")
|
||||
}
|
||||
if f.forward != "DROP" {
|
||||
t.Errorf("the forward policy was left open after ufw was retired: %v", f.asked)
|
||||
}
|
||||
for _, a := range f.asked {
|
||||
if strings.Contains(a, "-F") || strings.Contains(a, "flush") || strings.Contains(a, "reset") {
|
||||
t.Errorf("retiring ufw flushed something: %s", a)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestRetiringUfwOnAMachineWithoutIptablesStillRetiresIt(t *testing.T) {
|
||||
f := &fakeUFW{installed: true, active: true}
|
||||
if err := Disable(context.Background(), f.run); err != nil || f.active {
|
||||
t.Fatalf("disable: %v, active %v", err, f.active)
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user