Skip to content

Commit 479b8de

Browse files
improved connections parsing
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.
1 parent 743ef71 commit 479b8de

File tree

2 files changed

+12
-10
lines changed

2 files changed

+12
-10
lines changed

daemon/conman/connection.go

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -83,7 +83,7 @@ func newConnectionImpl(nfp *netfilter.Packet, c *Connection, protoType string) (
8383
}
8484

8585
pid := -1
86-
var uid int
86+
uid := -1
8787
if procmon.MethodIsEbpf() {
8888
pid, uid, err = ebpf.GetPid(c.Protocol, c.SrcPort, c.SrcIP, c.DstIP, c.DstPort)
8989
if err != nil {
@@ -118,17 +118,17 @@ func newConnectionImpl(nfp *netfilter.Packet, c *Connection, protoType string) (
118118
for n, inode := range inodeList {
119119
pid = procmon.GetPIDFromINode(inode, fmt.Sprint(inode, c.SrcIP, c.SrcPort, c.DstIP, c.DstPort))
120120
if pid != -1 {
121-
log.Debug("[%d] PID found %d", n, pid)
121+
log.Debug("[%d] PID found %d [%d]", n, pid, inode)
122122
c.Entry.INode = inode
123123
break
124124
}
125125
}
126126
}
127127

128-
if uid != -1 {
129-
c.Entry.UserId = uid
130-
} else if c.Entry.UserId == -1 && nfp.UID != 0xffffffff {
128+
if nfp.UID != 0xffffffff {
131129
c.Entry.UserId = int(nfp.UID)
130+
} else {
131+
c.Entry.UserId = uid
132132
}
133133

134134
if pid == os.Getpid() {

daemon/netlink/socket.go

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -44,8 +44,9 @@ func GetSocketInfo(proto string, srcIP net.IP, srcPort uint, dstIP net.IP, dstPo
4444
if sock.UID != 0xffffffff {
4545
uid = int(sock.UID)
4646
}
47-
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 ",
47+
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 ",
4848
n, len(sockList),
49+
int(sock.UID),
4950
srcPort, srcIP, dstIP, dstPort,
5051
sock.ID.SourcePort, sock.ID.Source,
5152
sock.ID.Destination, sock.ID.DestinationPort, sock.INode,
@@ -62,14 +63,11 @@ func GetSocketInfo(proto string, srcIP net.IP, srcPort uint, dstIP net.IP, dstPo
6263
((sock.ID.Destination.IsGlobalUnicast() || sock.ID.Destination.IsLoopback()) && sock.ID.Destination.Equal(dstIP)) {
6364
inodes = append([]int{int(sock.INode)}, inodes...)
6465
continue
65-
} else if sock.ID.SourcePort == uint16(srcPort) && sock.ID.Source.Equal(srcIP) &&
66-
(sock.ID.DestinationPort == uint16(dstPort)) {
67-
inodes = append([]int{int(sock.INode)}, inodes...)
68-
continue
6966
}
7067
log.Debug("GetSocketInfo() invalid: %d:%v -> %v:%d", sock.ID.SourcePort, sock.ID.Source, sock.ID.Destination, sock.ID.DestinationPort)
7168
}
7269

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

0 commit comments

Comments
 (0)