feat(firewall): auto-detect which iptables

- On `iptables` error, try to use `iptables-nft`
- On `ip6tables` error, try to use `ip6tables-nft`
This commit is contained in:
Quentin McGaw
2022-02-26 22:55:22 +00:00
parent 2b09b9c290
commit 006b218ade
4 changed files with 79 additions and 27 deletions

View File

@@ -10,16 +10,27 @@ import (
"github.com/qdm12/golibs/command"
)
var (
ErrIP6NotSupported = errors.New("ip6tables not supported")
)
// findIP6tablesSupported checks for multiple iptables implementations
// and returns the iptables path that is supported. If none work, an
// empty string path is returned.
func findIP6tablesSupported(ctx context.Context, runner command.Runner) (
ip6tablesPath string) {
binsToTry := []string{"ip6tables", "ip6tables-nft"}
func ip6tablesSupported(ctx context.Context, runner command.Runner) (supported bool) {
cmd := exec.CommandContext(ctx, "ip6tables", "-L")
if _, err := runner.Run(cmd); err != nil {
return false
var err error
for _, ip6tablesPath = range binsToTry {
cmd := exec.CommandContext(ctx, ip6tablesPath, "-L")
_, err = runner.Run(cmd)
if err == nil {
break
}
}
return true
if err != nil {
return ""
}
return ip6tablesPath
}
func (c *Config) runIP6tablesInstructions(ctx context.Context, instructions []string) error {
@@ -32,18 +43,19 @@ func (c *Config) runIP6tablesInstructions(ctx context.Context, instructions []st
}
func (c *Config) runIP6tablesInstruction(ctx context.Context, instruction string) error {
if !c.ip6Tables {
if c.ip6Tables == "" {
return nil
}
c.ip6tablesMutex.Lock() // only one ip6tables command at once
defer c.ip6tablesMutex.Unlock()
c.logger.Debug("ip6tables " + instruction)
c.logger.Debug(c.ip6Tables + " " + instruction)
flags := strings.Fields(instruction)
cmd := exec.CommandContext(ctx, "ip6tables", flags...)
cmd := exec.CommandContext(ctx, c.ip6Tables, flags...) // #nosec G204
if output, err := c.runner.Run(cmd); err != nil {
return fmt.Errorf("command failed: \"ip6tables %s\": %s: %w", instruction, output, err)
return fmt.Errorf("command failed: \"%s %s\": %s: %w",
c.ip6Tables, instruction, output, err)
}
return nil
}