mirror of
https://github.com/tailscale/tailscale.git
synced 2024-11-29 04:55:31 +00:00
wgengine/router: disable IPv6 on Linux if ip rule -6 fails (#1074)
Updates #562 Fixes #973 Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
This commit is contained in:
parent
1e88050403
commit
0d94fe5f69
@ -6,6 +6,7 @@
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"errors"
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"os"
|
||||
@ -113,8 +114,15 @@ func newUserspaceRouter(logf logger.Logf, _ *device.Device, tunDev tun.Device) (
|
||||
return nil, err
|
||||
}
|
||||
|
||||
supportsV6 := supportsV6()
|
||||
v6err := checkIPv6()
|
||||
if v6err != nil {
|
||||
logf("disabling IPv6 due to system IPv6 config: %v", v6err)
|
||||
}
|
||||
supportsV6 := v6err == nil
|
||||
supportsV6NAT := supportsV6 && supportsV6NAT()
|
||||
if supportsV6 {
|
||||
logf("v6nat = %v", supportsV6NAT)
|
||||
}
|
||||
|
||||
var ipt6 netfilterRunner
|
||||
if supportsV6 {
|
||||
@ -1003,46 +1011,53 @@ func cleanup(logf logger.Logf, interfaceName string) {
|
||||
// TODO(dmytro): clean up iptables.
|
||||
}
|
||||
|
||||
// supportsV6 returns whether the system appears to have a working
|
||||
// IPv6 network stack.
|
||||
func supportsV6() bool {
|
||||
// checkIPv6 checks whether the system appears to have a working IPv6
|
||||
// network stack. It returns an error explaining what looks wrong or
|
||||
// missing. It does not check that IPv6 is currently functional or
|
||||
// that there's a global address, just that the system would support
|
||||
// IPv6 if it were on an IPv6 network.
|
||||
func checkIPv6() error {
|
||||
_, err := os.Stat("/proc/sys/net/ipv6")
|
||||
if os.IsNotExist(err) {
|
||||
return false
|
||||
return err
|
||||
}
|
||||
bs, err := ioutil.ReadFile("/proc/sys/net/ipv6/conf/all/disable_ipv6")
|
||||
if err != nil {
|
||||
// Be conservative if we can't find the ipv6 configuration knob.
|
||||
return false
|
||||
return err
|
||||
}
|
||||
disabled, err := strconv.ParseBool(strings.TrimSpace(string(bs)))
|
||||
if err != nil {
|
||||
return false
|
||||
return errors.New("disable_ipv6 has invalid bool")
|
||||
}
|
||||
if disabled {
|
||||
return false
|
||||
return errors.New("disable_ipv6 is set")
|
||||
}
|
||||
|
||||
// Older kernels don't support IPv6 policy routing.
|
||||
bs, err = ioutil.ReadFile("/proc/sys/net/ipv6/conf/all/disable_policy")
|
||||
if err != nil {
|
||||
// Absent knob means policy routing is unsupported.
|
||||
return false
|
||||
return err
|
||||
}
|
||||
disabled, err = strconv.ParseBool(strings.TrimSpace(string(bs)))
|
||||
if err != nil {
|
||||
return false
|
||||
return errors.New("disable_policy has invalid bool")
|
||||
}
|
||||
if disabled {
|
||||
return false
|
||||
return errors.New("disable_policy is set")
|
||||
}
|
||||
|
||||
// Some distros ship ip6tables separately from iptables.
|
||||
if _, err := exec.LookPath("ip6tables"); err != nil {
|
||||
return false
|
||||
return err
|
||||
}
|
||||
|
||||
return true
|
||||
if err := checkIPRuleSupportsV6(); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// supportsV6NAT returns whether the system has a "nat" table in the
|
||||
@ -1060,3 +1075,22 @@ func supportsV6NAT() bool {
|
||||
|
||||
return bytes.Contains(bs, []byte("nat\n"))
|
||||
}
|
||||
|
||||
func checkIPRuleSupportsV6() error {
|
||||
// First add a rule for "ip rule del" to delete.
|
||||
// We ignore the "add" operation's error because it can also
|
||||
// fail if the rule already exists.
|
||||
exec.Command("ip", "-6", "rule", "add",
|
||||
"pref", "123", "fwmark", tailscaleBypassMark, "table", fmt.Sprint(tailscaleRouteTable)).Run()
|
||||
out, err := exec.Command("ip", "-6", "rule", "del",
|
||||
"pref", "123", "fwmark", tailscaleBypassMark, "table", fmt.Sprint(tailscaleRouteTable)).CombinedOutput()
|
||||
if err != nil {
|
||||
out = bytes.TrimSpace(out)
|
||||
var detail interface{} = out
|
||||
if len(out) == 0 {
|
||||
detail = err.Error()
|
||||
}
|
||||
return fmt.Errorf("ip -6 rule failed: %s", detail)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user