Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 14 additions & 0 deletions docs/reference/auditbeat/processor-dns.md
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,13 @@ The `dns` processor has the following configuration settings:
`success_cache.min_ttl`
: The duration of the minimum alternative cache TTL for successful DNS responses. Ensures that `TTL=0` successful reverse DNS responses can be cached. Valid time units are "ns", "us" (or "µs"), "ms", "s", "m", "h". Default value is `1m`.

`success_cache.enabled`
: Whether the success cache should be enabled. The default value is `true`, meaning the cache is used by default.

::::{note}
Disabling the cache has throughput implications, requiring each event to perform a round trip to the DNS server. For example, if a DNS lookup takes 1 ms, serial throughput is limited to a maximum of 1,000 events per second.
::::

`failure_cache.capacity.initial`
: The initial number of items that the failure cache will be allocated to hold. When initialized the processor will allocate the memory for this number of items. Default value is `1000`.

Expand All @@ -88,6 +95,13 @@ The `dns` processor has the following configuration settings:
`failure_cache.ttl`
: The duration for which failures are cached. Valid time units are "ns", "us" (or "µs"), "ms", "s", "m", "h". Default value is `1m`.

`failure_cache.enabled`
: Whether the failure cache should be enabled. The default value is `true`, meaning the cache is used by default.

::::{note}
Disabling the cache has throughput implications, requiring each event to perform a round trip to the DNS server. For example, if a DNS lookup takes 1 ms, serial throughput is limited to a maximum of 1,000 events per second. Additionally, if the failure occurs because the server is overloaded, retrying immediately might have compounding effects.
::::

`nameservers`
: A list of nameservers to query. If there are multiple servers, the resolver queries them in the order listed. If none are specified then it will read the nameservers listed in `/etc/resolv.conf` once at initialization. On Windows you must always supply at least one nameserver.

Expand Down
14 changes: 14 additions & 0 deletions docs/reference/filebeat/processor-dns.md
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,13 @@ The `dns` processor has the following configuration settings:
`success_cache.min_ttl`
: The duration of the minimum alternative cache TTL for successful DNS responses. Ensures that `TTL=0` successful reverse DNS responses can be cached. Valid time units are "ns", "us" (or "µs"), "ms", "s", "m", "h". Default value is `1m`.

`success_cache.enabled`
: Whether the success cache should be enabled. The default value is `true`, meaning the cache is used by default.

::::{note}
Disabling the cache has throughput implications, requiring each event to perform a round trip to the DNS server. For example, if a DNS lookup takes 1 ms, serial throughput is limited to a maximum of 1,000 events per second.
::::

`failure_cache.capacity.initial`
: The initial number of items that the failure cache will be allocated to hold. When initialized the processor will allocate the memory for this number of items. Default value is `1000`.

Expand All @@ -88,6 +95,13 @@ The `dns` processor has the following configuration settings:
`failure_cache.ttl`
: The duration for which failures are cached. Valid time units are "ns", "us" (or "µs"), "ms", "s", "m", "h". Default value is `1m`.

`failure_cache.enabled`
: Whether the failure cache should be enabled. The default value is `true`, meaning the cache is used by default.

::::{note}
Disabling the cache has throughput implications, requiring each event to perform a round trip to the DNS server. For example, if a DNS lookup takes 1 ms, serial throughput is limited to a maximum of 1,000 events per second. Additionally, if the failure occurs because the server is overloaded, retrying immediately might have compounding effects.
::::

`nameservers`
: A list of nameservers to query. If there are multiple servers, the resolver queries them in the order listed. If none are specified then it will read the nameservers listed in `/etc/resolv.conf` once at initialization. On Windows you must always supply at least one nameserver.

Expand Down
14 changes: 14 additions & 0 deletions docs/reference/heartbeat/processor-dns.md
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,13 @@ The `dns` processor has the following configuration settings:
`success_cache.min_ttl`
: The duration of the minimum alternative cache TTL for successful DNS responses. Ensures that `TTL=0` successful reverse DNS responses can be cached. Valid time units are "ns", "us" (or "µs"), "ms", "s", "m", "h". Default value is `1m`.

`success_cache.enabled`
: Whether the success cache should be enabled. The default value is `true`, meaning the cache is used by default.

::::{note}
Disabling the cache has throughput implications, requiring each event to perform a round trip to the DNS server. For example, if a DNS lookup takes 1 ms, serial throughput is limited to a maximum of 1,000 events per second.
::::

`failure_cache.capacity.initial`
: The initial number of items that the failure cache will be allocated to hold. When initialized the processor will allocate the memory for this number of items. Default value is `1000`.

Expand All @@ -88,6 +95,13 @@ The `dns` processor has the following configuration settings:
`failure_cache.ttl`
: The duration for which failures are cached. Valid time units are "ns", "us" (or "µs"), "ms", "s", "m", "h". Default value is `1m`.

