diff --git a/go.mod b/go.mod index 7d856d1c1..9d056b2bd 100644 --- a/go.mod +++ b/go.mod @@ -63,6 +63,7 @@ require ( github.com/coocood/freecache v1.2.3 github.com/coreos/go-semver v0.3.1 github.com/coreos/go-systemd v0.0.0-20190719114852-fd7a80b32e1f + github.com/coreos/go-systemd/v22 v22.5.0 github.com/couchbase/go-couchbase v0.1.1 github.com/digitalocean/go-libvirt v0.0.0-20220811165305-15feff002086 github.com/dimchansky/utfbom v1.1.1 @@ -321,6 +322,7 @@ require ( github.com/goburrow/serial v0.1.1-0.20211022031912-bfb69110f8dd // indirect github.com/goccy/go-json v0.10.2 // indirect github.com/godbus/dbus v0.0.0-20190726142602-4481cbc300e2 // indirect + github.com/godbus/dbus/v5 v5.1.0 // indirect github.com/gofrs/uuid v4.2.0+incompatible // indirect github.com/gogo/protobuf v1.3.2 // indirect github.com/golang-jwt/jwt/v4 v4.5.0 // indirect diff --git a/go.sum b/go.sum index 2480536c9..bea8d6734 100644 --- a/go.sum +++ b/go.sum @@ -1029,6 +1029,8 @@ github.com/coreos/go-systemd v0.0.0-20190321100706-95778dfbb74e/go.mod h1:F5haX7 github.com/coreos/go-systemd v0.0.0-20190719114852-fd7a80b32e1f h1:JOrtw2xFKzlg+cbHpyrpLDmnN1HqhBfnX7WDiW7eG2c= github.com/coreos/go-systemd v0.0.0-20190719114852-fd7a80b32e1f/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4= github.com/coreos/go-systemd/v22 v22.3.2/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSVTIJ3seZv2GcEnc= +github.com/coreos/go-systemd/v22 v22.5.0 h1:RrqgGjYQKalulkV8NGVIfkXQf6YYmOyiJKk8iXXhfZs= +github.com/coreos/go-systemd/v22 v22.5.0/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSVTIJ3seZv2GcEnc= github.com/coreos/pkg v0.0.0-20180928190104-399ea9e2e55f/go.mod h1:E3G3o1h8I7cfcXa63jLwjI0eiQQMgzzUDFVpN/nH/eA= github.com/couchbase/go-couchbase v0.1.1 h1:ClFXELcKj/ojyoTYbsY34QUrrYCBi/1G749sXSCkdhk= github.com/couchbase/go-couchbase v0.1.1/go.mod h1:+/bddYDxXsf9qt0xpDUtRR47A2GjaXmGGAqQ/k3GJ8A= @@ -1234,6 +1236,8 @@ github.com/godbus/dbus v0.0.0-20190726142602-4481cbc300e2 h1:ZpnhV/YsD2/4cESfV5+ github.com/godbus/dbus v0.0.0-20190726142602-4481cbc300e2/go.mod h1:bBOAhwG1umN6/6ZUMtDFBMQR8jRg9O75tm9K00oMsK4= github.com/godbus/dbus/v5 v5.0.4/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA= github.com/godbus/dbus/v5 v5.0.6/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA= +github.com/godbus/dbus/v5 v5.1.0 h1:4KLkAxT3aOY8Li4FRJe/KvhoNFFxo0m6fNuFUO8QJUk= +github.com/godbus/dbus/v5 v5.1.0/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA= github.com/gofrs/uuid v3.3.0+incompatible/go.mod h1:b2aQJv3Z4Fp6yNu3cdSllBxTCLRxnplIgP/c0N/04lM= github.com/gofrs/uuid v4.0.0+incompatible/go.mod h1:b2aQJv3Z4Fp6yNu3cdSllBxTCLRxnplIgP/c0N/04lM= github.com/gofrs/uuid v4.2.0+incompatible h1:yyYWMnhkhrKwwr8gAOcOCYxOOscHgDS9yZgBrnJfGa0= diff --git a/plugins/secretstores/README.md b/plugins/secretstores/README.md index 32ddb0968..891d7a30f 100644 --- a/plugins/secretstores/README.md +++ b/plugins/secretstores/README.md @@ -6,5 +6,6 @@ This folder contains the plugins for the secret-store functionality: * http: Query secrets from an HTTP endpoint * jose: Javascript Object Signing and Encryption * os: Native tooling provided on Linux, MacOS, or Windows. +* systemd: Secret-store to access systemd secrets See each plugin's README for additional details. diff --git a/plugins/secretstores/all/systemd.go b/plugins/secretstores/all/systemd.go new file mode 100644 index 000000000..a8fcf6385 --- /dev/null +++ b/plugins/secretstores/all/systemd.go @@ -0,0 +1,5 @@ +//go:build !custom || secretstores || secretstores.systemd + +package all + +import _ "github.com/influxdata/telegraf/plugins/secretstores/systemd" // register plugin diff --git a/plugins/secretstores/systemd/README.md b/plugins/secretstores/systemd/README.md new file mode 100644 index 000000000..eaf14f4e1 --- /dev/null +++ b/plugins/secretstores/systemd/README.md @@ -0,0 +1,246 @@ + +# Systemd Secret-Store Plugin + +The `systemd` plugin allows utilizing credentials and secrets provided by +[systemd][] to the Telegraf service. Systemd ensures that only the intended +service can access the credentials for the lifetime of this service. The +credentials appear as plaintext files to the consuming service but are stored +encrypted on the host system. This encryption can also use TPM2 protection if +available (see [this article][systemd-descr] for details). + +This plugin does not support setting the credentials. See the +[credentials management section](#credential-management) below for how to +setup systemd credentials and how to add credentials + +**Note**: Secrets of this plugin are static and are not updated after startup. + +## Requirements and caveats + +This plugin requires **systemd version 250+** with correctly set-up credentials +via [systemd-creds][] (see [setup section](#credential-management)). +However, to use `ImportCredential`, as done in the default service file, you +need **systemd version 254+** otherwise you need to specify the credentials +using `LoadCredentialEncrypted` in a service-override. + +In the default setup, Telegraf expects credential files to be prefixed with +`telegraf.` and without a custom name setting (i.e. no `--name`). + +It is important to note that when TPM2 sealing is available on the host, +credentials can only be created and used on the **same machine** as decrypting +the secrets requires the encryption key *and* a key stored in TPM2. Therefore, +creating credentials and then copying it to another machine will fail! + +Please be aware that, due to its nature, this plugin is **ONLY** available +when started as a service. It does **NOT** find any credentials when started +manually via the command line! Therefore, `secrets` commands should **not** +be used with this plugin. + +## Usage + +Secrets defined by a store are referenced with `@{:}` +the Telegraf configuration. Only certain Telegraf plugins and options of +support secret stores. To see which plugins and options support +secrets, see their respective documentation (e.g. +`plugins/outputs/influxdb/README.md`). If the plugin's README has the +`Secret-store support` section, it will detail which options support secret +store usage. + +## Configuration + +```toml @sample.conf +# Secret-store to access systemd secrets +[[secretstores.systemd]] + ## Unique identifier for the secretstore. + ## This id can later be used in plugins to reference the secrets + ## in this secret-store via @{:} (mandatory) + id = "systemd" + + ## Path to systemd credentials directory + ## This should not be required as systemd indicates this directory + ## via the CREDENTIALS_DIRECTORY environment variable. + # path = "${CREDENTIALS_DIRECTORY}" + + ## Prefix to remove from systemd credential-filenames to derive secret names + # prefix = "telegraf." + +``` + +Each Secret provided by systemd will be available as file under +`${CREDENTIALS_DIRECTORY}/` for the service. You will **not** be +able to see them as a regular, non-telegraf user. Credential visibility from +other systemd services is mediated by the `User=` and `PrivateMounts=` +service-unit directives for those services. See the +[systemd.exec man-page][systemd-exec] for details. + +## Credential management + +Most steps here are condensed from the [systemd-creds man-page][systemd-creds] +and are using this command. Please also check that man-page as the options +or verbs used here might be outdated for the systemd version you are using. + +**Please note**: We are using `/etc/credstore.encrypted` as our storage +location for encrypted credentials throughout the examples below and assuming +a Telegraf install via package manager. If you are using some other means to +install Telegraf you might need to create that directory. +Furthermore, we assume the secret-store ID to be set to `systemd` in the +examples. + +Setting up systemd-credentials might vary on your distribution or version so +please also check the documentation there. You might also need to install +supporting packages such as `tpm2-tools`. + +### Setup + +If you have not done it already, systemd requires a first-time setup of the +credential system. If you are planning to use the TPM2 chip of your system +for protecting the credentials, you should first make sure that it is +available using + +```shell +sudo systemd-creds has-tpm2 +``` + +The output should look similar to + +```text +partial +-firmware ++driver ++system ++subsystem +``` + +If TPM2 is available on your system, credentials can also be tied to the device +by utilizing TPM2 sealing. See the [systemd-creds man-page][systemd-creds] for +details. + +Now setup the credentials by creating the root key. + +```shell +sudo systemd-creds setup +``` + +A warning may appears if you are storing the generated key on an unencrypted +disk which is not recommended. With this, we are all set to create credentials. + +### Creating credentials + +After setting up the encryption key we can create a new credential using + +```shell +echo -n "john-doe-jr" | sudo systemd-creds encrypt - /etc/credstore.encrypted/telegraf.http_user +``` + +You should now have a file named `telegraf.http_user` containing the encrypted +username. The secret-store later provides the secret using this filename as the +secret's key. +**Please note:**: By default Telegraf strips the `telegraf.` prefix. If you use +a different prefix or no prefix at all you need to adapt the `prefix` setting! + +We can now add more secrets. To avoid potentially leaking the plain-text +credentials through command-history or showing it on the screen we use + +```shell +systemd-ask-password -n | sudo systemd-creds encrypt - /etc/credstore.encrypted/telegraf.http_password +``` + +to interactively enter the password. + +### Using credentials as secrets + +To use the credentials as secrets you need to first instantiate a `systemd` +secret-store by adding + +```toml +[[secretstores.systemd]] + id = "systemd" +``` + +to your Telegraf configuration. Assuming the two example credentials +`http_user` and `http_password` you can now use those as secrets via + +```toml +[[inputs.http]] + urls = ["http://localhost/metrics"] + username = "@{systemd:http_user}" + password = "@{systemd:http_password}" + +``` + +in your plugins. + +### Chaining for unattended start + +When using many secrets or when secrets need to be shared among hosts, listing +all of them in the service file might be cumbersome. Additionally, it is hard +to manually test Telegraf configurations with the `systemd` secret-store as +those secrets are only available when started as a service. + +Here, secret-store chaining comes into play, denoting a setup where one +secret-store, in our case `secretstores.systemd`, is used to unlock another +secret-store (`secretstores.jose` in this example). + +```toml +[[secretstores.systemd]] + id = "systemd" + +[[secretstores.jose]] + id = "mysecrets" + path = "/etc/telegraf/secrets" + password = "@{systemd:initial}" +``` + +Here we assume that an `initial` credential was injected through the service +file. This `initial` secret is then used to unlock the `jose` secret-store +which might provide many different secrets backed by encrypted files. + +Input and output plugins can the use the `jose` secrets (via `@{mysecrets:...}`) +to fill sensitive data such as usernames, passwords or tokens. + +### Troubleshooting + +Please always make sure your systemd version matches Telegraf's requirements, +i.e. you do have version 254 or later. + +When not being able to start the service please check the logs. A common issue +is using the `--name` option which does not work with systemd's +`ImportCredential` setting. +a mismatch between the name stored in the credential (given during +`systemd-creds encrypt`) and the one used in the +`LoadCredentialEncrypted` statement. + +In case you are having trouble referencing credentials in Telegraf, you should +check what is available via + +```shell +CREDENTIALS_DIRECTORY=/etc/credstore.encrypted sudo systemd-creds list +``` + +for the example above you should see + +```text +NAME SECURE SIZE PATH +------------------------------------------------------------------- +telegraf.http_password insecure 146B /etc/credstore.encrypted/telegraf.http_password +telegraf.http_user insecure 142B /etc/credstore.encrypted/telegraf.http_user +``` + +**Please note**: Telegraf's secret management functionality is not helpful here +as credentials are *only* available to the systemd service, not via commandline. + +Remember to remove the `prefix` configured in your secret-store from the `NAME` +column to get the secrets' `key`. + +To get the actual value of a credential use + +```shell +sudo systemd-creds decrypt /etc/credstore.encrypted/telegraf.http_password - +``` + +Please use the above command(s) with care as they do reveal the secret value +of the credential! + +[systemd]: https://www.freedesktop.org/wiki/Software/systemd/ +[systemd-descr]: https://systemd.io/CREDENTIALS +[systemd-creds]: https://www.freedesktop.org/software/systemd/man/systemd-creds.html +[systemd-exec]: https://www.freedesktop.org/software/systemd/man/systemd.exec.html diff --git a/plugins/secretstores/systemd/sample.conf b/plugins/secretstores/systemd/sample.conf new file mode 100644 index 000000000..d2b2c7b19 --- /dev/null +++ b/plugins/secretstores/systemd/sample.conf @@ -0,0 +1,15 @@ +# Secret-store to access systemd secrets +[[secretstores.systemd]] + ## Unique identifier for the secretstore. + ## This id can later be used in plugins to reference the secrets + ## in this secret-store via @{:} (mandatory) + id = "systemd" + + ## Path to systemd credentials directory + ## This should not be required as systemd indicates this directory + ## via the CREDENTIALS_DIRECTORY environment variable. + # path = "${CREDENTIALS_DIRECTORY}" + + ## Prefix to remove from systemd credential-filenames to derive secret names + # prefix = "telegraf." + diff --git a/plugins/secretstores/systemd/systemd.go b/plugins/secretstores/systemd/systemd.go new file mode 100644 index 000000000..005edb039 --- /dev/null +++ b/plugins/secretstores/systemd/systemd.go @@ -0,0 +1,138 @@ +//go:build linux + +//go:generate ../../../tools/readme_config_includer/generator +package systemd + +import ( + "context" + _ "embed" + "errors" + "fmt" + "os" + "path/filepath" + "strconv" + "strings" + + "github.com/coreos/go-systemd/v22/dbus" + "github.com/influxdata/telegraf" + "github.com/influxdata/telegraf/plugins/secretstores" +) + +const systemdMinimumVersion = 250 + +// Required to be a variable to mock the version in tests +var getSystemdVersion = getSystemdMajorVersion + +//go:embed sample.conf +var sampleConfig string + +type Systemd struct { + Path string `toml:"path"` + Prefix string `toml:"prefix"` + Log telegraf.Logger `toml:"-"` +} + +func (*Systemd) SampleConfig() string { + return sampleConfig +} + +// Init initializes all internals of the secret-store +func (s *Systemd) Init() error { + version, err := getSystemdVersion() + if err != nil { + return fmt.Errorf("unable to detect systemd version: %w", err) + } + s.Log.Debugf("Found systemd version %d...", version) + if version < systemdMinimumVersion { + return fmt.Errorf("systemd version %d below minimum version %d", version, systemdMinimumVersion) + } + + // By default the credentials directory is passed in by systemd + // via the "CREDENTIALS_DIRECTORY" environment variable. + defaultPath := os.Getenv("CREDENTIALS_DIRECTORY") + if defaultPath == "" { + s.Log.Warn("CREDENTIALS_DIRECTORY environment variable undefined. Make sure credentials are setup correctly!") + if s.Path == "" { + return errors.New("'path' required without CREDENTIALS_DIRECTORY") + } + } + + // Use default path if no explicit was specified. This should be the common case. + if s.Path == "" { + s.Path = defaultPath + } + s.Path, err = filepath.Abs(s.Path) + if err != nil { + return fmt.Errorf("cannot determine absolute path of %q: %w", s.Path, err) + } + + // Check if we can access the target directory + if _, err := os.Stat(s.Path); err != nil { + return fmt.Errorf("accessing credentials directory %q failed: %w", s.Path, err) + } + return nil +} + +func (s *Systemd) Get(key string) ([]byte, error) { + secretFile, err := filepath.Abs(filepath.Join(s.Path, s.Prefix+key)) + if err != nil { + return nil, err + } + if filepath.Dir(secretFile) != s.Path { + return nil, fmt.Errorf("invalid directory detected for key %q", key) + } + value, err := os.ReadFile(secretFile) + if err != nil { + return nil, fmt.Errorf("cannot read the secret's value: %w", err) + } + return value, nil +} + +func (s *Systemd) List() ([]string, error) { + secretFiles, err := os.ReadDir(s.Path) + if err != nil { + return nil, fmt.Errorf("cannot read files: %w", err) + } + secrets := make([]string, 0, len(secretFiles)) + for _, entry := range secretFiles { + key := strings.TrimPrefix(entry.Name(), s.Prefix) + secrets = append(secrets, key) + } + return secrets, nil +} + +func (s *Systemd) Set(_, _ string) error { + return errors.New("secret-store does not support creating secrets") +} + +// GetResolver returns a function to resolve the given key. +func (s *Systemd) GetResolver(key string) (telegraf.ResolveFunc, error) { + resolver := func() ([]byte, bool, error) { + s, err := s.Get(key) + return s, false, err + } + return resolver, nil +} + +func getSystemdMajorVersion() (int, error) { + ctx := context.Background() + conn, err := dbus.NewWithContext(ctx) + if err != nil { + return 0, err + } + defer conn.Close() + + fullVersion, err := conn.GetManagerProperty("Version") + if err != nil { + return 0, err + } + fullVersion = strings.Trim(fullVersion, "\"") + return strconv.Atoi(strings.SplitN(fullVersion, ".", 2)[0]) +} + +// Register the secret-store on load. +func init() { + secretstores.Add("systemd", func(_ string) telegraf.SecretStore { + return &Systemd{Prefix: "telegraf."} + }) +} diff --git a/plugins/secretstores/systemd/systemd_nonlinux.go b/plugins/secretstores/systemd/systemd_nonlinux.go new file mode 100644 index 000000000..728b12359 --- /dev/null +++ b/plugins/secretstores/systemd/systemd_nonlinux.go @@ -0,0 +1 @@ +package systemd diff --git a/plugins/secretstores/systemd/systemd_test.go b/plugins/secretstores/systemd/systemd_test.go new file mode 100644 index 000000000..88f9a6bad --- /dev/null +++ b/plugins/secretstores/systemd/systemd_test.go @@ -0,0 +1,174 @@ +//go:build linux + +package systemd + +import ( + "testing" + + "github.com/influxdata/telegraf/testutil" + "github.com/stretchr/testify/require" +) + +func getSystemdVersionMin() (int, error) { + return systemdMinimumVersion, nil +} + +func TestSampleConfig(t *testing.T) { + plugin := &Systemd{} + require.NotEmpty(t, plugin.SampleConfig()) +} + +func TestMinimumVersion(t *testing.T) { + getSystemdVersion = func() (int, error) { return 123, nil } + + plugin := &Systemd{Log: testutil.Logger{}} + require.ErrorContains(t, plugin.Init(), "below minimum version") +} + +func TestEmptyPath(t *testing.T) { + getSystemdVersion = getSystemdVersionMin + + plugin := &Systemd{Log: testutil.Logger{}} + require.ErrorContains(t, plugin.Init(), "'path' required without CREDENTIALS_DIRECTORY") +} + +func TestEmptyCredentialsDirectoryWarning(t *testing.T) { + getSystemdVersion = getSystemdVersionMin + + logger := &testutil.CaptureLogger{} + plugin := &Systemd{ + Path: "testdata", + Log: logger} + require.NoError(t, plugin.Init()) + + actual := logger.Warnings() + require.Len(t, actual, 1) + require.Contains(t, actual[0], "CREDENTIALS_DIRECTORY environment variable undefined") +} + +func TestPathNonExistentExplicit(t *testing.T) { + getSystemdVersion = getSystemdVersionMin + t.Setenv("CREDENTIALS_DIRECTORY", "testdata") + + plugin := &Systemd{ + Path: "non/existent/path", + Log: testutil.Logger{}, + } + require.ErrorContains(t, plugin.Init(), "accessing credentials directory") +} + +func TestPathNonExistentImplicit(t *testing.T) { + getSystemdVersion = getSystemdVersionMin + t.Setenv("CREDENTIALS_DIRECTORY", "non/existent/path") + + plugin := &Systemd{ + Log: testutil.Logger{}, + } + require.ErrorContains(t, plugin.Init(), "accessing credentials directory") +} + +func TestInit(t *testing.T) { + getSystemdVersion = getSystemdVersionMin + t.Setenv("CREDENTIALS_DIRECTORY", "testdata") + + plugin := &Systemd{Log: testutil.Logger{}} + require.NoError(t, plugin.Init()) +} + +func TestSetNotAvailable(t *testing.T) { + getSystemdVersion = getSystemdVersionMin + t.Setenv("CREDENTIALS_DIRECTORY", "testdata") + + plugin := &Systemd{Log: testutil.Logger{}} + require.NoError(t, plugin.Init()) + + // Try to Store the secrets, which this plugin should not let + require.ErrorContains(t, plugin.Set("foo", "bar"), "secret-store does not support creating secrets") +} + +func TestListGet(t *testing.T) { + getSystemdVersion = getSystemdVersionMin + t.Setenv("CREDENTIALS_DIRECTORY", "testdata") + + // secret files name and their content to compare under the `testdata` directory + secrets := map[string]string{ + "secret-file-1": "IWontTell", + "secret_file_2": "SuperDuperSecret!23", + "secretFile": "foobar", + } + + // Initialize the plugin + plugin := &Systemd{Log: testutil.Logger{}} + require.NoError(t, plugin.Init()) + + // List the Secrets + keys, err := plugin.List() + require.NoError(t, err) + require.Len(t, keys, len(secrets)) + // check if the returned array from List() is the same + // as the name of secret files + for secretFileName := range secrets { + require.Contains(t, keys, secretFileName) + } + + // Get the secrets + for _, k := range keys { + value, err := plugin.Get(k) + require.NoError(t, err) + v, found := secrets[k] + require.Truef(t, found, "unexpected secret requested that was not found: %q", k) + require.Equal(t, v, string(value)) + } +} + +func TestResolver(t *testing.T) { + getSystemdVersion = getSystemdVersionMin + t.Setenv("CREDENTIALS_DIRECTORY", "testdata") + + // Secret Value Name to Resolve + secretFileName := "secret-file-1" + // Secret Value to Resolve To + secretVal := "IWontTell" + + // Initialize the plugin + plugin := &Systemd{Log: testutil.Logger{}} + require.NoError(t, plugin.Init()) + + // Get the resolver + resolver, err := plugin.GetResolver(secretFileName) + require.NoError(t, err) + require.NotNil(t, resolver) + s, dynamic, err := resolver() + require.NoError(t, err) + require.False(t, dynamic) + require.Equal(t, secretVal, string(s)) +} + +func TestResolverInvalid(t *testing.T) { + getSystemdVersion = getSystemdVersionMin + t.Setenv("CREDENTIALS_DIRECTORY", "testdata") + + // Initialize the plugin + plugin := &Systemd{Log: testutil.Logger{}} + require.NoError(t, plugin.Init()) + + // Get the resolver + resolver, err := plugin.GetResolver("foo") + require.NoError(t, err) + require.NotNil(t, resolver) + _, _, err = resolver() + require.ErrorContains(t, err, "cannot read the secret's value:") +} + +func TestGetNonExistant(t *testing.T) { + getSystemdVersion = getSystemdVersionMin + t.Setenv("CREDENTIALS_DIRECTORY", "testdata") + + // Initialize the plugin + plugin := &Systemd{Log: testutil.Logger{}} + require.NoError(t, plugin.Init()) + + // Get the resolver + _, err := plugin.Get("foo") + require.ErrorContains(t, err, "cannot read the secret's value:") +} diff --git a/plugins/secretstores/systemd/testdata/secret-file-1 b/plugins/secretstores/systemd/testdata/secret-file-1 new file mode 100644 index 000000000..49bf3f9e9 --- /dev/null +++ b/plugins/secretstores/systemd/testdata/secret-file-1 @@ -0,0 +1 @@ +IWontTell \ No newline at end of file diff --git a/plugins/secretstores/systemd/testdata/secretFile b/plugins/secretstores/systemd/testdata/secretFile new file mode 100644 index 000000000..f6ea04951 --- /dev/null +++ b/plugins/secretstores/systemd/testdata/secretFile @@ -0,0 +1 @@ +foobar \ No newline at end of file diff --git a/plugins/secretstores/systemd/testdata/secret_file_2 b/plugins/secretstores/systemd/testdata/secret_file_2 new file mode 100644 index 000000000..4c4c24ef3 --- /dev/null +++ b/plugins/secretstores/systemd/testdata/secret_file_2 @@ -0,0 +1 @@ +SuperDuperSecret!23 \ No newline at end of file diff --git a/scripts/telegraf.service b/scripts/telegraf.service index 29ec9c055..77b204c4c 100644 --- a/scripts/telegraf.service +++ b/scripts/telegraf.service @@ -8,6 +8,7 @@ Wants=network-online.target Type=notify EnvironmentFile=-/etc/default/telegraf User=telegraf +ImportCredential=telegraf.* ExecStart=/usr/bin/telegraf -config /etc/telegraf/telegraf.conf -config-directory /etc/telegraf/telegraf.d $TELEGRAF_OPTS ExecReload=/bin/kill -HUP $MAINPID Restart=on-failure @@ -15,6 +16,7 @@ RestartForceExitStatus=SIGPIPE KillMode=mixed TimeoutStopSec=5 LimitMEMLOCK=8M:8M +PrivateMounts=true [Install] WantedBy=multi-user.target