From f674099fad6b5169436eb52325b65e55829cdd34 Mon Sep 17 00:00:00 2001 From: Sven Rebhan <36194019+srebhan@users.noreply.github.com> Date: Wed, 13 Mar 2024 17:39:37 +0100 Subject: [PATCH] feat(snmp): Add secret support for auth_password and priv_password (#14975) --- internal/snmp/config.go | 42 +++++++++++------------- internal/snmp/wrapper.go | 21 +++++++++--- plugins/inputs/snmp/README.md | 9 +++++ plugins/inputs/snmp/snmp_test.go | 20 +++++------ plugins/processors/ifname/README.md | 9 +++++ plugins/processors/snmp_lookup/README.md | 9 +++++ 6 files changed, 72 insertions(+), 38 deletions(-) diff --git a/internal/snmp/config.go b/internal/snmp/config.go index 1166c8138..20cc20acb 100644 --- a/internal/snmp/config.go +++ b/internal/snmp/config.go @@ -8,15 +8,10 @@ import ( type ClientConfig struct { // Timeout to wait for a response. - Timeout config.Duration `toml:"timeout"` - Retries int `toml:"retries"` - // Values: 1, 2, 3 - Version uint8 `toml:"version"` - UnconnectedUDPSocket bool `toml:"unconnected_udp_socket"` - // Path to mib files - Path []string `toml:"path"` - // Translator implementation - Translator string `toml:"-"` + Timeout config.Duration `toml:"timeout"` + Retries int `toml:"retries"` + Version uint8 `toml:"version"` + UnconnectedUDPSocket bool `toml:"unconnected_udp_socket"` // Parameters for Version 1 & 2 Community string `toml:"community"` @@ -25,19 +20,20 @@ type ClientConfig struct { MaxRepetitions uint32 `toml:"max_repetitions"` // Parameters for Version 3 - ContextName string `toml:"context_name"` - // Values: "noAuthNoPriv", "authNoPriv", "authPriv" - SecLevel string `toml:"sec_level"` - SecName string `toml:"sec_name"` - // Values: "MD5", "SHA", "". Default: "" - AuthProtocol string `toml:"auth_protocol"` - AuthPassword string `toml:"auth_password"` - // Values: "DES", "AES", "". Default: "" - PrivProtocol string `toml:"priv_protocol"` - PrivPassword string `toml:"priv_password"` - EngineID string `toml:"-"` - EngineBoots uint32 `toml:"-"` - EngineTime uint32 `toml:"-"` + ContextName string `toml:"context_name"` + SecLevel string `toml:"sec_level"` + SecName string `toml:"sec_name"` + AuthProtocol string `toml:"auth_protocol"` + AuthPassword config.Secret `toml:"auth_password"` + PrivProtocol string `toml:"priv_protocol"` + PrivPassword config.Secret `toml:"priv_password"` + EngineID string `toml:"-"` + EngineBoots uint32 `toml:"-"` + EngineTime uint32 `toml:"-"` + + // Path to mib files + Path []string `toml:"path"` + Translator string `toml:"-"` } func DefaultClientConfig() *ClientConfig { @@ -52,6 +48,6 @@ func DefaultClientConfig() *ClientConfig { SecLevel: "authNoPriv", SecName: "myuser", AuthProtocol: "MD5", - AuthPassword: "pass", + AuthPassword: config.NewSecret([]byte("pass")), } } diff --git a/internal/snmp/wrapper.go b/internal/snmp/wrapper.go index 8cf306110..625a0f7c2 100644 --- a/internal/snmp/wrapper.go +++ b/internal/snmp/wrapper.go @@ -109,7 +109,14 @@ func NewWrapper(s ClientConfig) (GosnmpWrapper, error) { return GosnmpWrapper{}, errors.New("invalid authProtocol") } - sp.AuthenticationPassphrase = s.AuthPassword + if !s.AuthPassword.Empty() { + p, err := s.AuthPassword.Get() + if err != nil { + return GosnmpWrapper{}, fmt.Errorf("getting authentication password failed: %w", err) + } + sp.AuthenticationPassphrase = p.String() + p.Destroy() + } switch strings.ToLower(s.PrivProtocol) { case "des": @@ -130,12 +137,16 @@ func NewWrapper(s ClientConfig) (GosnmpWrapper, error) { return GosnmpWrapper{}, errors.New("invalid privProtocol") } - sp.PrivacyPassphrase = s.PrivPassword - + if !s.PrivPassword.Empty() { + p, err := s.PrivPassword.Get() + if err != nil { + return GosnmpWrapper{}, fmt.Errorf("getting private password failed: %w", err) + } + sp.PrivacyPassphrase = p.String() + p.Destroy() + } sp.AuthoritativeEngineID = s.EngineID - sp.AuthoritativeEngineBoots = s.EngineBoots - sp.AuthoritativeEngineTime = s.EngineTime } return gs, nil diff --git a/plugins/inputs/snmp/README.md b/plugins/inputs/snmp/README.md index 3e0cc4f09..3e8d8f84e 100644 --- a/plugins/inputs/snmp/README.md +++ b/plugins/inputs/snmp/README.md @@ -18,6 +18,15 @@ See the [CONFIGURATION.md][CONFIGURATION.md] for more details. [CONFIGURATION.md]: ../../../docs/CONFIGURATION.md#plugins +## Secret-store support + +This plugin supports secrets from secret-stores for the `auth_password` and +`priv_password` option. +See the [secret-store documentation][SECRETSTORE] for more details on how +to use them. + +[SECRETSTORE]: ../../../docs/CONFIGURATION.md#secret-store-secrets + ## SNMP backend: gosmi and netsnmp Telegraf has two backends to translate SNMP objects. By default, Telegraf will diff --git a/plugins/inputs/snmp/snmp_test.go b/plugins/inputs/snmp/snmp_test.go index 48abaf365..0637d2768 100644 --- a/plugins/inputs/snmp/snmp_test.go +++ b/plugins/inputs/snmp/snmp_test.go @@ -245,9 +245,9 @@ func TestGetSNMPConnection_v3(t *testing.T) { SecLevel: "authPriv", SecName: "myuser", AuthProtocol: "md5", - AuthPassword: "password123", + AuthPassword: config.NewSecret([]byte("password123")), PrivProtocol: "des", - PrivPassword: "321drowssap", + PrivPassword: config.NewSecret([]byte("321drowssap")), EngineID: "myengineid", EngineBoots: 1, EngineTime: 2, @@ -294,9 +294,9 @@ func TestGetSNMPConnection_v3_blumenthal(t *testing.T) { SecLevel: "authPriv", SecName: "myuser", AuthProtocol: "md5", - AuthPassword: "password123", + AuthPassword: config.NewSecret([]byte("password123")), PrivProtocol: "AES192", - PrivPassword: "password123", + PrivPassword: config.NewSecret([]byte("password123")), EngineID: "myengineid", EngineBoots: 1, EngineTime: 2, @@ -316,9 +316,9 @@ func TestGetSNMPConnection_v3_blumenthal(t *testing.T) { SecLevel: "authPriv", SecName: "myuser", AuthProtocol: "md5", - AuthPassword: "password123", + AuthPassword: config.NewSecret([]byte("password123")), PrivProtocol: "AES192C", - PrivPassword: "password123", + PrivPassword: config.NewSecret([]byte("password123")), EngineID: "myengineid", EngineBoots: 1, EngineTime: 2, @@ -338,9 +338,9 @@ func TestGetSNMPConnection_v3_blumenthal(t *testing.T) { SecLevel: "authPriv", SecName: "myuser", AuthProtocol: "md5", - AuthPassword: "password123", + AuthPassword: config.NewSecret([]byte("password123")), PrivProtocol: "AES256", - PrivPassword: "password123", + PrivPassword: config.NewSecret([]byte("password123")), EngineID: "myengineid", EngineBoots: 1, EngineTime: 2, @@ -360,9 +360,9 @@ func TestGetSNMPConnection_v3_blumenthal(t *testing.T) { SecLevel: "authPriv", SecName: "myuser", AuthProtocol: "md5", - AuthPassword: "password123", + AuthPassword: config.NewSecret([]byte("password123")), PrivProtocol: "AES256C", - PrivPassword: "password123", + PrivPassword: config.NewSecret([]byte("password123")), EngineID: "myengineid", EngineBoots: 1, EngineTime: 2, diff --git a/plugins/processors/ifname/README.md b/plugins/processors/ifname/README.md index 659cc1b1b..301b4d87f 100644 --- a/plugins/processors/ifname/README.md +++ b/plugins/processors/ifname/README.md @@ -13,6 +13,15 @@ See the [CONFIGURATION.md][CONFIGURATION.md] for more details. [CONFIGURATION.md]: ../../../docs/CONFIGURATION.md#plugins +## Secret-store support + +This plugin supports secrets from secret-stores for the `auth_password` and +`priv_password` option. +See the [secret-store documentation][SECRETSTORE] for more details on how +to use them. + +[SECRETSTORE]: ../../../docs/CONFIGURATION.md#secret-store-secrets + ## Configuration ```toml @sample.conf diff --git a/plugins/processors/snmp_lookup/README.md b/plugins/processors/snmp_lookup/README.md index 5be7a3ca8..e617a4ee4 100644 --- a/plugins/processors/snmp_lookup/README.md +++ b/plugins/processors/snmp_lookup/README.md @@ -13,6 +13,15 @@ See the [CONFIGURATION.md][CONFIGURATION.md] for more details. [CONFIGURATION.md]: ../../../docs/CONFIGURATION.md#plugins +## Secret-store support + +This plugin supports secrets from secret-stores for the `auth_password` and +`priv_password` option. +See the [secret-store documentation][SECRETSTORE] for more details on how +to use them. + +[SECRETSTORE]: ../../../docs/CONFIGURATION.md#secret-store-secrets + ## Configuration ```toml @sample.conf