`failure_cache.enabled`
: Whether the failure cache should be enabled. The default value is `true`, meaning the cache is used by default.

::::{note}
Disabling the cache has throughput implications, requiring each event to perform a round trip to the DNS server. For example, if a DNS lookup takes 1 ms, serial throughput is limited to a maximum of 1,000 events per second. Additionally, if the failure occurs because the server is overloaded, retrying immediately might have compounding effects.
::::

`nameservers`
: A list of nameservers to query. If there are multiple servers, the resolver queries them in the order listed. If none are specified then it will read the nameservers listed in `/etc/resolv.conf` once at initialization. On Windows you must always supply at least one nameserver.

Expand Down
14 changes: 14 additions & 0 deletions docs/reference/metricbeat/processor-dns.md
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,13 @@ The `dns` processor has the following configuration settings:
`success_cache.min_ttl`
: The duration of the minimum alternative cache TTL for successful DNS responses. Ensures that `TTL=0` successful reverse DNS responses can be cached. Valid time units are "ns", "us" (or "µs"), "ms", "s", "m", "h". Default value is `1m`.

`success_cache.enabled`
: Whether the success cache should be enabled. The default value is `true`, meaning the cache is used by default.

::::{note}
Disabling the cache has throughput implications, requiring each event to perform a round trip to the DNS server. For example, if a DNS lookup takes 1 ms, serial throughput is limited to a maximum of 1,000 events per second.
::::

`failure_cache.capacity.initial`
: The initial number of items that the failure cache will be allocated to hold. When initialized the processor will allocate the memory for this number of items. Default value is `1000`.

Expand All @@ -88,6 +95,13 @@ The `dns` processor has the following configuration settings:
`failure_cache.ttl`
: The duration for which failures are cached. Valid time units are "ns", "us" (or "µs"), "ms", "s", "m", "h". Default value is `1m`.

`failure_cache.enabled`
: Whether the failure cache should be enabled. The default value is `true`, meaning the cache is used by default.

::::{note}
Disabling the cache has throughput implications, requiring each event to perform a round trip to the DNS server. For example, if a DNS lookup takes 1 ms, serial throughput is limited to a maximum of 1,000 events per second. Additionally, if the failure occurs because the server is overloaded, retrying immediately might have compounding effects.
::::

`nameservers`
: A list of nameservers to query. If there are multiple servers, the resolver queries them in the order listed. If none are specified then it will read the nameservers listed in `/etc/resolv.conf` once at initialization. On Windows you must always supply at least one nameserver.

Expand Down
14 changes: 14 additions & 0 deletions docs/reference/packetbeat/processor-dns.md
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,13 @@ The `dns` processor has the following configuration settings:
`success_cache.min_ttl`
: The duration of the minimum alternative cache TTL for successful DNS responses. Ensures that `TTL=0` successful reverse DNS responses can be cached. Valid time units are "ns", "us" (or "µs"), "ms", "s", "m", "h". Default value is `1m`.

`success_cache.enabled`
: Whether the success cache should be enabled. The default value is `true`, meaning the cache is used by default.

::::{note}
Disabling the cache has throughput implications, requiring each event to perform a round trip to the DNS server. For example, if a DNS lookup takes 1 ms, serial throughput is limited to a maximum of 1,000 events per second.
::::

`failure_cache.capacity.initial`
: The initial number of items that the failure cache will be allocated to hold. When initialized the processor will allocate the memory for this number of items. Default value is `1000`.

Expand All @@ -88,6 +95,13 @@ The `dns` processor has the following configuration settings:
`failure_cache.ttl`
: The duration for which failures are cached. Valid time units are "ns", "us" (or "µs"), "ms", "s", "m", "h". Default value is `1m`.

`failure_cache.enabled`
: Whether the failure cache should be enabled. The default value is `true`, meaning the cache is used by default.

::::{note}
Disabling the cache has throughput implications, requiring each event to perform a round trip to the DNS server. For example, if a DNS lookup takes 1 ms, serial throughput is limited to a maximum of 1,000 events per second. Additionally, if the failure occurs because the server is overloaded, retrying immediately might have compounding effects.
::::

`nameservers`
: A list of nameservers to query. If there are multiple servers, the resolver queries them in the order listed. If none are specified then it will read the nameservers listed in `/etc/resolv.conf` once at initialization. On Windows you must always supply at least one nameserver.

Expand Down
14 changes: 14 additions & 0 deletions docs/reference/winlogbeat/processor-dns.md
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,13 @@ The `dns` processor has the following configuration settings:
`success_cache.min_ttl`
: The duration of the minimum alternative cache TTL for successful DNS responses. Ensures that `TTL=0` successful reverse DNS responses can be cached. Valid time units are "ns", "us" (or "µs"), "ms", "s", "m", "h". Default value is `1m`.

