health: warn about reverse path filtering and exit nodes
When reverse path filtering is in strict mode on Linux, using an exit node blocks all network connectivity. This change adds a warning about this to `tailscale status` and the logs. Example in `tailscale status`: ``` - not connected to home DERP region 22 - The following issues on your machine will likely make usage of exit nodes impossible: [interface "eth0" has strict reverse-path filtering enabled], please set rp_filter=2 instead of rp_filter=1; see https://github.com/tailscale/tailscale/issues/3310 ``` Example in the logs: ``` 2024/02/21 21:17:07 health("overall"): error: multiple errors: not in map poll The following issues on your machine will likely make usage of exit nodes impossible: [interface "eth0" has strict reverse-path filtering enabled], please set rp_filter=2 instead of rp_filter=1; see https://github.com/tailscale/tailscale/issues/3310 ``` Updates #3310 Signed-off-by: Anton Tolchanov <anton@tailscale.com>
This commit is contained in:

committed by
Anton Tolchanov

parent
7ef1fb113d
commit
8cc5c51888
@ -153,7 +153,7 @@ func CheckIPForwarding(routes []netip.Prefix, state *interfaces.State) (warn, er
|
||||
// This function returns an error if it is unable to determine whether reverse
|
||||
// path filtering is enabled, or a warning describing configuration issues if
|
||||
// reverse path fitering is non-functional or partly functional.
|
||||
func CheckReversePathFiltering(routes []netip.Prefix, state *interfaces.State) (warn []string, err error) {
|
||||
func CheckReversePathFiltering(state *interfaces.State) (warn []string, err error) {
|
||||
if runtime.GOOS != "linux" {
|
||||
return nil, nil
|
||||
}
|
||||
@ -166,12 +166,6 @@ func CheckReversePathFiltering(routes []netip.Prefix, state *interfaces.State) (
|
||||
}
|
||||
}
|
||||
|
||||
// Reverse path filtering as a syscall is only implemented on Linux for IPv4.
|
||||
wantV4, _ := protocolsRequiredForForwarding(routes, state)
|
||||
if !wantV4 {
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
// The kernel uses the maximum value for rp_filter between the 'all'
|
||||
// setting and each per-interface config, so we need to fetch both.
|
||||
allSetting, err := reversePathFilterValueLinux("all")
|
||||
@ -205,7 +199,7 @@ func CheckReversePathFiltering(routes []netip.Prefix, state *interfaces.State) (
|
||||
iSetting = allSetting
|
||||
}
|
||||
if iSetting == filtStrict {
|
||||
warn = append(warn, fmt.Sprintf("Interface %q has strict reverse-path filtering enabled", iface.Name))
|
||||
warn = append(warn, fmt.Sprintf("interface %q has strict reverse-path filtering enabled", iface.Name))
|
||||
}
|
||||
}
|
||||
return warn, nil
|
||||
|
Reference in New Issue
Block a user