Skip to content

Commit

Permalink
[CWS] fix the hostname resolution of CWS/CSPM EvP paylods (#21061)
Browse files Browse the repository at this point in the history
* allow the logs message to override the hostname in the message

* override the CWS events hostname using the one we computed in the security agent

* fix compliance part as well

* add release note

* apply review suggestion on release note

Co-authored-by: Kari Halsted <[email protected]>

---------

Co-authored-by: Kari Halsted <[email protected]>
  • Loading branch information
paulcacheux and kayayarai authored Nov 27, 2023
1 parent d7e40ec commit c03e4cf
Show file tree
Hide file tree
Showing 12 changed files with 65 additions and 30 deletions.
10 changes: 5 additions & 5 deletions cmd/cluster-agent/subcommands/start/compliance.go
Original file line number Diff line number Diff line change
Expand Up @@ -83,19 +83,19 @@ func startCompliance(senderManager sender.SenderManager, stopper startstop.Stopp
configDir := coreconfig.Datadog.GetString("compliance_config.dir")
checkInterval := coreconfig.Datadog.GetDuration("compliance_config.check_interval")

reporter, err := compliance.NewLogReporter(stopper, "compliance-agent", "compliance", runPath, endpoints, ctx)
hname, err := hostname.Get(context.TODO())
if err != nil {
return err
}

runner := runner.NewRunner(senderManager)
stopper.Add(runner)

hname, err := hostname.Get(context.TODO())
reporter, err := compliance.NewLogReporter(hname, stopper, "compliance-agent", "compliance", runPath, endpoints, ctx)
if err != nil {
return err
}

runner := runner.NewRunner(senderManager)
stopper.Add(runner)

agent := compliance.NewAgent(senderManager, compliance.AgentOptions{
ConfigDir: configDir,
Reporter: reporter,
Expand Down
10 changes: 8 additions & 2 deletions cmd/security-agent/subcommands/check/command.go
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ import (
"github.com/DataDog/datadog-agent/pkg/compliance/k8sconfig"
pkgconfig "github.com/DataDog/datadog-agent/pkg/config"
"github.com/DataDog/datadog-agent/pkg/security/common"
"github.com/DataDog/datadog-agent/pkg/security/utils"
"github.com/DataDog/datadog-agent/pkg/util/flavor"
"github.com/DataDog/datadog-agent/pkg/util/fxutil"
"github.com/DataDog/datadog-agent/pkg/util/hostname"
Expand Down Expand Up @@ -243,15 +244,20 @@ func dumpComplianceEvents(reportFile string, events []*compliance.CheckEvent) er
return nil
}

func reportComplianceEvents(_ log.Component, config config.Component, events []*compliance.CheckEvent) error {
func reportComplianceEvents(log log.Component, config config.Component, events []*compliance.CheckEvent) error {
hostnameDetected, err := utils.GetHostnameWithContextAndFallback(context.Background())
if err != nil {
return log.Errorf("Error while getting hostname, exiting: %v", err)
}

stopper := startstop.NewSerialStopper()
defer stopper.Stop()
runPath := config.GetString("compliance_config.run_path")
endpoints, context, err := common.NewLogContextCompliance()
if err != nil {
return fmt.Errorf("reporter: could not reate log context for compliance: %w", err)
}
reporter, err := compliance.NewLogReporter(stopper, "compliance-agent", "compliance", runPath, endpoints, context)
reporter, err := compliance.NewLogReporter(hostnameDetected, stopper, "compliance-agent", "compliance", runPath, endpoints, context)
if err != nil {
return fmt.Errorf("reporter: could not create: %w", err)
}
Expand Down
11 changes: 9 additions & 2 deletions cmd/security-agent/subcommands/compliance/command.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
package compliance

import (
"context"
"fmt"
"strings"

Expand All @@ -21,6 +22,7 @@ import (
"github.com/DataDog/datadog-agent/comp/core/secrets"
"github.com/DataDog/datadog-agent/pkg/compliance"
"github.com/DataDog/datadog-agent/pkg/security/common"
"github.com/DataDog/datadog-agent/pkg/security/utils"
"github.com/DataDog/datadog-agent/pkg/util/fxutil"
"github.com/DataDog/datadog-agent/pkg/util/startstop"
)
Expand Down Expand Up @@ -79,7 +81,12 @@ func complianceEventCommand(globalParams *command.GlobalParams) *cobra.Command {
return eventCmd
}

func eventRun(_ log.Component, config config.Component, _ secrets.Component, eventArgs *cliParams) error {
func eventRun(log log.Component, config config.Component, eventArgs *cliParams) error {
hostnameDetected, err := utils.GetHostnameWithContextAndFallback(context.Background())
if err != nil {
return log.Errorf("Error while getting hostname, exiting: %v", err)
}

stopper := startstop.NewSerialStopper()
defer stopper.Stop()

Expand All @@ -89,7 +96,7 @@ func eventRun(_ log.Component, config config.Component, _ secrets.Component, eve
}

runPath := config.GetString("compliance_config.run_path")
reporter, err := compliance.NewLogReporter(stopper, eventArgs.sourceName, eventArgs.sourceType, runPath, endpoints, dstContext)
reporter, err := compliance.NewLogReporter(hostnameDetected, stopper, eventArgs.sourceName, eventArgs.sourceType, runPath, endpoints, dstContext)
if err != nil {
return fmt.Errorf("failed to set up compliance log reporter: %w", err)
}
Expand Down
2 changes: 1 addition & 1 deletion cmd/security-agent/subcommands/compliance/compliance.go
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ func StartCompliance(log log.Component, config config.Component, sysprobeconfig
}
stopper.Add(context)

reporter, err := compliance.NewLogReporter(stopper, "compliance-agent", "compliance", runPath, endpoints, context)
reporter, err := compliance.NewLogReporter(hostname, stopper, "compliance-agent", "compliance", runPath, endpoints, context)
if err != nil {
return nil, err
}
Expand Down
2 changes: 1 addition & 1 deletion cmd/security-agent/subcommands/runtime/command.go
Original file line number Diff line number Diff line change
Expand Up @@ -646,7 +646,7 @@ func StartRuntimeSecurity(log log.Component, config config.Component, hostname s
stopper.Add(ctx)

runPath := config.GetString("runtime_security_config.run_path")
reporter, err := reporter.NewCWSReporter(runPath, stopper, endpoints, ctx)
reporter, err := reporter.NewCWSReporter(hostname, runPath, stopper, endpoints, ctx)
if err != nil {
return nil, err
}
Expand Down
10 changes: 2 additions & 8 deletions cmd/security-agent/subcommands/start/command.go
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,6 @@ import (
"github.com/DataDog/datadog-agent/pkg/tagger/remote"
"github.com/DataDog/datadog-agent/pkg/util"
"github.com/DataDog/datadog-agent/pkg/util/fxutil"
"github.com/DataDog/datadog-agent/pkg/util/hostname"
"github.com/DataDog/datadog-agent/pkg/util/profiling"
"github.com/DataDog/datadog-agent/pkg/util/startstop"
"github.com/DataDog/datadog-agent/pkg/version"
Expand Down Expand Up @@ -241,15 +240,10 @@ func RunAgent(ctx context.Context, log log.Component, config config.Component, s
}
}()

hostnameDetected, err := utils.GetHostnameWithContext(ctx)
hostnameDetected, err := utils.GetHostnameWithContextAndFallback(ctx)
if err != nil {
log.Warnf("Could not resolve hostname from core-agent: %v", err)
hostnameDetected, err = hostname.Get(ctx)
if err != nil {
return log.Errorf("Error while getting hostname, exiting: %v", err)
}
return log.Errorf("Error while getting hostname, exiting: %v", err)
}
log.Infof("Hostname is: %s", hostnameDetected)
demultiplexer.AddAgentStartupTelemetry(fmt.Sprintf("%s - Datadog Security Agent", version.AgentVersion))

stopper = startstop.NewSerialStopper()
Expand Down
11 changes: 4 additions & 7 deletions pkg/compliance/reporter.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@
package compliance

import (
"context"
"encoding/json"
"fmt"
"strings"
Expand All @@ -23,25 +22,21 @@ import (
"github.com/DataDog/datadog-agent/pkg/logs/sources"
"github.com/DataDog/datadog-agent/pkg/security/common"
"github.com/DataDog/datadog-agent/pkg/status/health"
"github.com/DataDog/datadog-agent/pkg/util/hostname"
"github.com/DataDog/datadog-agent/pkg/util/log"
"github.com/DataDog/datadog-agent/pkg/util/startstop"
)

// LogReporter is responsible for sending compliance logs to DataDog backends.
type LogReporter struct {
hostname string
logSource *sources.LogSource
logChan chan *message.Message
endpoints *config.Endpoints
tags []string
}

// NewLogReporter instantiates a new log LogReporter
func NewLogReporter(stopper startstop.Stopper, sourceName, sourceType, runPath string, endpoints *config.Endpoints, dstcontext *client.DestinationsContext) (*LogReporter, error) {
hostname, err := hostname.Get(context.Background())
if err != nil || hostname == "" {
hostname = "unknown"
}
func NewLogReporter(hostname string, stopper startstop.Stopper, sourceName, sourceType, runPath string, endpoints *config.Endpoints, dstcontext *client.DestinationsContext) (*LogReporter, error) {
health := health.RegisterLiveness(sourceType)

// setup the auditor
Expand Down Expand Up @@ -79,6 +74,7 @@ func NewLogReporter(stopper startstop.Stopper, sourceName, sourceType, runPath s
}

return &LogReporter{
hostname: hostname,
logSource: logSource,
logChan: logChan,
endpoints: endpoints,
Expand All @@ -101,5 +97,6 @@ func (r *LogReporter) ReportEvent(event interface{}) {
origin := message.NewOrigin(r.logSource)
origin.SetTags(r.tags)
msg := message.NewMessage(buf, origin, message.StatusInfo, time.Now().UnixNano())
msg.Hostname = r.hostname
r.logChan <- msg
}
5 changes: 5 additions & 0 deletions pkg/logs/message/message.go
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ type Payload struct {
// Message represents a log line sent to datadog, with its metadata
type Message struct {
MessageContent
Hostname string
Origin *Origin
Status string
IngestionTimestamp int64
Expand Down Expand Up @@ -307,6 +308,10 @@ func (m *Message) GetLatency() int64 {

// GetHostname returns the hostname to applied the given log message
func (m *Message) GetHostname() string {
if m.Hostname != "" {
return m.Hostname
}

if m.Lambda != nil {
return m.Lambda.ARN
}
Expand Down
4 changes: 3 additions & 1 deletion pkg/security/module/server.go
Original file line number Diff line number Diff line change
Expand Up @@ -482,7 +482,9 @@ func newDirectReporter(stopper startstop.Stopper) (common.RawReporter, error) {
log.Info(status)
}

reporter, err := reporter.NewCWSReporter(runPath, stopper, endpoints, destinationsCtx)
// we set the hostname to the empty string to take advantage of the out of the box message hostname
// resolution
reporter, err := reporter.NewCWSReporter("", runPath, stopper, endpoints, destinationsCtx)
if err != nil {
return nil, fmt.Errorf("failed to create direct reporter: %w", err)
}
Expand Down
9 changes: 6 additions & 3 deletions pkg/security/reporter/reporter.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ import (

// RuntimeReporter represents a CWS reporter, used to send events to the intake
type RuntimeReporter struct {
hostname string
logSource *sources.LogSource
logChan chan *message.Message
}
Expand All @@ -34,15 +35,16 @@ func (r *RuntimeReporter) ReportRaw(content []byte, service string, tags ...stri
origin.SetTags(tags)
origin.SetService(service)
msg := message.NewMessage(content, origin, message.StatusInfo, time.Now().UnixNano())
msg.Hostname = r.hostname
r.logChan <- msg
}

// NewCWSReporter returns a new CWS reported based on the fields necessary to communicate with the intake
func NewCWSReporter(runPath string, stopper startstop.Stopper, endpoints *logsconfig.Endpoints, context *client.DestinationsContext) (seccommon.RawReporter, error) {
return newReporter(runPath, stopper, "runtime-security-agent", "runtime-security", endpoints, context)
func NewCWSReporter(hostname string, runPath string, stopper startstop.Stopper, endpoints *logsconfig.Endpoints, context *client.DestinationsContext) (seccommon.RawReporter, error) {
return newReporter(hostname, runPath, stopper, "runtime-security-agent", "runtime-security", endpoints, context)
}

func newReporter(runPath string, stopper startstop.Stopper, sourceName, sourceType string, endpoints *logsconfig.Endpoints, context *client.DestinationsContext) (seccommon.RawReporter, error) {
func newReporter(hostname string, runPath string, stopper startstop.Stopper, sourceName, sourceType string, endpoints *logsconfig.Endpoints, context *client.DestinationsContext) (seccommon.RawReporter, error) {
health := health.RegisterLiveness("runtime-security")

// setup the auditor
Expand All @@ -64,6 +66,7 @@ func newReporter(runPath string, stopper startstop.Stopper, sourceName, sourceTy
)
logChan := pipelineProvider.NextPipelineChan()
return &RuntimeReporter{
hostname: hostname,
logSource: logSource,
logChan: logChan,
}, nil
Expand Down
16 changes: 16 additions & 0 deletions pkg/security/utils/hostname.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import (

pbgo "github.com/DataDog/datadog-agent/pkg/proto/pbgo/core"
"github.com/DataDog/datadog-agent/pkg/util/grpc"
"github.com/DataDog/datadog-agent/pkg/util/hostname"
"github.com/DataDog/datadog-agent/pkg/util/log"
)

Expand Down Expand Up @@ -54,3 +55,18 @@ func GetHostnameWithContext(ctx context.Context) (string, error) {
}, retry.LastErrorOnly(true), retry.Attempts(maxAttempts), retry.Context(ctx))
return hostname, err
}

// GetHostnameWithContextAndFallback attempts to acquire a hostname by connecting to the
// core agent's gRPC endpoints extending the given context, or falls back to local resolution
func GetHostnameWithContextAndFallback(ctx context.Context) (string, error) {
hostnameDetected, err := GetHostnameWithContext(ctx)
if err != nil {
log.Warnf("Could not resolve hostname from core-agent: %v", err)
hostnameDetected, err = hostname.Get(ctx)
if err != nil {
return "", err
}
}
log.Infof("Hostname is: %s", hostnameDetected)
return hostnameDetected, nil
}
5 changes: 5 additions & 0 deletions releasenotes/notes/csm-events-hostname-42359b25de381a90.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
fixes:
- |
CWS/CSPM: Fixes the hostname value attached to CWS and CSPM events, which in rare cases
the security agent computed incorrectly.

0 comments on commit c03e4cf

Please sign in to comment.