Add SNMPv3 trap support to snmp_trap input plugin (#7294)

Extend snmp_trap input plugin to support SNMPv3 traps. MD5 and SHA1 authentication protocols are supported, and DES, AES, AES192, AES256, AES192c and AES256c privacy protocols are supported.
This commit is contained in:
kauppine 2020-06-05 00:19:47 +03:00 committed by GitHub
parent aa8cefedda
commit 36316ee8f2
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 1120 additions and 17 deletions

3
go.mod
View File

@ -57,7 +57,6 @@ require (
github.com/gofrs/uuid v2.1.0+incompatible
github.com/gogo/protobuf v1.2.2-0.20190723190241-65acae22fc9d
github.com/golang/geo v0.0.0-20190916061304-5b978397cfec
github.com/golang/mock v1.4.3 // indirect
github.com/golang/protobuf v1.3.5
github.com/google/go-cmp v0.4.0
github.com/google/go-github v17.0.0+incompatible
@ -113,7 +112,7 @@ require (
github.com/shirou/gopsutil v2.20.2+incompatible
github.com/shopspring/decimal v0.0.0-20200105231215-408a2507e114 // indirect
github.com/sirupsen/logrus v1.4.2
github.com/soniah/gosnmp v1.22.0
github.com/soniah/gosnmp v1.25.0
github.com/streadway/amqp v0.0.0-20180528204448-e5adc2ada8b8
github.com/stretchr/testify v1.5.1
github.com/tbrandon/mbserver v0.0.0-20170611213546-993e1772cc62

6
go.sum
View File

@ -247,8 +247,6 @@ github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfb
github.com/golang/mock v1.2.0/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A=
github.com/golang/mock v1.3.1/go.mod h1:sBzyDLLjw3U8JLTeZvSv8jJB+tU5PVekmnlKIyFUx0Y=
github.com/golang/mock v1.4.0/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw=
github.com/golang/mock v1.4.3 h1:GV+pQPG/EUUbkh47niozDcADz6go/dUwhVzdUQHIVRw=
github.com/golang/mock v1.4.3/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw=
github.com/golang/protobuf v0.0.0-20161109072736-4bd1920723d7/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
@ -530,8 +528,8 @@ github.com/sirupsen/logrus v1.2.0 h1:juTguoYk5qI21pwyTXY3B3Y5cOTH3ZUyZCg1v/mihuo
github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo=
github.com/sirupsen/logrus v1.4.2 h1:SPIRibHv4MatM3XXNO2BJeFLZwZ2LvZgfQ5+UNI2im4=
github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE=
github.com/soniah/gosnmp v1.22.0 h1:jVJi8+OGvR+JHIaZKMmnyNP0akJd2vEgNatybwhZvxg=
github.com/soniah/gosnmp v1.22.0/go.mod h1:DuEpAS0az51+DyVBQwITDsoq4++e3LTNckp2GoasF2I=
github.com/soniah/gosnmp v1.25.0 h1:0y8vpjD07NPmnT+wojnUrKkYLX9Fxw1jI4cGTumWugQ=
github.com/soniah/gosnmp v1.25.0/go.mod h1:8YvfZxH388NIIw2A+X5z2Oh97VcNhtmxDLt5QeUzVuQ=
github.com/spf13/pflag v0.0.0-20170130214245-9ff6c6923cff/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4=
github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg=
github.com/streadway/amqp v0.0.0-20180528204448-e5adc2ada8b8 h1:l6epF6yBwuejBfhGkM5m8VSNM/QAm7ApGyH35ehA7eQ=

View File

@ -33,6 +33,24 @@ information.
# service_address = "udp://:162"
## Timeout running snmptranslate command
# timeout = "5s"
## Snmp version
# version = "2c"
## SNMPv3 authentication and encryption options.
##
## Security Name.
# sec_name = "myuser"
## Authentication protocol; one of "MD5", "SHA" or "".
# auth_protocol = "MD5"
## Authentication password.
# auth_password = "pass"
## Security Level; one of "noAuthNoPriv", "authNoPriv", or "authPriv".
# sec_level = "authNoPriv"
## Context Name.
# context_name = ""
## Privacy protocol used for encrypted messages; one of "DES", "AES", "AES192", "AES192C", "AES256", "AES256C" or "".
# priv_protocol = ""
## Privacy password used for encrypted messages.
# priv_password = ""
```
#### Using a Privileged Port

View File

@ -31,6 +31,22 @@ type mibEntry struct {
type SnmpTrap struct {
ServiceAddress string `toml:"service_address"`
Timeout internal.Duration `toml:"timeout"`
Version string `toml:"version"`
// Settings 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:"-"`
acc telegraf.Accumulator
listener *gosnmp.TrapListener
@ -58,6 +74,24 @@ var sampleConfig = `
# service_address = "udp://:162"
## Timeout running snmptranslate command
# timeout = "5s"
## Snmp version, defaults to 2c
# version = "2c"
## SNMPv3 authentication and encryption options.
##
## Security Name.
# sec_name = "myuser"
## Authentication protocol; one of "MD5", "SHA" or "".
# auth_protocol = "MD5"
## Authentication password.
# auth_password = "pass"
## Security Level; one of "noAuthNoPriv", "authNoPriv", or "authPriv".
# sec_level = "authNoPriv"
## Context Name.
# context_name = ""
## Privacy protocol used for encrypted messages; one of "DES", "AES", "AES192", "AES192C", "AES256", "AES256C" or "".
# priv_protocol = ""
## Privacy password used for encrypted messages.
# priv_password = ""
`
func (s *SnmpTrap) SampleConfig() string {
@ -78,6 +112,7 @@ func init() {
timeFunc: time.Now,
ServiceAddress: "udp://:162",
Timeout: defaultTimeout,
Version: "2c",
}
})
}
@ -105,6 +140,85 @@ func (s *SnmpTrap) Start(acc telegraf.Accumulator) error {
s.listener.OnNewTrap = makeTrapHandler(s)
s.listener.Params = gosnmp.Default
switch s.Version {
case "3":
s.listener.Params.Version = gosnmp.Version3
case "2c":
s.listener.Params.Version = gosnmp.Version2c
case "1":
s.listener.Params.Version = gosnmp.Version1
default:
s.listener.Params.Version = gosnmp.Version2c
}
if s.listener.Params.Version == gosnmp.Version3 {
s.listener.Params.ContextName = s.ContextName
s.listener.Params.SecurityModel = gosnmp.UserSecurityModel
switch strings.ToLower(s.SecLevel) {
case "noauthnopriv", "":
s.listener.Params.MsgFlags = gosnmp.NoAuthNoPriv
case "authnopriv":
s.listener.Params.MsgFlags = gosnmp.AuthNoPriv
case "authpriv":
s.listener.Params.MsgFlags = gosnmp.AuthPriv
default:
return fmt.Errorf("unknown security level '%s'", s.SecLevel)
}
var authenticationProtocol gosnmp.SnmpV3AuthProtocol
switch strings.ToLower(s.AuthProtocol) {
case "md5":
authenticationProtocol = gosnmp.MD5
case "sha":
authenticationProtocol = gosnmp.SHA
//case "sha224":
// authenticationProtocol = gosnmp.SHA224
//case "sha256":
// authenticationProtocol = gosnmp.SHA256
//case "sha384":
// authenticationProtocol = gosnmp.SHA384
//case "sha512":
// authenticationProtocol = gosnmp.SHA512
case "":
authenticationProtocol = gosnmp.NoAuth
default:
return fmt.Errorf("unknown authentication protocol '%s'", s.AuthProtocol)
}
var privacyProtocol gosnmp.SnmpV3PrivProtocol
switch strings.ToLower(s.PrivProtocol) {
case "aes":
privacyProtocol = gosnmp.AES
case "des":
privacyProtocol = gosnmp.DES
case "aes192":
privacyProtocol = gosnmp.AES192
case "aes192c":
privacyProtocol = gosnmp.AES192C
case "aes256":
privacyProtocol = gosnmp.AES256
case "aes256c":
privacyProtocol = gosnmp.AES256C
case "":
privacyProtocol = gosnmp.NoPriv
default:
return fmt.Errorf("unknown privacy protocol '%s'", s.PrivProtocol)
}
s.listener.Params.SecurityParameters = &gosnmp.UsmSecurityParameters{
AuthoritativeEngineID: s.EngineID,
AuthoritativeEngineBoots: s.EngineBoots,
AuthoritativeEngineTime: s.EngineTime,
UserName: s.SecName,
PrivacyProtocol: privacyProtocol,
PrivacyPassphrase: s.PrivPassword,
AuthenticationPassphrase: s.AuthPassword,
AuthenticationProtocol: authenticationProtocol,
}
}
// wrap the handler, used in unit tests
if nil != s.makeHandlerWrapper {
s.listener.OnNewTrap = s.makeHandlerWrapper(s.listener.OnNewTrap)

File diff suppressed because it is too large Load Diff