`success_cache.enabled`
: Whether the success cache should be enabled. The default value is `true`, meaning the cache is used by default.

::::{note}
Disabling the cache has throughput implications, requiring each event to perform a round trip to the DNS server. For example, if a DNS lookup takes 1 ms, serial throughput is limited to a maximum of 1,000 events per second.
::::

`failure_cache.capacity.initial`
: The initial number of items that the failure cache will be allocated to hold. When initialized the processor will allocate the memory for this number of items. Default value is `1000`.

Expand All @@ -88,6 +95,13 @@ The `dns` processor has the following configuration settings:
`failure_cache.ttl`
: The duration for which failures are cached. Valid time units are "ns", "us" (or "µs"), "ms", "s", "m", "h". Default value is `1m`.

`failure_cache.enabled`
: Whether the failure cache should be enabled. The default value is `true`, meaning the cache is used by default.

::::{note}
Disabling the cache has throughput implications, requiring each event to perform a round trip to the DNS server. For example, if a DNS lookup takes 1 ms, serial throughput is limited to a maximum of 1,000 events per second. Additionally, if the failure occurs because the server is overloaded, retrying immediately might have compounding effects.
::::

`nameservers`
: A list of nameservers to query. If there are multiple servers, the resolver queries them in the order listed. If none are specified then it will read the nameservers listed in `/etc/resolv.conf` once at initialization. On Windows you must always supply at least one nameserver.

Expand Down
30 changes: 28 additions & 2 deletions libbeat/processors/dns/cache.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
package dns

