Create alarms from snmp v3 trap authenticated by specific User

Prerequisites

Modules

Checkout branches

git checkout origin/osp-snmp-trap .

Note

In this example the following acronym is used: USM : User Security Model

Description

Note

The complete example can be checkout out with git checkout origin/example-snmp-trap-v3-create-alarm-only-if-authenticated-by-specific-usm .

In this tutorial, you will learn how to :

  • Log a message with a specific log level

  • Log information contained by a trap

  • Check a trap’s version

  • Ensure a v3 trap has been authenticated

  • Check which USM was used to authenticate a trap

  • Discard a trap on conditions

  • Create an alarm from a Lua script

  • Log information contained by an alarm

Steps

1. Prerequisite explanation

The prerequisites ensures you have a running snmp-trap connector with a default Lua function creating alarms for every traps it receives. Upon reception of a trap, the snmp-trap module invokes the default Lua function an uses information contained in the received trap to create an alarm.

1. Modify the default provided configuration to include USMs

V3 version of SNMP brings some security features among which, the possibility to authenticate a trap. To do so the snmp-trap module needs to have the information to use for said authentication.

The first step is to enable the SNMPv3 feature, by setting an engineId

/modules/snmp-trap/snmp-trap-1/module.snmp-trap

{
  "messagingConfiguration": 
  {
    "clientId": "osp-snmp-trap-1",
    "host": "rabbit"
  },
  "serialization": {
    "enabled": true,
    "maxTrapPerFile": 10000,
    "maxSizeMo": 10
  },
  "snmp": {
    "snmpv3": {
      "engineId": "00DEADBEEF00"
    }
  }
}

Then add the USMs

{
  "moduleId": "modules.snmp-trap.snmp-trap-1",
  "userSecurityModel" : {
    "type" : "authNoPriv",
    "securityName" : "random_security_name_A",
    "authenticationProtocol" : {
      "type" : "SHA",
      "passwordProvider" : {
        "type" : "PLAINTEXT",
        "password" : "random_pwd_for_random_security_name_A"
      }
    }
  }
}
{
  "moduleId": "modules.snmp-trap.snmp-trap-1",
  "userSecurityModel" : {
    "type" : "authNoPriv",
    "securityName" : "random_security_name_B",
    "authenticationProtocol" : {
      "type" : "SHA",
      "passwordProvider" : {
        "type" : "PLAINTEXT",
        "password" : "random_pwd_for_random_security_name_B"
      }
    }
  }
}
{
  "moduleId": "modules.snmp-trap.snmp-trap-1",
  "userSecurityModel" : {
    "type" : "authPriv",
    "securityName" : "specific-usm-security-name",
    "authenticationProtocol" : {
      "type" : "SHA",
      "passwordProvider" : {
        "type" : "PLAINTEXT",
        "password" : "sha_pwd_sha_sha_sha"
      }
    },
    "privProtocol" : {
      "type": "DES",
        "passwordProvider" : {
          "type" : "PLAINTEXT",
          "password" : "pwd_desandSomeMore2"
        }
    }
  }
}

1. Modify default Lua function to create alarms only for trap authenticated by a specific USM

As we have seen in the Prerequisites explanation, the default provided Lua function creates alarms for every traps it receives. We need to modify it to only create alarms for authenticated trap. Furthermore, we are going to go a step further and create alarms only for trap authenticated by the USM configured with the specific-usm-security-name security name. Once modified, the configuration file should look like this:

/root/rules/main.rules

