Add tags to snmp_trap input for context name and engine ID (#7633)

Add tags for the context name and engine ID
This commit is contained in:
reimda 2020-06-05 08:35:14 -06:00 committed by GitHub
parent 6f931c9834
commit 49caba9b2f
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 114 additions and 107 deletions

View File

@ -45,8 +45,6 @@ information.
# 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.
@ -87,6 +85,8 @@ On Mac OS, listening on privileged ports is unrestricted on versions
- mib (string, MIB from SNMPv2-MIB::snmpTrapOID.0 PDU)
- oid (string, OID string from SNMPv2-MIB::snmpTrapOID.0 PDU)
- version (string, "1" or "2c" or "3")
- context_name (string, value from v3 trap)
- engine_id (string, value from v3 trap)
- fields:
- Fields are mapped from variables in the trap. Field names are
the trap variable names after MIB lookup. Field values are trap

View File

@ -34,7 +34,6 @@ type SnmpTrap struct {
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"`
@ -44,9 +43,6 @@ type SnmpTrap struct {
// 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
@ -86,8 +82,6 @@ var sampleConfig = `
# 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.
@ -152,7 +146,6 @@ func (s *SnmpTrap) Start(acc telegraf.Accumulator) error {
}
if s.listener.Params.Version == gosnmp.Version3 {
s.listener.Params.ContextName = s.ContextName
s.listener.Params.SecurityModel = gosnmp.UserSecurityModel
switch strings.ToLower(s.SecLevel) {
@ -207,9 +200,6 @@ func (s *SnmpTrap) Start(acc telegraf.Accumulator) error {
}
s.listener.Params.SecurityParameters = &gosnmp.UsmSecurityParameters{
AuthoritativeEngineID: s.EngineID,
AuthoritativeEngineBoots: s.EngineBoots,
AuthoritativeEngineTime: s.EngineTime,
UserName: s.SecName,
PrivacyProtocol: privacyProtocol,
PrivacyPassphrase: s.PrivPassword,
@ -359,6 +349,16 @@ func makeTrapHandler(s *SnmpTrap) handler {
fields[name] = value
}
if packet.Version == gosnmp.Version3 {
if packet.ContextName != "" {
tags["context_name"] = packet.ContextName
}
if packet.ContextEngineID != "" {
// SNMP RFCs like 3411 and 5343 show engine ID as a hex string
tags["engine_id"] = fmt.Sprintf("%x", packet.ContextEngineID)
}
}
s.acc.AddFields("snmp_trap", fields, tags, tm)
}
}

View File

@ -40,12 +40,12 @@ func fakeExecCmd(_ internal.Duration, x string, y ...string) ([]byte, error) {
return nil, fmt.Errorf("mock " + x + " " + strings.Join(y, " "))
}
func sendTrap(t *testing.T, port uint16, now uint32, trap gosnmp.SnmpTrap, version gosnmp.SnmpVersion, seclevel string, username string, authproto string, authpass string, privproto string, privpass string) {
func sendTrap(t *testing.T, port uint16, now uint32, trap gosnmp.SnmpTrap, version gosnmp.SnmpVersion, secLevel string, username string, authProto string, authPass string, privProto string, privPass string, contextName string, engineID string) {
var s gosnmp.GoSNMP
if version == gosnmp.Version3 {
var msgFlags gosnmp.SnmpV3MsgFlags
switch strings.ToLower(seclevel) {
switch strings.ToLower(secLevel) {
case "noauthnopriv", "":
msgFlags = gosnmp.NoAuthNoPriv
case "authnopriv":
@ -57,7 +57,7 @@ func sendTrap(t *testing.T, port uint16, now uint32, trap gosnmp.SnmpTrap, versi
}
var authenticationProtocol gosnmp.SnmpV3AuthProtocol
switch strings.ToLower(authproto) {
switch strings.ToLower(authProto) {
case "md5":
authenticationProtocol = gosnmp.MD5
case "sha":
@ -77,7 +77,7 @@ func sendTrap(t *testing.T, port uint16, now uint32, trap gosnmp.SnmpTrap, versi
}
var privacyProtocol gosnmp.SnmpV3PrivProtocol
switch strings.ToLower(privproto) {
switch strings.ToLower(privProto) {
case "aes":
privacyProtocol = gosnmp.AES
case "des":
@ -102,8 +102,8 @@ func sendTrap(t *testing.T, port uint16, now uint32, trap gosnmp.SnmpTrap, versi
AuthoritativeEngineTime: 1,
UserName: username,
PrivacyProtocol: privacyProtocol,
PrivacyPassphrase: privpass,
AuthenticationPassphrase: authpass,
PrivacyPassphrase: privPass,
AuthenticationPassphrase: authPass,
AuthenticationProtocol: authenticationProtocol,
}
s = gosnmp.GoSNMP{
@ -116,6 +116,8 @@ func sendTrap(t *testing.T, port uint16, now uint32, trap gosnmp.SnmpTrap, versi
SecurityParameters: sp,
SecurityModel: gosnmp.UserSecurityModel,
MsgFlags: msgFlags,
ContextName: contextName,
ContextEngineID: engineID,
}
} else {
s = gosnmp.GoSNMP{
@ -162,12 +164,16 @@ func TestReceiveTrap(t *testing.T) {
version gosnmp.SnmpVersion
trap gosnmp.SnmpTrap // include pdus
// V3 auth and priv parameters
secname string // v3 username
seclevel string // v3 security level
authproto string // Auth protocol: "", MD5 or SHA
authpass string // Auth passphrase
privproto string // Priv protocol: "", DES or AES
privpass string // Priv passphrase
secName string // v3 username
secLevel string // v3 security level
authProto string // Auth protocol: "", MD5 or SHA
authPass string // Auth passphrase
privProto string // Priv protocol: "", DES or AES
privPass string // Priv passphrase
// V3 sender context
contextName string
engineID string
// receive
entries []entry
@ -363,10 +369,12 @@ func TestReceiveTrap(t *testing.T) {
},
//ordinary v3 coldStart trap no auth and no priv
{
name: "v3 coldStart noAuthNoPriv",
version: gosnmp.Version3,
secname: "noAuthNoPriv",
seclevel: "noAuthNoPriv",
name: "v3 coldStart noAuthNoPriv",
version: gosnmp.Version3,
secName: "noAuthNoPriv",
secLevel: "noAuthNoPriv",
contextName: "foo_context_name",
engineID: "bar_engine_id",
trap: gosnmp.SnmpTrap{
Variables: []gosnmp.SnmpPDU{
{
@ -408,11 +416,13 @@ func TestReceiveTrap(t *testing.T) {
testutil.MustMetric(
"snmp_trap", // name
map[string]string{ // tags
"oid": ".1.3.6.1.6.3.1.1.5.1",
"name": "coldStart",
"mib": "SNMPv2-MIB",
"version": "3",
"source": "127.0.0.1",
"oid": ".1.3.6.1.6.3.1.1.5.1",
"name": "coldStart",
"mib": "SNMPv2-MIB",
"version": "3",
"source": "127.0.0.1",
"context_name": "foo_context_name",
"engine_id": "6261725f656e67696e655f6964",
},
map[string]interface{}{ // fields
"sysUpTimeInstance": now,
@ -425,10 +435,10 @@ func TestReceiveTrap(t *testing.T) {
{
name: "v3 coldStart authShaNoPriv",
version: gosnmp.Version3,
secname: "authShaNoPriv",
seclevel: "authNoPriv",
authproto: "SHA",
authpass: "passpass",
secName: "authShaNoPriv",
secLevel: "authNoPriv",
authProto: "SHA",
authPass: "passpass",
trap: gosnmp.SnmpTrap{
Variables: []gosnmp.SnmpPDU{
{
@ -488,10 +498,10 @@ func TestReceiveTrap(t *testing.T) {
{
name: "v3 coldStart authShaNoPriv",
version: gosnmp.Version3,
secname: "authSha224NoPriv",
seclevel: "authNoPriv",
authproto: "SHA224",
authpass: "passpass",
secName: "authSha224NoPriv",
secLevel: "authNoPriv",
authProto: "SHA224",
authPass: "passpass",
trap: gosnmp.SnmpTrap{
Variables: []gosnmp.SnmpPDU{
{
@ -550,10 +560,10 @@ func TestReceiveTrap(t *testing.T) {
{
name: "v3 coldStart authSha256NoPriv",
version: gosnmp.Version3,
secname: "authSha256NoPriv",
seclevel: "authNoPriv",
authproto: "SHA256",
authpass: "passpass",
secName: "authSha256NoPriv",
secLevel: "authNoPriv",
authProto: "SHA256",
authPass: "passpass",
trap: gosnmp.SnmpTrap{
Variables: []gosnmp.SnmpPDU{
{
@ -612,10 +622,10 @@ func TestReceiveTrap(t *testing.T) {
{
name: "v3 coldStart authSha384NoPriv",
version: gosnmp.Version3,
secname: "authSha384NoPriv",
seclevel: "authNoPriv",
authproto: "SHA384",
authpass: "passpass",
secName: "authSha384NoPriv",
secLevel: "authNoPriv",
authProto: "SHA384",
authPass: "passpass",
trap: gosnmp.SnmpTrap{
Variables: []gosnmp.SnmpPDU{
{
@ -674,10 +684,10 @@ func TestReceiveTrap(t *testing.T) {
{
name: "v3 coldStart authShaNoPriv",
version: gosnmp.Version3,
secname: "authSha512NoPriv",
seclevel: "authNoPriv",
authproto: "SHA512",
authpass: "passpass",
secName: "authSha512NoPriv",
secLevel: "authNoPriv",
authProto: "SHA512",
authPass: "passpass",
trap: gosnmp.SnmpTrap{
Variables: []gosnmp.SnmpPDU{
{
@ -736,10 +746,10 @@ func TestReceiveTrap(t *testing.T) {
{
name: "v3 coldStart authShaNoPriv",
version: gosnmp.Version3,
secname: "authShaNoPriv",
seclevel: "authNoPriv",
authproto: "SHA",
authpass: "passpass",
secName: "authShaNoPriv",
secLevel: "authNoPriv",
authProto: "SHA",
authPass: "passpass",
trap: gosnmp.SnmpTrap{
Variables: []gosnmp.SnmpPDU{
{
@ -798,10 +808,10 @@ func TestReceiveTrap(t *testing.T) {
{
name: "v3 coldStart authMD5NoPriv",
version: gosnmp.Version3,
secname: "authMD5NoPriv",
seclevel: "authNoPriv",
authproto: "MD5",
authpass: "passpass",
secName: "authMD5NoPriv",
secLevel: "authNoPriv",
authProto: "MD5",
authPass: "passpass",
trap: gosnmp.SnmpTrap{
Variables: []gosnmp.SnmpPDU{
{
@ -860,12 +870,12 @@ func TestReceiveTrap(t *testing.T) {
{
name: "v3 coldStart authSHAPrivAES",
version: gosnmp.Version3,
secname: "authSHAPrivAES",
seclevel: "authPriv",
authproto: "SHA",
authpass: "passpass",
privproto: "AES",
privpass: "passpass",
secName: "authSHAPrivAES",
secLevel: "authPriv",
authProto: "SHA",
authPass: "passpass",
privProto: "AES",
privPass: "passpass",
trap: gosnmp.SnmpTrap{
Variables: []gosnmp.SnmpPDU{
{
@ -924,12 +934,12 @@ func TestReceiveTrap(t *testing.T) {
{
name: "v3 coldStart authSHAPrivDES",
version: gosnmp.Version3,
secname: "authSHAPrivDES",
seclevel: "authPriv",
authproto: "SHA",
authpass: "passpass",
privproto: "DES",
privpass: "passpass",
secName: "authSHAPrivDES",
secLevel: "authPriv",
authProto: "SHA",
authPass: "passpass",
privProto: "DES",
privPass: "passpass",
trap: gosnmp.SnmpTrap{
Variables: []gosnmp.SnmpPDU{
{
@ -988,12 +998,12 @@ func TestReceiveTrap(t *testing.T) {
{
name: "v3 coldStart authSHAPrivAES192",
version: gosnmp.Version3,
secname: "authSHAPrivAES192",
seclevel: "authPriv",
authproto: "SHA",
authpass: "passpass",
privproto: "AES192",
privpass: "passpass",
secName: "authSHAPrivAES192",
secLevel: "authPriv",
authProto: "SHA",
authPass: "passpass",
privProto: "AES192",
privPass: "passpass",
trap: gosnmp.SnmpTrap{
Variables: []gosnmp.SnmpPDU{
{
@ -1052,12 +1062,12 @@ func TestReceiveTrap(t *testing.T) {
{
name: "v3 coldStart authSHAPrivAES192C",
version: gosnmp.Version3,
secname: "authSHAPrivAES192C",
seclevel: "authPriv",
authproto: "SHA",
authpass: "passpass",
privproto: "AES192C",
privpass: "passpass",
secName: "authSHAPrivAES192C",
secLevel: "authPriv",
authProto: "SHA",
authPass: "passpass",
privProto: "AES192C",
privPass: "passpass",
trap: gosnmp.SnmpTrap{
Variables: []gosnmp.SnmpPDU{
{
@ -1116,12 +1126,12 @@ func TestReceiveTrap(t *testing.T) {
{
name: "v3 coldStart authSHAPrivAES256",
version: gosnmp.Version3,
secname: "authSHAPrivAES256",
seclevel: "authPriv",
authproto: "SHA",
authpass: "passpass",
privproto: "AES256",
privpass: "passpass",
secName: "authSHAPrivAES256",
secLevel: "authPriv",
authProto: "SHA",
authPass: "passpass",
privProto: "AES256",
privPass: "passpass",
trap: gosnmp.SnmpTrap{
Variables: []gosnmp.SnmpPDU{
{
@ -1180,12 +1190,12 @@ func TestReceiveTrap(t *testing.T) {
{
name: "v3 coldStart authSHAPrivAES256C",
version: gosnmp.Version3,
secname: "authSHAPrivAES256C",
seclevel: "authPriv",
authproto: "SHA",
authpass: "passpass",
privproto: "AES256C",
privpass: "passpass",
secName: "authSHAPrivAES256C",
secLevel: "authPriv",
authProto: "SHA",
authPass: "passpass",
privProto: "AES256C",
privPass: "passpass",
trap: gosnmp.SnmpTrap{
Variables: []gosnmp.SnmpPDU{
{
@ -1269,15 +1279,12 @@ func TestReceiveTrap(t *testing.T) {
},
Log: testutil.Logger{},
Version: tt.version.String(),
SecName: tt.secname,
SecLevel: tt.seclevel,
AuthProtocol: tt.authproto,
AuthPassword: tt.authpass,
PrivProtocol: tt.privproto,
PrivPassword: tt.privpass,
EngineID: "80001f8880031dd407f608905e00000000",
EngineBoots: 1,
EngineTime: 1,
SecName: tt.secName,
SecLevel: tt.secLevel,
AuthProtocol: tt.authProto,
AuthPassword: tt.authPass,
PrivProtocol: tt.privProto,
PrivPassword: tt.privPass,
}
require.Nil(t, s.Init())
var acc testutil.Accumulator
@ -1294,7 +1301,7 @@ func TestReceiveTrap(t *testing.T) {
s.execCmd = fakeExecCmd
// Send the trap
sendTrap(t, port, now, tt.trap, tt.version, tt.seclevel, tt.secname, tt.authproto, tt.authpass, tt.privproto, tt.privpass)
sendTrap(t, port, now, tt.trap, tt.version, tt.secLevel, tt.secName, tt.authProto, tt.authPass, tt.privProto, tt.privPass, tt.contextName, tt.engineID)
// Wait for trap to be received
select {