import (
"math"
"sync"
"time"

Expand All @@ -34,13 +35,17 @@ func (r successRecord) IsExpired(now time.Time) bool {
}

type successCache struct {
enabled bool
sync.RWMutex
data map[string]successRecord
maxSize int
minSuccessTTL time.Duration
}

func (c *successCache) set(now time.Time, key string, result *result) {
if !c.enabled {
return
}
c.Lock()
defer c.Unlock()

Expand All @@ -65,12 +70,15 @@ func (c *successCache) evict() {
}

func (c *successCache) get(now time.Time, key string) *result {
if !c.enabled {
return nil
}
c.RLock()
defer c.RUnlock()

r, found := c.data[key]
if found && !r.IsExpired(now) {
return &result{r.data, uint32(r.expires.Sub(now) / time.Second)}
return &result{r.data, safeUint32(r.expires.Sub(now).Seconds())}
}
return nil
}
Expand All @@ -85,13 +93,17 @@ func (r failureRecord) IsExpired(now time.Time) bool {
}

type failureCache struct {
enabled bool
sync.RWMutex
data map[string]failureRecord
maxSize int
failureTTL time.Duration
}

func (c *failureCache) set(now time.Time, key string, err error) {
if !c.enabled {
return
}
c.Lock()
defer c.Unlock()
if len(c.data) >= c.maxSize {
Expand All @@ -115,6 +127,9 @@ func (c *failureCache) evict() {
}

func (c *failureCache) get(now time.Time, key string) error {
if !c.enabled {
return nil
}
c.RLock()
defer c.RUnlock()

Expand Down Expand Up @@ -155,11 +170,13 @@ func newLookupCache(reg *monitoring.Registry, conf cacheConfig, resolver resolve

c := &lookupCache{
success: &successCache{
enabled: conf.FailureCache.Enabled,
data: make(map[string]successRecord, conf.SuccessCache.InitialCapacity),
maxSize: conf.SuccessCache.MaxCapacity,
minSuccessTTL: conf.SuccessCache.MinTTL,
},
failure: &failureCache{
enabled: conf.FailureCache.Enabled,
data: make(map[string]failureRecord, conf.FailureCache.InitialCapacity),
maxSize: conf.FailureCache.MaxCapacity,
failureTTL: conf.FailureCache.TTL,
Expand Down Expand Up @@ -200,7 +217,7 @@ func (c lookupCache) Lookup(q string, qt queryType) (*result, error) {
}

// We set the result TTL to the minimum TTL in case it is less than that.
r.TTL = max(r.TTL, uint32(c.success.minSuccessTTL/time.Second))
r.TTL = max(r.TTL, safeUint32(c.success.minSuccessTTL.Seconds()))

c.success.set(now, q, r)
return r, nil
Expand All @@ -212,3 +229,12 @@ func max(a, b uint32) uint32 {
}
return b
}

// safeUint32 converts a float64 to a uint32, protecting against out-of-bounds
// values. It takes the absolute value to prevent negative numbers and caps the
// result at math.MaxUint32 to avoid integer overflows.
//
// This function is used to satisfy the gosec security scanner rule G115.
func safeUint32(float float64) uint32 {
return uint32(math.Min(math.Abs(float), float64(math.MaxUint32)))
}
29 changes: 28 additions & 1 deletion libbeat/processors/dns/cache_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -101,7 +101,7 @@ func TestCache(t *testing.T) {
assert.EqualValues(t, 3, c.stats.Miss.Get()) // Cache miss.
}

minTTL := defaultConfig().cacheConfig.SuccessCache.MinTTL
minTTL := defaultConfig().SuccessCache.MinTTL
// Initial success returned TTL=0 with MinTTL.
r, err = c.Lookup(gatewayIP+"2", typePTR)
if assert.NoError(t, err) {
Expand All @@ -126,3 +126,30 @@ func TestCache(t *testing.T) {
assert.EqualValues(t, 4, c.stats.Miss.Get())
}
}

func TestDisabledCache(t *testing.T) {
config := defaultConfig().cacheConfig
config.SuccessCache.Enabled = false
config.FailureCache.Enabled = false

c, err := newLookupCache(
monitoring.NewRegistry(),
config,
&stubResolver{})
if err != nil {
t.Fatal(err)
}

// Initial success query.
var r *result
r, err = c.Lookup(gatewayIP, typePTR)
if assert.NoError(t, err) {
assert.EqualValues(t, []string{gatewayName}, r.Data)
}
r, err = c.Lookup(gatewayIP, typePTR)
if assert.NoError(t, err) {
assert.EqualValues(t, []string{gatewayName}, r.Data)
assert.EqualValues(t, 0, c.stats.Hit.Get())
assert.EqualValues(t, 2, c.stats.Miss.Get())
}
}
5 changes: 5 additions & 0 deletions libbeat/processors/dns/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -120,6 +120,9 @@ type cacheConfig struct {

// cacheSettings define the caching behavior for an individual cache.
type cacheSettings struct {
// Disable the use of the cache.
Enabled bool `config:"enabled"`

// TTL value for items in cache. Not used for success because we use TTL
// from the DNS record.
TTL time.Duration `config:"ttl"`
Expand Down Expand Up @@ -189,11 +192,13 @@ func defaultConfig() config {
return config{
cacheConfig: cacheConfig{
SuccessCache: cacheSettings{
Enabled: true,
MinTTL: time.Minute,
InitialCapacity: 1000,
MaxCapacity: 10000,
},
FailureCache: cacheSettings{
Enabled: true,
MinTTL: time.Minute,
TTL: time.Minute,
InitialCapacity: 1000,
Expand Down
14 changes: 7 additions & 7 deletions libbeat/processors/dns/dns_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ func TestDNSProcessorRun(t *testing.T) {
resolver: &stubResolver{},
log: logptest.NewTestingLogger(t, logName),
}
p.config.reverseFlat = map[string]string{
p.reverseFlat = map[string]string{
"source.ip": "source.domain",
}
t.Log(p.String())
Expand All @@ -60,7 +60,7 @@ func TestDNSProcessorRun(t *testing.T) {

const forwardDomain = "www." + gatewayName
t.Run("append", func(t *testing.T) {
p.config.Action = actionAppend
p.Action = actionAppend

event, err := p.Run(&beat.Event{
Fields: mapstr.M{
Expand All @@ -79,7 +79,7 @@ func TestDNSProcessorRun(t *testing.T) {
})

t.Run("replace", func(t *testing.T) {
p.config.Action = actionReplace
p.Action = actionReplace

event, err := p.Run(&beat.Event{
Fields: mapstr.M{
Expand Down Expand Up @@ -132,8 +132,8 @@ func TestDNSProcessorTagOnFailure(t *testing.T) {
resolver: &stubResolver{},
log: logptest.NewTestingLogger(t, logName),
}
p.config.TagOnFailure = []string{"_lookup_failed"}
p.config.reverseFlat = map[string]string{
p.TagOnFailure = []string{"_lookup_failed"}
p.reverseFlat = map[string]string{
"source.ip": "source.domain",
"destination.ip": "destination.domain",
}
Expand All @@ -151,7 +151,7 @@ func TestDNSProcessorTagOnFailure(t *testing.T) {

v, _ := event.GetValue("tags")
if assert.Len(t, v, 1) {
assert.ElementsMatch(t, v, p.config.TagOnFailure)
assert.ElementsMatch(t, v, p.TagOnFailure)
}
}

Expand All @@ -166,7 +166,7 @@ func TestDNSProcessorRunInParallel(t *testing.T) {
t.Fatal(err)
}
p := &processor{config: conf, resolver: cache, log: logptest.NewTestingLogger(t, logName)}
p.config.reverseFlat = map[string]string{"source.ip": "source.domain"}
p.reverseFlat = map[string]string{"source.ip": "source.domain"}

const numGoroutines = 10
const numEvents = 500
Expand Down
Loading