fix(secrets): Warn if OS limit for locked memory is too low (#12993)
This commit is contained in:
parent
5fdeae1ab1
commit
d8adb1edf2
|
|
@ -315,6 +315,18 @@ func (t *Telegraf) runAgent(ctx context.Context, c *config.Config, reloadConfig
|
|||
log.Printf("W! Deprecated secretstores: %d and %d options", count[0], count[1])
|
||||
}
|
||||
|
||||
// Compute the amount of locked memory needed for the secrets
|
||||
required := 2 * c.NumberSecrets * uint64(os.Getpagesize())
|
||||
available := getLockedMemoryLimit()
|
||||
if required > available {
|
||||
required /= 1024
|
||||
available /= 1024
|
||||
log.Printf("I! Found %d secrets...", c.NumberSecrets)
|
||||
msg := fmt.Sprintf("Insufficient lockable memory %dkb when %dkb is required.", available, required)
|
||||
msg += " Please increase the limit for Telegraf in your Operating System!"
|
||||
log.Printf("W! " + color.RedString(msg))
|
||||
}
|
||||
|
||||
ag := agent.NewAgent(c)
|
||||
|
||||
// Notify systemd that telegraf is ready
|
||||
|
|
|
|||
|
|
@ -2,7 +2,12 @@
|
|||
|
||||
package main
|
||||
|
||||
import "github.com/urfave/cli/v2"
|
||||
import (
|
||||
"log"
|
||||
"syscall"
|
||||
|
||||
"github.com/urfave/cli/v2"
|
||||
)
|
||||
|
||||
func (t *Telegraf) Run() error {
|
||||
stop = make(chan struct{})
|
||||
|
|
@ -12,3 +17,16 @@ func (t *Telegraf) Run() error {
|
|||
func cliFlags() []cli.Flag {
|
||||
return []cli.Flag{}
|
||||
}
|
||||
|
||||
func getLockedMemoryLimit() uint64 {
|
||||
// From https://elixir.bootlin.com/linux/latest/source/include/uapi/asm-generic/resource.h#L35
|
||||
const rLimitMemlock = 8
|
||||
|
||||
var limit syscall.Rlimit
|
||||
if err := syscall.Getrlimit(rLimitMemlock, &limit); err != nil {
|
||||
log.Printf("E! Cannot get limit for locked memory: %v", err)
|
||||
return 0
|
||||
}
|
||||
//nolint:unconvert // required for e.g. FreeBSD that has the field as int64
|
||||
return uint64(limit.Max)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -10,6 +10,7 @@ import (
|
|||
|
||||
"github.com/kardianos/service"
|
||||
"github.com/urfave/cli/v2"
|
||||
"golang.org/x/sys/windows"
|
||||
|
||||
"github.com/influxdata/telegraf/logger"
|
||||
)
|
||||
|
|
@ -45,6 +46,16 @@ func cliFlags() []cli.Flag {
|
|||
}
|
||||
}
|
||||
|
||||
func getLockedMemoryLimit() uint64 {
|
||||
handle := windows.CurrentProcess()
|
||||
|
||||
var min, max uintptr
|
||||
var flag uint32
|
||||
windows.GetProcessWorkingSetSizeEx(handle, &min, &max, &flag)
|
||||
|
||||
return uint64(max)
|
||||
}
|
||||
|
||||
func (t *Telegraf) Run() error {
|
||||
// Register the eventlog logging target for windows.
|
||||
err := logger.RegisterEventLogger(t.serviceName)
|
||||
|
|
|
|||
|
|
@ -89,6 +89,8 @@ type Config struct {
|
|||
version *semver.Version
|
||||
|
||||
Persister *persister.Persister
|
||||
|
||||
NumberSecrets uint64
|
||||
}
|
||||
|
||||
// Ordered plugins used to keep the order in which they appear in a file
|
||||
|
|
@ -471,6 +473,9 @@ func (c *Config) LoadAll(configFiles ...string) error {
|
|||
c.Agent.SnmpTranslator = "netsnmp"
|
||||
}
|
||||
|
||||
// Check if there is enough lockable memory for the secret
|
||||
c.NumberSecrets = uint64(secretCount.Load())
|
||||
|
||||
// Let's link all secrets to their secret-stores
|
||||
return c.LinkSecrets()
|
||||
}
|
||||
|
|
|
|||
|
|
@ -4,6 +4,7 @@ import (
|
|||
"fmt"
|
||||
"regexp"
|
||||
"strings"
|
||||
"sync/atomic"
|
||||
|
||||
"github.com/awnumar/memguard"
|
||||
|
||||
|
|
@ -25,6 +26,8 @@ var secretStorePattern = regexp.MustCompile(`^\w+$`)
|
|||
// in a secret-store.
|
||||
var secretPattern = regexp.MustCompile(`@\{(\w+:\w+)\}`)
|
||||
|
||||
var secretCount atomic.Int64
|
||||
|
||||
// Secret safely stores sensitive data such as a password or token
|
||||
type Secret struct {
|
||||
enclave *memguard.Enclave
|
||||
|
|
@ -60,6 +63,9 @@ func (s *Secret) UnmarshalText(b []byte) error {
|
|||
|
||||
// Initialize the secret content
|
||||
func (s *Secret) init(secret []byte) {
|
||||
// Keep track of the number of secrets...
|
||||
secretCount.Add(1)
|
||||
|
||||
// Remember if the secret is completely empty
|
||||
s.notempty = len(secret) != 0
|
||||
|
||||
|
|
@ -87,6 +93,9 @@ func (s *Secret) Destroy() {
|
|||
lockbuf.Destroy()
|
||||
}
|
||||
s.enclave = nil
|
||||
|
||||
// Keep track of the number of secrets...
|
||||
secretCount.Add(-1)
|
||||
}
|
||||
|
||||
// Empty return if the secret is completely empty
|
||||
|
|
|
|||
Loading…
Reference in New Issue