Skip to content

Commit c36dfe1

Browse files
authored
Fix bug where TCP SYN to a pod IP was not ignored on freshly started pods, potentially causing spammed discovered intents in cases of fast IP reuse (#272)
1 parent d6365d4 commit c36dfe1

File tree

2 files changed

+83
-6
lines changed

2 files changed

+83
-6
lines changed

src/mapper/pkg/resolvers/resolver_test.go

+70
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ import (
99
"github.com/otterize/intents-operator/src/shared/serviceidresolver"
1010
"github.com/otterize/network-mapper/src/mapper/pkg/awsintentsholder"
1111
"github.com/otterize/network-mapper/src/mapper/pkg/azureintentsholder"
12+
"github.com/otterize/network-mapper/src/mapper/pkg/config"
1213
"github.com/otterize/network-mapper/src/mapper/pkg/dnscache"
1314
"github.com/otterize/network-mapper/src/mapper/pkg/externaltrafficholder"
1415
"github.com/otterize/network-mapper/src/mapper/pkg/graph/model"
@@ -1503,6 +1504,75 @@ func (s *ResolverTestSuite) TestDiscoverInternalSrcIdentityIgnoreControlPlaneIfB
15031504
s.Require().Empty(identity)
15041505
}
15051506

1507+
func (s *ResolverTestSuite) TestReportTCPResultsIgnoreTargetsWithShortUptime() {
1508+
srcPodIP := "1.1.1.3"
1509+
_ = s.AddPod("pod3", srcPodIP, nil, nil)
1510+
targetPodIP := "1.1.1.2"
1511+
targetServiceIp := "10.0.0.37"
1512+
s.AddDeploymentWithService("service1", []string{targetPodIP}, map[string]string{"app": "service1"}, targetServiceIp)
1513+
s.Require().True(s.Mgr.GetCache().WaitForCacheSync(context.Background()))
1514+
1515+
// Report TCP results of traffic from src pod to target pod with short uptime
1516+
packetBadTimingBeforePodsCreation := time.Now().Add(config.TimeServerHasToLiveBeforeWeTrustItDefault).Add(-time.Minute)
1517+
err := s.resolver.handleReportTCPCaptureResults(context.Background(), model.CaptureTCPResults{
1518+
Results: []model.RecordedDestinationsForSrc{
1519+
{
1520+
SrcIP: srcPodIP,
1521+
Destinations: []model.Destination{
1522+
{
1523+
Destination: targetPodIP,
1524+
DestinationIP: &targetPodIP,
1525+
DestinationPort: lo.ToPtr(int64(80)),
1526+
LastSeen: packetBadTimingBeforePodsCreation,
1527+
},
1528+
},
1529+
},
1530+
},
1531+
})
1532+
s.Require().NoError(err)
1533+
s.Require().Len(s.intentsHolder.GetNewIntentsSinceLastGet(), 0)
1534+
1535+
// Report TCP results of traffic from src pod to target pod with good uptime
1536+
packetGoodTimingAfterPodsCreation := time.Now().Add(config.TimeServerHasToLiveBeforeWeTrustItDefault).Add(time.Minute)
1537+
err = s.resolver.handleReportTCPCaptureResults(context.Background(), model.CaptureTCPResults{
1538+
Results: []model.RecordedDestinationsForSrc{
1539+
{
1540+
SrcIP: srcPodIP,
1541+
Destinations: []model.Destination{
1542+
{
1543+
Destination: targetPodIP,
1544+
DestinationIP: &targetPodIP,
1545+
DestinationPort: lo.ToPtr(int64(80)),
1546+
LastSeen: packetGoodTimingAfterPodsCreation,
1547+
},
1548+
},
1549+
},
1550+
},
1551+
})
1552+
s.Require().NoError(err)
1553+
s.Require().Len(s.intentsHolder.GetNewIntentsSinceLastGet(), 1)
1554+
1555+
// Report TCP results of traffic from src pod to target service with short uptime
1556+
err = s.resolver.handleReportTCPCaptureResults(context.Background(), model.CaptureTCPResults{
1557+
Results: []model.RecordedDestinationsForSrc{
1558+
{
1559+
SrcIP: srcPodIP,
1560+
Destinations: []model.Destination{
1561+
{
1562+
Destination: targetServiceIp,
1563+
DestinationIP: &targetServiceIp,
1564+
DestinationPort: lo.ToPtr(int64(80)),
1565+
LastSeen: packetBadTimingBeforePodsCreation,
1566+
},
1567+
},
1568+
},
1569+
},
1570+
})
1571+
s.Require().NoError(err)
1572+
s.Require().Len(s.intentsHolder.GetNewIntentsSinceLastGet(), 1)
1573+
1574+
}
1575+
15061576
func TestRunSuite(t *testing.T) {
15071577
suite.Run(t, new(ResolverTestSuite))
15081578
}

src/mapper/pkg/resolvers/schema.helpers.resolvers.go

+13-6
Original file line numberDiff line numberDiff line change
@@ -57,20 +57,20 @@ func updateTelemetriesCounters(sourceType SourceType, intent model.Intent) {
5757
}
5858
}
5959

