Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Socket permission denied on ping #51

Merged
merged 7 commits into from
Dec 3, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions .github/workflows/docs.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,15 @@
name: docs

on:
workflow_dispatch:
push:
branches:
- main
paths:
- "docs/**"
- ".github/workflows/docs.yaml"
- "mkdocs.yml"
- "Makefile"

jobs:
deploy:
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/test.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,7 @@ jobs:
test-windows:
strategy:
matrix:
os: [windows-2022, windows-2019, windows-10, windows-11]
os: [windows-2022, windows-2019]
needs: build
runs-on: ${{ matrix.os }}
steps:
Expand Down
2 changes: 1 addition & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@
#

MODULE := github.com/situation-sh/situation
VERSION := 0.17.1
VERSION := 0.17.3
COMMIT := $(shell git rev-parse HEAD)

# system stuff
Expand Down
5 changes: 5 additions & 0 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ require (
github.com/invopop/jsonschema v0.12.0
github.com/jaypipes/ghw v0.12.0
github.com/libp2p/go-netroute v0.2.1
github.com/lorenzosaino/go-sysctl v0.3.1
github.com/prometheus-community/pro-bing v0.4.1
github.com/shiena/ansicolor v0.0.0-20230509054315-a9deabde6e02
github.com/shirou/gopsutil/v4 v4.24.7
Expand Down Expand Up @@ -76,13 +77,17 @@ require (
go.opentelemetry.io/otel/metric v1.29.0 // indirect
go.opentelemetry.io/otel/sdk v1.29.0 // indirect
go.opentelemetry.io/otel/trace v1.29.0 // indirect
golang.org/x/exp/typeparams v0.0.0-20220613132600-b0d781184e0d // indirect
golang.org/x/lint v0.0.0-20210508222113-6edffad5e616 // indirect
golang.org/x/mod v0.20.0 // indirect
golang.org/x/net v0.28.0 // indirect
golang.org/x/sync v0.8.0 // indirect
golang.org/x/time v0.6.0 // indirect
golang.org/x/tools v0.24.0 // indirect
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c // indirect
gopkg.in/yaml.v2 v2.4.0 // indirect
gotest.tools/v3 v3.5.1 // indirect
honnef.co/go/tools v0.3.2 // indirect
howett.net/plist v1.0.1 // indirect
modernc.org/gc/v3 v3.0.0-20240801135723-a856999a2e4a // indirect
modernc.org/libc v1.59.9 // indirect
Expand Down
8 changes: 8 additions & 0 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,8 @@ github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE=
github.com/libp2p/go-netroute v0.2.1 h1:V8kVrpD8GK0Riv15/7VN6RbUQ3URNZVosw7H2v9tksU=
github.com/libp2p/go-netroute v0.2.1/go.mod h1:hraioZr0fhBjG0ZRXJJ6Zj2IVEVNx6tDTFQfSmcq7mQ=
github.com/lorenzosaino/go-sysctl v0.3.1 h1:3phX80tdITw2fJjZlwbXQnDWs4S30beNcMbw0cn0HtY=
github.com/lorenzosaino/go-sysctl v0.3.1/go.mod h1:5grcsBRpspKknNS1qzt1eIeRDLrhpKZAtz8Fcuvs1Rc=
github.com/lufia/plan9stats v0.0.0-20240819163618-b1d8f4d146e7 h1:5RK988zAqB3/AN3opGfRpoQgAVqr6/A5+qRTi67VUZY=
github.com/lufia/plan9stats v0.0.0-20240819163618-b1d8f4d146e7/go.mod h1:ilwx/Dta8jXAgpFYFvSWEMwxmbWXyiUHkd5FwyKhb5k=
github.com/mailru/easyjson v0.7.7 h1:UGYAvKxe3sBsEDzO8ZeWOSlIQfWFlxbzLZe7hwFURr0=
Expand Down Expand Up @@ -171,7 +173,11 @@ go.opentelemetry.io/proto/otlp v1.3.1/go.mod h1:0X1WI4de4ZsLrrJNLAQbFeLCm3T7yBkR
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
golang.org/x/exp/typeparams v0.0.0-20220613132600-b0d781184e0d h1:+W8Qf4iJtMGKkyAygcKohjxTk4JPsL9DpzApJ22m5Ic=
golang.org/x/exp/typeparams v0.0.0-20220613132600-b0d781184e0d/go.mod h1:AbB0pIl9nAr9wVwH+Z2ZpaocVmF5I4GyWCDIsVjR0bk=
golang.org/x/lint v0.0.0-20200302205851-738671d3881b/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY=
golang.org/x/lint v0.0.0-20210508222113-6edffad5e616 h1:VLliZ0d+/avPrXXH+OakdXhpJuEoBZuwh1m2j7U6Iug=
golang.org/x/lint v0.0.0-20210508222113-6edffad5e616/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY=
golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg=
golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
Expand Down Expand Up @@ -237,6 +243,8 @@ gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
gotest.tools/v3 v3.5.1 h1:EENdUnS3pdur5nybKYIh2Vfgc8IUNBjxDPSjtiJcOzU=
gotest.tools/v3 v3.5.1/go.mod h1:isy3WKz7GK6uNw/sbHzfKBLvlvXwUyV06n6brMxxopU=
honnef.co/go/tools v0.3.2 h1:ytYb4rOqyp1TSa2EPvNVwtPQJctSELKaMyLfqNP4+34=
honnef.co/go/tools v0.3.2/go.mod h1:jzwdWgg7Jdq75wlfblQxO4neNaFFSvgc1tD5Wv8U0Yw=
howett.net/plist v1.0.1 h1:37GdZ8tP09Q35o9ych3ehygcsL+HqKSwzctveSlarvM=
howett.net/plist v1.0.1/go.mod h1:lqaXoTrLY4hg8tnEzNru53gicrbv7rrk+2xJA/7hw9g=
modernc.org/cc/v4 v4.21.4 h1:3Be/Rdo1fpr8GrQ7IVw9OHtplU4gWbb+wNgeoBMmGLQ=
Expand Down
57 changes: 0 additions & 57 deletions models/machine.go
Original file line number Diff line number Diff line change
Expand Up @@ -207,60 +207,3 @@ func (m *Machine) InsertPackage(pkg *Package) (*Package, bool) {
// m.Packages = append(m.Packages, pkg)
return nil, false
}

func (m *Machine) GetOrCreateHostLoopback(ip net.IP) (*NetworkInterface, bool) {
// check if the iface already exist
// it returns the first iface found
for _, nic := range m.NICS {
if nic.Flags.Loopback {
return nic, false
}
}

ifaces, err := net.Interfaces()
if err != nil {
return nil, false
}
for _, iface := range ifaces {
if (iface.Flags & net.FlagLoopback) > 0 {
addrs, err := iface.Addrs()
if err != nil {
continue
}
if len(addrs) > 0 {
nic := NetworkInterface{
Name: iface.Name,
MAC: iface.HardwareAddr,
}
// set the iface flags
nic.SetFlags(iface.Flags)

for _, addr := range addrs {
ipAddress, network, err := net.ParseCIDR(addr.String())
if ipAddress == nil || network == nil || err != nil {
continue
}
size, _ := network.Mask.Size()

if ipAddress.To4() == nil && nic.IP6 == nil {
// IPv6
nic.IP6 = ipAddress.To16()
nic.Mask6Size = size
} else if nic.IP == nil {
// IPv4
nic.IP = ipAddress.To4()
nic.MaskSize = size
}

}

m.NICS = append(m.NICS, &nic)
return &nic, true

}

}

}
return nil, false
}
6 changes: 3 additions & 3 deletions modules/host_network.go
Original file line number Diff line number Diff line change
Expand Up @@ -169,9 +169,9 @@ func filterInterfaces(interfaces []net.Interface) []net.Interface {
filtered := make([]net.Interface, 0)
for _, iface := range interfaces {
// ignore loopback
if (iface.Flags & net.FlagLoopback) != 0 {
continue
}
// if (iface.Flags & net.FlagLoopback) != 0 {
// continue
// }
// ignore non up
if (iface.Flags & net.FlagUp) == 0 {
continue
Expand Down
48 changes: 24 additions & 24 deletions modules/netstat.go
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ func (m *NetstatModule) Name() string {
}

func (m *NetstatModule) Dependencies() []string {
return []string{"host-basic"}
return []string{"host-basic", "host-network"}
}

func flowFilter(state netstat.SkState) bool {
Expand All @@ -58,12 +58,15 @@ func flowFilter(state netstat.SkState) bool {

// portFilter returns true when the connection is listening, established or close-wait
func portFilter(e *netstat.SockTabEntry) bool {
if e.LocalAddr.IP.IsLoopback() && !e.RemoteAddr.IP.IsLoopback() {
return false
}
// accept everything
if e.State == netstat.Listen || flowFilter(e.State) {
return true
}
// fmt.Println(e.LocalAddr.IP, ":", e.LocalAddr.Port, " -> ", e.RemoteAddr.IP, ":", e.RemoteAddr.Port)
// if e.LocalAddr.IP.IsLoopback() && !e.RemoteAddr.IP.IsLoopback() {
// return false
// }

return false
}

Expand Down Expand Up @@ -99,11 +102,6 @@ func (m *NetstatModule) Run() error {
continue
}

// (NEW!) create localhost if needed (localhost communication)
if entry.LocalAddr.IP.IsLoopback() && entry.RemoteAddr.IP.IsLoopback() {
machine.GetOrCreateHostLoopback(entry.LocalAddr.IP)
}

name := entry.Process.Name
args, err := utils.GetCmd(entry.Process.Pid)
if err == nil && len(args) > 0 {
Expand Down Expand Up @@ -146,21 +144,23 @@ func (m *NetstatModule) Run() error {
soft.Args = args
}

endpoint, created := soft.AddEndpoint(
entry.LocalAddr.IP,
entry.LocalAddr.Port,
protocols[k])
// fmt.Printf("%+v\n", soft)
// fmt.Printf("len: %v, cap: %v, %v\n",
// len(soft.Endpoints), cap(soft.Endpoints), soft.Endpoints)
if created {
// fmt.Println(len(soft.Endpoints))
// logging
l := logger.WithField("app", soft.Name)
l = l.WithField("ip", endpoint.Addr)
l = l.WithField("port", endpoint.Port)
l = l.WithField("proto", endpoint.Protocol)
l.Info("Endpoint found")
if entry.State == netstat.Listen {
endpoint, created := soft.AddEndpoint(
entry.LocalAddr.IP,
entry.LocalAddr.Port,
protocols[k])
// fmt.Printf("%+v\n", soft)
// fmt.Printf("len: %v, cap: %v, %v\n",
// len(soft.Endpoints), cap(soft.Endpoints), soft.Endpoints)
if created {
// fmt.Println(len(soft.Endpoints))
// logging
l := logger.WithField("app", soft.Name)
l = l.WithField("ip", endpoint.Addr)
l = l.WithField("port", endpoint.Port)
l = l.WithField("proto", endpoint.Protocol)
l.Info("Endpoint found")
}
}
}
}
Expand Down
31 changes: 8 additions & 23 deletions modules/ping.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,38 +7,18 @@ package modules
import (
"fmt"
"net"
"os/user"
"runtime"
"strings"
"sync"
"time"

ping "github.com/prometheus-community/pro-bing"
"github.com/sirupsen/logrus"
"github.com/situation-sh/situation/models"
"github.com/situation-sh/situation/modules/pingconfig"
"github.com/situation-sh/situation/store"
"github.com/situation-sh/situation/utils"
)

var useICMP bool = func() bool {
// According to the authors of go-ping
// the pinger must be privileged on windows
// even if we do not run the agent as admin/root
if runtime.GOOS == "windows" {
return true
}
u, err := user.Current()
if err != nil {
return false
}
// On alpine VM with root account, we notice that
// the ping privilege must be set to true
if runtime.GOOS == "linux" && u.Uid == "0" {
return false
}
return false
}()

const errorPrefix = "[ERROR_PREFIX]"

func init() {
Expand Down Expand Up @@ -72,10 +52,10 @@ func singlePing(ip net.IP, maskSize int, wg *sync.WaitGroup, cerr chan error) {
return
}
pinger.Count = 1
pinger.SetPrivileged(useICMP)
pinger.SetPrivileged(pingconfig.UseICMP())
pinger.Timeout = 300 * time.Millisecond
// see https://github.com/go-ping/ping/issues/168
pinger.Size = 548
pinger.Size = 2048

// callback when a target responds
pinger.OnRecv = func(p *ping.Packet) {
Expand Down Expand Up @@ -108,6 +88,11 @@ func singlePing(ip net.IP, maskSize int, wg *sync.WaitGroup, cerr chan error) {
logger.Info("New machine added")
store.InsertMachine(m)
}

pinger.OnSendError = func(p *ping.Packet, err error) {

}
// run
if err := pinger.Run(); err != nil {
logrus.Debugf("Error: %v", err)
cerr <- fmt.Errorf("error while pinging %v: %v", ip, err)
Expand Down
73 changes: 73 additions & 0 deletions modules/pingconfig/ping_linux.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
//go:build linux
// +build linux

package pingconfig

import (
"os/user"
"regexp"
"strconv"
"strings"

sysctl "github.com/lorenzosaino/go-sysctl"
)

// Retrieve net.ipv4.ping_group_range
func getPingGroupRange() (int, int, error) {
start := -1
end := -1
value, err := sysctl.Get("net.ipv4.ping_group_range")
if err != nil {
return start, end, err
}

value = strings.TrimSpace(value)
re := regexp.MustCompile(`^([0-9]+)[ ]+([0-9]+)$`)
subm := re.FindStringSubmatch(value)
if len(subm) < 3 {
return start, end, err
}
start, err = strconv.Atoi(subm[1])
if err != nil {
return start, end, err
}
end, err = strconv.Atoi(subm[2])
return start, end, err
}

func isUserAllowedToPing(usr *user.User) (bool, error) {
groups, err := usr.GroupIds()
if err != nil {
return false, err
}
start, end, err := getPingGroupRange()
if err != nil {
return false, err
}

if start > end {
return false, nil
}

for gid := range groups {
if (start <= gid) && (gid <= end) {
return true, nil
}
}
return false, nil
}

func UseICMP() bool {
usr, err := user.Current()
if err != nil {
return false
}

// check sysctl
allowed, err := isUserAllowedToPing(usr)
if err != nil {
return false
}

return !allowed
}
11 changes: 11 additions & 0 deletions modules/pingconfig/ping_windows.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
//go:build windows
// +build windows

package pingconfig

// According to the authors of go-ping
// the pinger must be privileged on windows
// even if we do not run the agent as admin/root
func UseICMP() bool {
return true
}
Loading