TUN-6715: Provide suggestion to add cloudflared to ping_group_range if it failed to open ICMP socket
This commit is contained in:
parent
b3e26420c0
commit
fdddd86380
|
@ -12,6 +12,9 @@ import (
|
|||
"fmt"
|
||||
"net"
|
||||
"net/netip"
|
||||
"os"
|
||||
"regexp"
|
||||
"strconv"
|
||||
"time"
|
||||
|
||||
"github.com/pkg/errors"
|
||||
|
@ -21,6 +24,15 @@ import (
|
|||
"github.com/cloudflare/cloudflared/packet"
|
||||
)
|
||||
|
||||
const (
|
||||
// https://lwn.net/Articles/550551/ IPv4 and IPv6 share the same path
|
||||
pingGroupPath = "/proc/sys/net/ipv4/ping_group_range"
|
||||
)
|
||||
|
||||
var (
|
||||
findGroupIDRegex = regexp.MustCompile(`\d+`)
|
||||
)
|
||||
|
||||
type icmpProxy struct {
|
||||
srcFunnelTracker *packet.FunnelTracker
|
||||
listenIP netip.Addr
|
||||
|
@ -30,7 +42,7 @@ type icmpProxy struct {
|
|||
}
|
||||
|
||||
func newICMPProxy(listenIP netip.Addr, zone string, logger *zerolog.Logger, idleTimeout time.Duration) (*icmpProxy, error) {
|
||||
if err := testPermission(listenIP, zone); err != nil {
|
||||
if err := testPermission(listenIP, zone, logger); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &icmpProxy{
|
||||
|
@ -42,12 +54,17 @@ func newICMPProxy(listenIP netip.Addr, zone string, logger *zerolog.Logger, idle
|
|||
}, nil
|
||||
}
|
||||
|
||||
func testPermission(listenIP netip.Addr, zone string) error {
|
||||
func testPermission(listenIP netip.Addr, zone string, logger *zerolog.Logger) error {
|
||||
// Opens a non-privileged ICMP socket. On Linux the group ID of the process needs to be in ping_group_range
|
||||
// Only check ping_group_range once for IPv4
|
||||
if listenIP.Is4() {
|
||||
if err := checkInPingGroup(); err != nil {
|
||||
logger.Warn().Err(err).Msgf("The user running cloudflared process has a GID (group ID) that is not within ping_group_range. You might need to add that user to a group within that range, or instead update the range to encompass a group the user is already in by modifying %s. Otherwise cloudflared will not be able to ping this network", pingGroupPath)
|
||||
return err
|
||||
}
|
||||
}
|
||||
conn, err := newICMPConn(listenIP, zone)
|
||||
if err != nil {
|
||||
// TODO: TUN-6715 check if cloudflared is in ping_group_range if the check failed. If not log instruction to
|
||||
// change the group ID
|
||||
return err
|
||||
}
|
||||
// This conn is only to test if cloudflared has permission to open this type of socket
|
||||
|
@ -55,6 +72,31 @@ func testPermission(listenIP netip.Addr, zone string) error {
|
|||
return nil
|
||||
}
|
||||
|
||||
func checkInPingGroup() error {
|
||||
file, err := os.ReadFile(pingGroupPath)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
groupID := os.Getgid()
|
||||
// Example content: 999 59999
|
||||
found := findGroupIDRegex.FindAll(file, 2)
|
||||
if len(found) == 2 {
|
||||
groupMin, err := strconv.ParseUint(string(found[0]), 10, 16)
|
||||
if err != nil {
|
||||
return errors.Wrapf(err, "failed to determine minimum ping group ID")
|
||||
}
|
||||
groupMax, err := strconv.ParseUint(string(found[1]), 10, 16)
|
||||
if err != nil {
|
||||
return errors.Wrapf(err, "failed to determine minimum ping group ID")
|
||||
}
|
||||
if groupID < int(groupMin) || groupID > int(groupMax) {
|
||||
return fmt.Errorf("Group ID %d is not between ping group %d to %d", groupID, groupMin, groupMax)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
return fmt.Errorf("did not find group range in %s", pingGroupPath)
|
||||
}
|
||||
|
||||
func (ip *icmpProxy) Request(pk *packet.ICMP, responder packet.FunnelUniPipe) error {
|
||||
if pk == nil {
|
||||
return errPacketNil
|
||||
|
|
Loading…
Reference in New Issue