mirror of
https://github.com/tailscale/tailscale.git
synced 2024-11-29 04:55:31 +00:00
util/linuxfw: fall back to nftables when iptables not found
When the desired netfilter mode was unset, we would always try to use the `iptables` binary. In such cases if iptables was not found, tailscaled would just crash as seen in #13440. To work around this, in those cases check if the `iptables` binary even exists and if it doesn't fall back to the nftables implementation. Verified that it works on stock Ubuntu 24.04. Updates #5621 Updates #8555 Updates #8762 Fixes #13440 Signed-off-by: Maisem Ali <maisem@tailscale.com>
This commit is contained in:
parent
98f4dd9857
commit
4d6a8224d5
@ -6,6 +6,9 @@
|
|||||||
package linuxfw
|
package linuxfw
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"errors"
|
||||||
|
"os/exec"
|
||||||
|
|
||||||
"tailscale.com/envknob"
|
"tailscale.com/envknob"
|
||||||
"tailscale.com/hostinfo"
|
"tailscale.com/hostinfo"
|
||||||
"tailscale.com/types/logger"
|
"tailscale.com/types/logger"
|
||||||
@ -30,11 +33,22 @@ func detectFirewallMode(logf logger.Logf, prefHint string) FirewallMode {
|
|||||||
} else if prefHint != "" {
|
} else if prefHint != "" {
|
||||||
logf("TS_DEBUG_FIREWALL_MODE set, overriding firewall mode from %s to %s", prefHint, mode)
|
logf("TS_DEBUG_FIREWALL_MODE set, overriding firewall mode from %s to %s", prefHint, mode)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var det linuxFWDetector
|
||||||
|
if mode == "" {
|
||||||
|
// We have no preference, so check if `iptables` is even available.
|
||||||
|
_, err := det.iptDetect()
|
||||||
|
if err != nil && errors.Is(err, exec.ErrNotFound) {
|
||||||
|
logf("iptables not found: %v; falling back to nftables", err)
|
||||||
|
mode = "nftables"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// We now use iptables as default and have "auto" and "nftables" as
|
// We now use iptables as default and have "auto" and "nftables" as
|
||||||
// options for people to test further.
|
// options for people to test further.
|
||||||
switch mode {
|
switch mode {
|
||||||
case "auto":
|
case "auto":
|
||||||
return pickFirewallModeFromInstalledRules(logf, linuxFWDetector{})
|
return pickFirewallModeFromInstalledRules(logf, det)
|
||||||
case "nftables":
|
case "nftables":
|
||||||
hostinfo.SetFirewallMode("nft-forced")
|
hostinfo.SetFirewallMode("nft-forced")
|
||||||
return FirewallModeNfTables
|
return FirewallModeNfTables
|
||||||
|
@ -29,6 +29,9 @@ func DebugIptables(logf logger.Logf) error {
|
|||||||
//
|
//
|
||||||
// It only returns an error when there is no iptables binary, or when iptables -S
|
// It only returns an error when there is no iptables binary, or when iptables -S
|
||||||
// fails. In all other cases, it returns the number of non-default rules.
|
// fails. In all other cases, it returns the number of non-default rules.
|
||||||
|
//
|
||||||
|
// If the iptables binary is not found, it returns an underlying exec.ErrNotFound
|
||||||
|
// error.
|
||||||
func detectIptables() (int, error) {
|
func detectIptables() (int, error) {
|
||||||
// run "iptables -S" to get the list of rules using iptables
|
// run "iptables -S" to get the list of rules using iptables
|
||||||
// exec.Command returns an error if the binary is not found
|
// exec.Command returns an error if the binary is not found
|
||||||
|
Loading…
Reference in New Issue
Block a user