Skip to content

Commit

Permalink
improved connections parsing
Browse files Browse the repository at this point in the history
Under certain conditions, when we dumped inodes via netlink, we were
linking network connections to wrong applications.

- To improve this situation:

1) Use netfilter's UID by default:
   Sometimes the UID reported via netlink was different than the one
   reported by libnetfilter. libnetfilter UID is always correct.
   If you had a rule that filtered by UID, this problem could cause to
   prompt you again to allow the connection.

2) Use the netlink entry that matches exactly the properties of an
   outgoing connection:
   There're some in-kernel sockets that doesn't match 1:1 outgoing
   connections (daemon/netlink/socket.go#L22).
   In order to identify the applications that initiate these network
   connections we use a workaround. But under certain conditions
   (source port reuse), we were associating connections to wrong
   applications.
   So in order to avoid this problem, if there's a 1:1 match use that
   netlink entry. If not, fallback to the workaround.

- misc: added more logs to better debug these issues.
  • Loading branch information
gustavo-iniguez-goya committed Nov 15, 2021
1 parent 743ef71 commit 479b8de
Show file tree
Hide file tree
Showing 2 changed files with 12 additions and 10 deletions.
10 changes: 5 additions & 5 deletions daemon/conman/connection.go
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,7 @@ func newConnectionImpl(nfp *netfilter.Packet, c *Connection, protoType string) (
}

pid := -1
var uid int
uid := -1
if procmon.MethodIsEbpf() {
pid, uid, err = ebpf.GetPid(c.Protocol, c.SrcPort, c.SrcIP, c.DstIP, c.DstPort)
if err != nil {
Expand Down Expand Up @@ -118,17 +118,17 @@ func newConnectionImpl(nfp *netfilter.Packet, c *Connection, protoType string) (
for n, inode := range inodeList {
pid = procmon.GetPIDFromINode(inode, fmt.Sprint(inode, c.SrcIP, c.SrcPort, c.DstIP, c.DstPort))
if pid != -1 {
log.Debug("[%d] PID found %d", n, pid)
log.Debug("[%d] PID found %d [%d]", n, pid, inode)
c.Entry.INode = inode
break
}
}
}

if uid != -1 {
c.Entry.UserId = uid
} else if c.Entry.UserId == -1 && nfp.UID != 0xffffffff {
if nfp.UID != 0xffffffff {
c.Entry.UserId = int(nfp.UID)
} else {
c.Entry.UserId = uid
}

if pid == os.Getpid() {
Expand Down
12 changes: 7 additions & 5 deletions daemon/netlink/socket.go
Original file line number Diff line number Diff line change
Expand Up @@ -44,8 +44,9 @@ func GetSocketInfo(proto string, srcIP net.IP, srcPort uint, dstIP net.IP, dstPo
if sock.UID != 0xffffffff {
uid = int(sock.UID)
}
log.Debug("[%d/%d] outgoing connection: %d:%v -> %v:%d || netlink response: %d:%v -> %v:%d inode: %d - loopback: %v multicast: %v unspecified: %v linklocalunicast: %v ifaceLocalMulticast: %v GlobalUni: %v ",
log.Debug("[%d/%d] outgoing connection uid: %d, %d:%v -> %v:%d || netlink response: %d:%v -> %v:%d inode: %d - loopback: %v multicast: %v unspecified: %v linklocalunicast: %v ifaceLocalMulticast: %v GlobalUni: %v ",
n, len(sockList),
int(sock.UID),
srcPort, srcIP, dstIP, dstPort,
sock.ID.SourcePort, sock.ID.Source,
sock.ID.Destination, sock.ID.DestinationPort, sock.INode,
Expand All @@ -62,14 +63,11 @@ func GetSocketInfo(proto string, srcIP net.IP, srcPort uint, dstIP net.IP, dstPo
((sock.ID.Destination.IsGlobalUnicast() || sock.ID.Destination.IsLoopback()) && sock.ID.Destination.Equal(dstIP)) {
inodes = append([]int{int(sock.INode)}, inodes...)
continue
} else if sock.ID.SourcePort == uint16(srcPort) && sock.ID.Source.Equal(srcIP) &&
(sock.ID.DestinationPort == uint16(dstPort)) {
inodes = append([]int{int(sock.INode)}, inodes...)
continue
}
log.Debug("GetSocketInfo() invalid: %d:%v -> %v:%d", sock.ID.SourcePort, sock.ID.Source, sock.ID.Destination, sock.ID.DestinationPort)
}

// handle special cases (see function description): ntp queries (123), broadcasts, incomming connections.
if len(inodes) == 0 && len(sockList) > 0 {
for n, sock := range sockList {
if sockList[n].ID.Destination.Equal(net.IPv4zero) || sockList[n].ID.Destination.Equal(net.IPv6zero) {
Expand All @@ -79,6 +77,10 @@ func GetSocketInfo(proto string, srcIP net.IP, srcPort uint, dstIP net.IP, dstPo
sockList[n].ID.SourcePort, sockList[n].ID.Source,
sockList[n].ID.Destination, sockList[n].ID.DestinationPort,
sockList[n].INode, TCPStatesMap[sock.State])
} else if sock.ID.SourcePort == uint16(srcPort) && sock.ID.Source.Equal(srcIP) &&
(sock.ID.DestinationPort == uint16(dstPort)) {
inodes = append([]int{int(sock.INode)}, inodes...)
continue
} else {
log.Debug("netlink socket not found, EXCLUDING entry: %d:%v -> %v:%d || %d:%v -> %v:%d inode: %d state: %s",
srcPort, srcIP, dstIP, dstPort,
Expand Down

0 comments on commit 479b8de

Please sign in to comment.