60-
func (r *Resolver) resolveDestIdentity(ctx context.Context, dest model.Destination, lastSeen time.Time) (model.OtterizeServiceIdentity, bool, error) {
61-
destSvc, foundSvc, err := r.kubeFinder.ResolveIPToService(ctx, dest.Destination)
60+
func (r *Resolver) resolveDestIdentityTCP(ctx context.Context, dest model.Destination, lastSeen time.Time) (model.OtterizeServiceIdentity, bool, error) {
61+
destSvc, isTargetService, err := r.kubeFinder.ResolveIPToService(ctx, dest.Destination)
6262
if err != nil {
6363
return model.OtterizeServiceIdentity{}, false, errors.Wrap(err)
6464
}
65-
if foundSvc {
65+
if isTargetService {
6666
dstSvcIdentity, ok, err := r.kubeFinder.ResolveOtterizeIdentityForService(ctx, destSvc, lastSeen)
6767
if err != nil {
6868
return model.OtterizeServiceIdentity{}, false, errors.Wrap(err)
6969
}
7070
if ok {
7171
dstSvcIdentity.ResolutionData.Host = lo.ToPtr(dest.Destination)
7272
dstSvcIdentity.ResolutionData.Port = dest.DestinationPort
73-
dstSvcIdentity.ResolutionData.ExtraInfo = lo.ToPtr("resolveDestIdentity")
73+
dstSvcIdentity.ResolutionData.ExtraInfo = lo.ToPtr("resolveDestIdentityTCP")
7474
return dstSvcIdentity, true, nil
7575
}
7676
}
@@ -95,6 +95,13 @@ func (r *Resolver) resolveDestIdentity(ctx context.Context, dest model.Destinati
9595
return model.OtterizeServiceIdentity{}, false, nil
9696
}
9797

98+
// If the mapper runs on AWS - pod ip addresses can be reused. In this case we ignore the traffic if service is not at least 5 minutes old.
99+
fiveMinutesAgo := dest.LastSeen.Add(-viper.GetDuration(config.TimeServerHasToLiveBeforeWeTrustItKey))
100+
if destPod.CreationTimestamp.Time.After(fiveMinutesAgo) {
101+
logrus.Debugf("Pod %s is not up at least %d minutes, ignoring", destPod.Name, int(viper.GetDuration(config.TimeServerHasToLiveBeforeWeTrustItKey).Minutes()))
102+
return model.OtterizeServiceIdentity{}, false, nil
103+
}
104+
98105
dstService, err := r.serviceIdResolver.ResolvePodToServiceIdentity(ctx, destPod)
99106
if err != nil {
100107
logrus.WithError(err).Debugf("Could not resolve pod %s to identity", destPod.Name)
@@ -110,7 +117,7 @@ func (r *Resolver) resolveDestIdentity(ctx context.Context, dest model.Destinati
110117
PodHostname: lo.ToPtr(destPod.Name),
111118
Port: dest.DestinationPort,
112119
IsService: lo.ToPtr(false),
113-
ExtraInfo: lo.ToPtr("resolveDestIdentity"),
120+
ExtraInfo: lo.ToPtr("resolveDestIdentityTCP"),
114121
LastSeen: lo.ToPtr(dest.LastSeen.String()),
115122
Uptime: lo.ToPtr(time.Since(destPod.CreationTimestamp.Time).String()),
116123
HasLinkerdSidecar: lo.ToPtr(hasLinkerdSidecar(destPod)),
@@ -523,7 +530,7 @@ func (r *Resolver) reportIncomingInternetTraffic(ctx context.Context, srcIP stri
523530

524531
func (r *Resolver) handleInternalTrafficTCPResult(ctx context.Context, srcIdentity model.OtterizeServiceIdentity, dest model.Destination) {
525532
lastSeen := dest.LastSeen
526-
destIdentity, ok, err := r.resolveDestIdentity(ctx, dest, lastSeen)
533+
destIdentity, ok, err := r.resolveDestIdentityTCP(ctx, dest, lastSeen)
527534
if err != nil {
528535
logrus.WithError(err).Error("could not resolve destination identity")
529536
return

0 commit comments

Comments
 (0)