function main (trap, alarm)

    -- Logs a message with a WARNING level every time it receives a trap
    log("WARN", "A new TRAP is received")

    -- Logs the information contained in the trap
    print_trap_info(trap)

    local TARGETED_USER_SECURITY_NAME = "specific-usm-security-name"

    -- Checks the trap has v3 specific information (necessaries for this example to be able to discard un-authenticated traps)
 
    if (trap.version == 3 and trap.v3_specific_fields ~= nil) then
        -- Checks the trap is authenticated (SNMPv3 doesn't force the authentication for SNMPv3 TRAP receiver)
        -- Checks USM used to authenticate it matches configured `specific-usm-security-name`
        if (trap.v3_specific_fields.is_authenticated and trap.v3_specific_fields.user_security_name == TARGETED_USER_SECURITY_NAME) then

            alarm.summary = "Alarm created for authenticated user [" .. trap.v3_specific_fields.user_security_name .. "]"
            alarm.severity = "root.alarms.severities.warning"
            alarm.source = trap.v3_specific_fields.engine_id


            alarm.serial = "AUTHENTICATED -" .. trap.type .. "-" .. trap.v3_specific_fields.engine_id .. "-" .. trap.oid

            alarm.tags:add("snmptrap-v3")
            alarm.tags:add("Example")
            alarm.tags:add("Authenticated")

        else
            -- If the auth is not valide or the specific user is not ""specific-usm-security-name"
            log("WARN", "New trap is discarded because it has not been authenticated by specified [" .. TARGETED_USER_SECURITY_NAME .. "] user")
            discard()

        end
    else
        -- Discard not SNMPv3 traps.
        discard()

    end

    for index, binding in ipairs(trap.bindings) do
        alarm.additionalData[binding.oid] = binding.value
    end
    print_alarm_info(alarm)
end

1. Test from any linux device disposing of snmptrap binary

Note

By default SNMP-TRAP uses port 162, but it is possible that this port is already used by another service. In this case, you can change the port published in the module.service configuration.

Display snmp-trap module logs

docker service logs --raw -f osp-stack-1_modules_snmp-trap_snmp-trap-1

3.0 Trap with version other than v3 are discarded

Send one test v2c trap :

snmptrap -v 2c -c public localhost:10162 '' 1.3.6.1.4.1.8072.2.3.0.1 1.3.6.1.4.1.8072.2.3.2.1 i 123456

Args

Description

-v 2c

is used to specify this trap version is 2c

Logs should look like this :

[warning] A new TRAP is received
[info]      New trap
[info] SnmpMsg oid                : 1.3.6.1.4.1.8072.2.3.0.1
[info] SnmpMsg occurrence         : 1648132361110828273
[info] Community name             : public
[info] Snmp version               : 1
[info] Source                     : 127.0.0.1:46636
[info] Destination                : 0.0.0.0:10162
[info] Specific-trap              : 1
[info] SnmpMsg variables bindings :
[info]  - 1.3.6.1.4.1.8072.2.3.2.1 : 123456.0
[info] -----------------------------------------------------

It shows the trap is received but discarded without any alarms being created. Looking at the trap information we can see the trap version is different that the expected version 3.

3.1 Test un-authenticated traps are discarded

Send one test un-authenticated trap using a security name different than specific-usm-security-name but still configured, e.g random_security_name_B

snmptrap -v 3 -e 0x00DEADBEEF00 -u random_security_name_B -l noAuthNoPriv localhost:162 '' 1.3.6.1.4.1.8072.2.3.0.1 1.3.6.1.4.1.8072.2.3.2.1 i 123456

Commands args :

Args

Description

-u

is used to specify the security name on behalf of which the trap is sent

-l

is used to specify the trap security level

noAuthNoPriv

indicates the trap does not need to be authenticated nor encrypted

localhost:162

“localhost” should be replaced by the IP of the machine running the SNMP-trap module and “162” with the port exposed (configured in the module.service file of the SNMP-trap module)

Logs should look like this :

[warning] A new TRAP is received
[info]      New trap
[info] SnmpMsg oid                : 1.3.6.1.4.1.8072.2.3.0.1
[info] SnmpMsg occurrence         : 1648131038197472406
[info] Community name             :
[info] Snmp version               : 3
[info] Source                     : 127.0.0.1:51542
[info] Destination                : 0.0.0.0:10162
[info] Specific-trap              : 1
[info] Authenticated              : false
[info] UserSecurityName           : random_security_name_B
[info] SnmpMsg variables bindings :
[info]  - 1.3.6.1.4.1.8072.2.3.2.1 : 123456.0
[info] -----------------------------------------------------
[warning] New trap is discarded because it has not been authenticated by specified [specific-usm-security-name] user

It shows the trap is discarded and looking at the trap information we can see it is because the trap is not authenticated and the security name used to send it does not match the one expected specific-usm-security-name in this example

3.2 Test traps authenticated with another USM than specific-usm-security-name are discarded

Send one authenticated trap using another USM than the one registered for specific-usm-security-name

snmptrap -v 3 -e 0x00DEADBEEF00 -u random_security_name_B -Z 1,1 -l authNoPriv -a SHA -A random_pwd_for_random_security_name_B localhost:10162 '' 1.3.6.1.4.1.8072.2.3.0.1 1.3.6.1.4.1.8072.2.3.2.1 i 123456

Commands args :

Args

Description

authNoPriv

indicates the trap must be authenticated

-Z 1,1

is used to specify the agent sending the trap number of boot and the duration since its last rebooted. For more information you should read SNMP dedicated RFC.

localhost:162

“localhost” should be replaced by the IP of the machine running the SNMP-trap module and “162” with the port exposed (configured in the module.service file of the SNMP-trap module)

Logs should look like this :

[info]      New trap
[info] SnmpMsg oid                : 1.3.6.1.4.1.8072.2.3.0.1
[info] SnmpMsg occurrence         : 1648131337010479096
[info] Community name             :
[info] Snmp version               : 3
[info] Source                     : 127.0.0.1:55743
[info] Destination                : 0.0.0.0:10162
[info] Specific-trap              : 1
[info] Authenticated              : true
[info] UserSecurityName           : random_security_name_B
[info] SnmpMsg variables bindings :
[info]  - 1.3.6.1.4.1.8072.2.3.2.1 : 123456.0
[info] -----------------------------------------------------
[warning] New trap is discarded because it has not been authenticated by specified [specific-usm-security-name] user

It shows the trap is discarded and looking at the trap information we can see it is because while the trap is authenticated, the user security name used to send the trap is not the one we expect in this example (random_security_name_B instead of specific-usm-security-name).

3.3. Test trap authenticated with USM for specific-usm-security-name generates alarms

Send one authenticated trap using specific-usm-security-name security name

snmptrap -v 3 -e 0x00DEADBEEF00 -u specific-usm-security-name -Z 1,1 -l authNoPriv -a SHA -A sha_pwd_sha_sha_sha localhost:10162 '' 1.3.6.1.4.1.8072.2.3.0.1 1.3.6.1.4.1.8072.2.3.2.1 i 123456

Args

Description

-u specific-usm-security-name

is used to specify the security name used to send the trap is “specific-usm-security-name” which is the one this example expects to receive to generate an alarm

-l authNoPriv

is used to specify the trap security level

-a SHA -A sha_pwd_sha_sha_sha

indicates the trap should be authenticated and the parameters to use to authenticate it

Logs should look like this :

[warning] A new TRAP is received
[info]      New trap
[info] SnmpMsg oid                : 1.3.6.1.4.1.8072.2.3.0.1
[info] SnmpMsg occurrence         : 1648131792051096183
[info] Community name             :
[info] Snmp version               : 3
[info] Source                     : 127.0.0.1:58572
[info] Destination                : 0.0.0.0:10162
[info] Specific-trap              : 1
[info] Authenticated              : true
[info] UserSecurityName           : specific-usm-security-name
[info] SnmpMsg variables bindings :
[info]  - 1.3.6.1.4.1.8072.2.3.2.1 : 123456.0
[info] -----------------------------------------------------
[info]      Alarm
[info] UID             : cde5e3de-8333-49ff-a02f-7ed5d4f95cfd
[info] Occurrence      : 1648131792051096183
[info] Summary         : Alarm created for authenticated user [specific-usm-security-name]
[info] Location        :
[info] Severity        : root.alarms.severities.warning
[info] Source          :
[info] Serial          :
[info] Tags            :
[info]  - snmptrap-v3
[info]  - Example
[info]  - Authenticated
[info] Additional info :
[info] -----------------------------------------------------
```

It shows the trap reception leads to an alarm generation. Looking at the trap information we can see it was properly authenticated using the USM matching the expected specific-usm-security-name security name.