Record the forward policies before disabling ufw, so a retried retirement restores them (hq ADR 0100)
This commit is contained in:
@@ -806,40 +806,46 @@ func Enable(ctx context.Context, run Runner) error {
|
||||
// runtime had set that one to drop when it turned forwarding on, and it does not set it again while
|
||||
// forwarding stays on — not even on a restart. Left so, a retired ufw turns the machine into a
|
||||
// router for anyone who can reach it. So each family's forward policy is read before, and one that
|
||||
// was drop is put back and read back.
|
||||
func Disable(ctx context.Context, run Runner) error {
|
||||
type family struct{ tool, policy string }
|
||||
var before []family
|
||||
for _, tool := range []string{"iptables", "ip6tables"} {
|
||||
if policy, ok := forwardPolicy(ctx, run, tool); ok {
|
||||
before = append(before, family{tool, policy})
|
||||
}
|
||||
}
|
||||
// was drop is put back and read back. before is ForwardPolicies as read before the first attempt.
|
||||
func Disable(ctx context.Context, run Runner, before map[string]string) error {
|
||||
if _, err := run(ctx, "ufw", "disable"); err != nil {
|
||||
return fmt.Errorf("disabling ufw: %w", err)
|
||||
}
|
||||
if err := expectActive(ctx, run, false); err != nil {
|
||||
return err
|
||||
}
|
||||
for _, f := range before {
|
||||
if f.policy != "DROP" {
|
||||
for _, tool := range []string{"iptables", "ip6tables"} {
|
||||
if before[tool] != "DROP" {
|
||||
continue
|
||||
}
|
||||
if now, ok := forwardPolicy(ctx, run, f.tool); ok && now == "DROP" {
|
||||
if now, ok := forwardPolicy(ctx, run, tool); ok && now == "DROP" {
|
||||
continue
|
||||
}
|
||||
if _, err := run(ctx, f.tool, "-P", "FORWARD", "DROP"); err != nil {
|
||||
if _, err := run(ctx, tool, "-P", "FORWARD", "DROP"); err != nil {
|
||||
return fmt.Errorf("ufw is disabled, and %s's forward policy, which was drop, could not be put back: %w",
|
||||
f.tool, err)
|
||||
tool, err)
|
||||
}
|
||||
if now, ok := forwardPolicy(ctx, run, f.tool); !ok || now != "DROP" {
|
||||
if now, ok := forwardPolicy(ctx, run, tool); !ok || now != "DROP" {
|
||||
return fmt.Errorf("ufw is disabled, and %s's forward policy was put back to drop and reads %q",
|
||||
f.tool, now)
|
||||
tool, now)
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// ForwardPolicies reads each family's forward policy, by the tool that sets it. Read before ufw is
|
||||
// disabled and kept by the caller, so a retirement that fails half-way is retried with what the
|
||||
// machine had — not with what the half-done disable left.
|
||||
func ForwardPolicies(ctx context.Context, run Runner) map[string]string {
|
||||
out := map[string]string{}
|
||||
for _, tool := range []string{"iptables", "ip6tables"} {
|
||||
if policy, ok := forwardPolicy(ctx, run, tool); ok {
|
||||
out[tool] = policy
|
||||
}
|
||||
}
|
||||
return out
|
||||
}
|
||||
|
||||
// forwardPolicy reads the forward chain's policy the way iptables prints it: "-P FORWARD DROP".
|
||||
// Not ok when the tool is absent or says nothing readable.
|
||||
func forwardPolicy(ctx context.Context, run Runner, tool string) (string, bool) {
|
||||
|
||||
Reference in New Issue
Block a user