Skip to content

Commit a01721b

Browse files
authored
chore: no longer correlate other events to dns events (#11)
Currently we try to correlate other connections with hostnames from recent dns events. This winds up error prone and can cause surprising and incorrect correlations. This removes that functionality in favor of just printing out DNS traffic we see.
1 parent 6782f7e commit a01721b

File tree

5 files changed

+70
-22
lines changed

5 files changed

+70
-22
lines changed

bpf/counter.c

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -92,7 +92,12 @@ struct {
9292
static const __u8 ip4in6[] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0xff, 0xff};
9393

9494
typedef struct udp_pkt_t {
95+
struct in6_addr srcip; // source IPv6 address
96+
struct in6_addr dstip; // destination IPv6 address
97+
__u16 src_port; // source port
98+
__u16 dst_port;
9599
pid_t pid;
100+
char comm[TASK_COMM_LEN];
96101
unsigned char pkt[MAX_PKT];
97102
} udp_pkt;
98103

@@ -717,12 +722,17 @@ static inline void process_udp_recv(struct sk_buff *skb, statkey *key,
717722
}
718723

719724
data->pid = pid;
725+
data->src_port = key->src_port;
726+
data->dst_port = key->dst_port;
720727
unsigned char *pktdata = BPF_CORE_READ(skb, data);
721728
size_t buflen = BPF_CORE_READ(skb, len);
722729
if (buflen > MAX_PKT) {
723730
buflen = MAX_PKT;
724731
}
725732

733+
__builtin_memcpy(&data->srcip, &key->srcip, sizeof(struct in6_addr));
734+
__builtin_memcpy(&data->dstip, &key->dstip, sizeof(struct in6_addr));
735+
__builtin_memcpy(&data->comm, &key->comm, sizeof(data->comm));
726736
bpf_core_read(&data->pkt, buflen, pktdata);
727737
bpf_ringbuf_submit(data, 0);
728738
}

counter_arm64_bpfel.go

Lines changed: 7 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

counter_x86_bpfel.go

Lines changed: 11 additions & 4 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

dns.go

Lines changed: 41 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -7,18 +7,27 @@ import (
77
"errors"
88
"fmt"
99
"log"
10-
"sync"
10+
"time"
1111

1212
"github.com/cilium/ebpf/ringbuf"
1313
"github.com/google/gopacket"
1414
"github.com/google/gopacket/layers"
1515
)
1616

17-
func processUDPPackets(ctx context.Context, reader *ringbuf.Reader, dnsLookupMap map[uint32]string, dnsLookupMapMutex *sync.RWMutex) {
17+
func processUDPPackets(ctx context.Context, reader *ringbuf.Reader) {
18+
seenDNSPackets := map[statEntry]struct{}{}
19+
resetSeenPacketsTick := time.NewTicker(time.Minute)
20+
defer resetSeenPacketsTick.Stop()
21+
1822
for {
1923
select {
2024
case <-ctx.Done():
2125
return
26+
case <-resetSeenPacketsTick.C:
27+
// Reset the seenDNSPacketIDs map every once in a while so it doesn't grow unbounded,
28+
// as well the unlikely case a random ID gets re-used. There is a small chance we reset
29+
// this in between processing packets that would result in a duplicate entry, but that's fine.
30+
seenDNSPackets = map[statEntry]struct{}{}
2231
default:
2332
record, err := reader.Read()
2433
if err != nil {
@@ -52,10 +61,36 @@ func processUDPPackets(ctx context.Context, reader *ringbuf.Reader, dnsLookupMap
5261
log.Printf("Skipping dns packet: no questions")
5362
}
5463

55-
// just grab the first question for now
56-
dnsLookupMapMutex.Lock()
57-
dnsLookupMap[uint32(udpPktDetails.Pid)] = string(dnsLayer.Questions[0].Name)
58-
dnsLookupMapMutex.Unlock()
64+
entry := statEntry{
65+
SrcPort: udpPktDetails.SrcPort,
66+
SrcIP: bytesToAddr(udpPktDetails.Srcip.In6U.U6Addr8),
67+
DstPort: udpPktDetails.DstPort,
68+
DstIP: bytesToAddr(udpPktDetails.Dstip.In6U.U6Addr8),
69+
Proto: "UDP",
70+
Pid: udpPktDetails.Pid,
71+
Comm: comm2String(udpPktDetails.Comm[:]),
72+
DNSQueryName: string(dnsLayer.Questions[0].Name),
73+
LikelyService: "dns",
74+
}
75+
76+
if getKubeClient() != nil {
77+
entry.SourcePod = lookupPodForIP(entry.SrcIP)
78+
entry.DstPod = lookupPodForIP(entry.DstIP)
79+
}
80+
81+
// Currently we see the same DNS packet make it's journey from the originating process,
82+
// to the local dns resolver, and on it's way out of the VM's network. This results in
83+
// quite a few duplicate events being printed to stdout. So check if this would cause
84+
// a duplicate output and skip printing it if so.
85+
if _, ok := seenDNSPackets[entry]; ok {
86+
log.Printf("Skipping DNS packet we've already seen")
87+
continue
88+
} else {
89+
seenDNSPackets[entry] = struct{}{}
90+
}
91+
92+
entry.Timestamp = time.Now().UTC()
93+
fmt.Print(outputJSON([]statEntry{entry}))
5994
}
6095
}
6196
}

main.go

Lines changed: 1 addition & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -162,7 +162,7 @@ func main() {
162162
log.Printf("Failed to create ringbuf reader for UDP packets: %v", err)
163163
} else {
164164
log.Printf("Created UDP packet ringbuf reader successfully")
165-
go processUDPPackets(ctx, udpPktReader, dnsLookupMap, dnsLookupMapMutex)
165+
go processUDPPackets(ctx, udpPktReader)
166166
defer udpPktReader.Close()
167167
}
168168

@@ -181,15 +181,6 @@ func main() {
181181
// Filter out entries we've already seen and enrich with DNS data
182182
var newEntries []statEntry
183183
for _, entry := range entries {
184-
// Enrich entry with DNS hostname if available
185-
if entry.Pid != 0 {
186-
dnsLookupMapMutex.RLock()
187-
if hostname, exists := dnsLookupMap[uint32(entry.Pid)]; exists {
188-
entry.DNSQueryName = hostname
189-
}
190-
dnsLookupMapMutex.RUnlock()
191-
}
192-
193184
// For --unique tracking (without timestamp)
194185
uniqueKey := fmt.Sprintf("%s:%d->%s:%d:%s:%d:%s",
195186
entry.SrcIP, entry.SrcPort, entry.DstIP, entry.DstPort,

0 commit comments

Comments
 (0)