etingof / pysnmp

Python SNMP library
http://snmplabs.com/pysnmp/
BSD 2-Clause "Simplified" License
584 stars 201 forks source link

How to implement CommandResponder and NotificationOriginator in the same agent? #408

Open FabianNiehaus opened 3 years ago

FabianNiehaus commented 3 years ago

I am trying to build an SNMP agent based on PySNMP. This agent should both respond to commands received from the NMS and send traps to the NMS.

However, I can only get one of those functions to work at a time. Whenever I send a trap, commands from the NMS no longer work and I receive a timeout error. When the part of the code sending traps is deactivated, command handling works just fine.

It seems the issue stems from SnmpV1SecurityModel._com2sec(), where this part (L306-313) raises the error:

        if communityName in self.__communityToTagMap:
            if transportInformation in self.__transportToTagMap:
                tags = self.__transportToTagMap[transportInformation].intersection(
                    self.__communityToTagMap[communityName])
            elif self.__emptyTag in self.__communityToTagMap[communityName]:
                tags = [self.__emptyTag]
            else:
                raise error.StatusInformation(errorIndication=errind.unknownCommunityName)

When running WITH traps, transportInformation is ((1, 3, 6, 1, 6, 1, 1), ('127.0.0.1', 59937)) while self.__transportToTagMap contains the key ((1, 3, 6, 1, 6, 1, 1), ('127.0.0.1', 40162)). This means that once a trap is sent to the NMS at 127.0.0.1:40162, that is the only remote address that can be communicated through. The command origination from the NMS at 127.0.0.1:59937 (random port) therefore does not produce a match and is rejected.

When running WITHOUT traps, self.__transportToTagMap is empty and self.__communityToTagMap[communityName] only contains the emptyTag. This results in the tags being set to emptyTag and the processing being continued.

Can anybody point me to what I am doing wrong?

Debug output WITH traps ``` 2021-08-18 11:09:41,358 pysnmp: sendVarBinds: final varBinds [(, payload [1.3.6.1.2.1.1.3.0]>, , subtypeSpec >, payload [0]>), (, payload [1.3.6.1.6.3.1.1.4.1.0]>, ObjectIdentity(, payload [1.1.1234.2.1.4.5]>)), (, payload [1.1.1234.2.1.4.1]>, , subtypeSpec , >, encoding iso-8859-1, payload [2021-8-18,11:9:40.8,+2:0]>), (, payload [1.1.1234.2.1.4.2]>, , subtypeSpec , >, encoding iso-8859-1, payload [1]>), (, payload [1.1.1234.2.1.4.3]>, , subtypeSpec , >, encoding iso-8859-1, payload [2021-8-18,11:9:40.8,+2:0]>), (, payload [1.1.1234.2.1.4.4]>, , subtypeSpec , >, namedValues , payload [false]>)] 2021-08-18 11:09:41,359 pysnmp: sendVarBinds: notificationHandle 898929000, notifyTag -8285651105444112065 yields: transportDomain 1.3.6.1.6.1.1, transportAddress ('127.0.0.1', 40162), securityModel 2, securityName my-area, securityLevel noAuthNoPriv 2021-08-18 11:09:41,359 pysnmp: isAccessAllowed: securityModel 2, securityName my-area, securityLevel noAuthNoPriv, viewType notify, contextName b'' for variableName 1.1.1234.2.1.4.1 2021-08-18 11:09:41,359 pysnmp: sendVarBinds: ACL succeeded for OID 1.1.1234.2.1.4.1 securityName my-area 2021-08-18 11:09:41,359 pysnmp: isAccessAllowed: securityModel 2, securityName my-area, securityLevel noAuthNoPriv, viewType notify, contextName b'' for variableName 1.1.1234.2.1.4.2 2021-08-18 11:09:41,359 pysnmp: sendVarBinds: ACL succeeded for OID 1.1.1234.2.1.4.2 securityName my-area 2021-08-18 11:09:41,360 pysnmp: isAccessAllowed: securityModel 2, securityName my-area, securityLevel noAuthNoPriv, viewType notify, contextName b'' for variableName 1.1.1234.2.1.4.3 2021-08-18 11:09:41,360 pysnmp: sendVarBinds: ACL succeeded for OID 1.1.1234.2.1.4.3 securityName my-area 2021-08-18 11:09:41,360 pysnmp: isAccessAllowed: securityModel 2, securityName my-area, securityLevel noAuthNoPriv, viewType notify, contextName b'' for variableName 1.1.1234.2.1.4.4 2021-08-18 11:09:41,365 pysnmp: sendVarBinds: ACL succeeded for OID 1.1.1234.2.1.4.4 securityName my-area 2021-08-18 11:09:41,368 pysnmp: sendPdu: securityName my-area, PDU SNMPv2TrapPDU: request-id=6752989 error-status=noError error-index=0 variable-bindings=VarBindList: VarBind: name=1.3.6.1.2.1.1.3.0 =_BindValue: value=ObjectSyntax: application-wide=ApplicationSyntax: timeticks-value=0 VarBind: name=1.3.6.1.6.3.1.1.4.1.0 =_BindValue: value=ObjectSyntax: simple=SimpleSyntax: objectID-value=1.1.1234.2.1.4.5 VarBind: name=1.1.1234.2.1.4.1 =_BindValue: value=ObjectSyntax: simple=SimpleSyntax: string-value=2021-8-18,11:9:40.8,+2:0 VarBind: name=1.1.1234.2.1.4.2 =_BindValue: value=ObjectSyntax: simple=SimpleSyntax: string-value=1 VarBind: name=1.1.1234.2.1.4.3 =_BindValue: value=ObjectSyntax: simple=SimpleSyntax: string-value=2021-8-18,11:9:40.8,+2:0 VarBind: name=1.1.1234.2.1.4.4 =_BindValue: value=ObjectSyntax: simple=SimpleSyntax: integer-value=false 2021-08-18 11:09:41,368 pysnmp: sendPdu: new sendPduHandle 14944561, timeout 0 ticks, cbFun None 2021-08-18 11:09:41,368 pysnmp: prepareOutgoingMessage: using contextEngineId , subtypeSpec , >, encoding iso-8859-1, payload [0x80004fb805646f...6e6e6572f23e4b80]> contextName b'' 2021-08-18 11:09:41,368 pysnmp: _sec2com: built securityName to communityName map, version 14: {(, subtypeSpec , , >, encoding utf-8, payload [my-area]>, , subtypeSpec , >, encoding iso-8859-1, payload [0x80004fb805646f...6e6e6572f23e4b80]>, , subtypeSpec , , >, encoding utf-8, payload []>): , subtypeSpec >, encoding iso-8859-1, payload [public]>} 2021-08-18 11:09:41,369 pysnmp: generateRequestMsg: using community , subtypeSpec >, encoding iso-8859-1, payload [public]> for securityModel , subtypeSpec , , >, payload [2]>, securityName , subtypeSpec , >, encoding utf-8, payload [my-area]>, contextEngineId , subtypeSpec , >, encoding iso-8859-1, payload [0x80004fb805646f...6e6e6572f23e4b80]> contextName b'' 2021-08-18 11:09:41,369 pysnmp: generateRequestMsg: Message: version=1 community=public data=PDUs: snmpV2-trap=SNMPv2TrapPDU: request-id=6752989 error-status=noError error-index=0 variable-bindings=VarBindList: VarBind: name=1.3.6.1.2.1.1.3.0 =_BindValue: value=ObjectSyntax: application-wide=ApplicationSyntax: timeticks-value=0 VarBind: name=1.3.6.1.6.3.1.1.4.1.0 =_BindValue: value=ObjectSyntax: simple=SimpleSyntax: objectID-value=1.1.1234.2.1.4.5 VarBind: name=1.1.1234.2.1.4.1 =_BindValue: value=ObjectSyntax: simple=SimpleSyntax: string-value=2021-8-18,11:9:40.8,+2:0 VarBind: name=1.1.1234.2.1.4.2 =_BindValue: value=ObjectSyntax: simple=SimpleSyntax: string-value=1 VarBind: name=1.1.1234.2.1.4.3 =_BindValue: value=ObjectSyntax: simple=SimpleSyntax: string-value=2021-8-18,11:9:40.8,+2:0 VarBind: name=1.1.1234.2.1.4.4 =_BindValue: value=ObjectSyntax: simple=SimpleSyntax: integer-value=false 2021-08-18 11:09:41,370 pysnmp: sendPdu: MP succeeded 2021-08-18 11:09:41,370 pysnmp: sendMessage: sending transportAddress ('127.0.0.1', 40162) outgoingMessage 00000: 30 81 8C 02 01 01 04 06 70 75 62 6C 69 63 A7 7F 00016: 02 03 67 0A DD 02 01 00 02 01 00 30 72 30 0D 06 00032: 08 2B 06 01 02 01 01 03 00 43 01 00 30 15 06 0A 00048: 2B 06 01 06 03 01 01 04 01 00 06 07 29 89 52 02 00064: 01 04 05 30 16 06 07 29 89 52 02 01 04 01 04 0B 00080: 07 E5 08 12 0B 09 28 08 2B 02 00 30 0C 06 07 29 00096: 89 52 02 01 04 02 04 01 31 30 16 06 07 29 89 52 00112: 02 01 04 03 04 0B 07 E5 08 12 0B 09 28 08 2B 02 00128: 00 30 0C 06 07 29 89 52 02 01 04 04 02 01 02 2021-08-18 11:09:41,370 pysnmp: sendPdu: message sent 2021-08-18 11:09:41,370 pysnmp: sendVarBinds: notificationHandle 898929000, sendRequestHandle None, timeout 100 2021-08-18 11:09:41,370 pysnmp: sendVarBinds: notificationHandle 898929000, sendRequestHandle None, notification(s) sent 2021-08-18 11:09:45,514 pysnmp: receiveMessage: msgVersion 1, msg decoded 2021-08-18 11:09:45,515 pysnmp: prepareDataElements: Message: version=version-2c community=public data=PDUs: get-next-request=GetNextRequestPDU: request-id=387 error-status=noError error-index=0 variable-bindings=VarBindList: VarBind: name=1.1.1234.2.1.1.1.2 =_BindValue: unSpecified= 2021-08-18 11:09:45,515 pysnmp: _com2sec: built transport-to-tag map version 4: {((1, 3, 6, 1, 6, 1, 1), ('127.0.0.1', 40162)): {, subtypeSpec , >, encoding utf-8, payload [-8285651105444112065]>}} 2021-08-18 11:09:45,515 pysnmp: _com2sec: built communityName to tag map (securityModel 2), version 14: {, subtypeSpec >, encoding iso-8859-1, payload [public]>: {, subtypeSpec , >, encoding utf-8, payload [-8285651105444112065]>}} 2021-08-18 11:09:45,515 pysnmp: _com2sec: built tag & community to securityName map (securityModel 2), version 14: {(, subtypeSpec , >, encoding utf-8, payload [-8285651105444112065]>, , subtypeSpec >, encoding iso-8859-1, payload [public]>): {(, subtypeSpec , , >, encoding utf-8, payload [my-area]>, , subtypeSpec , >, encoding iso-8859-1, payload [0x80004fb805646f...6e6e6572f23e4b80]>, , subtypeSpec , , >, encoding utf-8, payload []>)}} 2021-08-18 11:09:45,515 pysnmp: StatusInformation: {'errorIndication': UnknownCommunityName('Unknown SNMP community name encountered')} 2021-08-18 11:09:45,516 pysnmp: StatusInformation: {'errorIndication': UnknownCommunityName('Unknown SNMP community name encountered'), 'communityName': , encoding iso-8859-1, payload [public]>} ```
Debug output WITHOUT traps ``` 2021-08-18 11:08:31,862 pysnmp: receiveMessage: msgVersion 1, msg decoded 2021-08-18 11:08:31,862 pysnmp: prepareDataElements: Message: version=version-2c community=public data=PDUs: get-next-request=GetNextRequestPDU: request-id=384 error-status=noError error-index=0 variable-bindings=VarBindList: VarBind: name=1.1.1234.2.1.1.1.2 =_BindValue: unSpecified= 2021-08-18 11:08:31,862 pysnmp: _com2sec: built transport-to-tag map version 0: {} 2021-08-18 11:08:31,862 pysnmp: _com2sec: built securityName to securityModel map, version 0: {} 2021-08-18 11:08:31,863 pysnmp: _com2sec: built communityName to tag map (securityModel 2), version 4: {, subtypeSpec >, encoding iso-8859-1, payload [public]>: {, subtypeSpec , >, encoding utf-8, payload []>}} 2021-08-18 11:08:31,863 pysnmp: _com2sec: built tag & community to securityName map (securityModel 2), version 4: {(, subtypeSpec , >, encoding utf-8, payload []>, , subtypeSpec >, encoding iso-8859-1, payload [public]>): {(, subtypeSpec , , >, encoding utf-8, payload [my-area]>, , subtypeSpec , >, encoding iso-8859-1, payload [0x80004fb805646f...6e6e6572f1b62e40]>, , subtypeSpec , , >, encoding utf-8, payload []>)}} 2021-08-18 11:08:31,863 pysnmp: _com2sec: securityName candidates for communityName 'public' are [(, subtypeSpec , , >, encoding utf-8, payload [my-area]>, , subtypeSpec , >, encoding iso-8859-1, payload [0x80004fb805646f...6e6e6572f1b62e40]>, , subtypeSpec , , >, encoding utf-8, payload []>)]; choosing securityName 'my-area' 2021-08-18 11:08:31,863 pysnmp: processIncomingMsg: looked up securityName , subtypeSpec , , >, encoding utf-8, payload [my-area]> securityModel 2 contextEngineId , subtypeSpec , >, encoding iso-8859-1, payload [0x80004fb805646f...6e6e6572f1b62e40]> contextName , subtypeSpec , , >, encoding utf-8, payload []> by communityName , encoding iso-8859-1, payload [public]> AND transportInformation ((1, 3, 6, 1, 6, 1, 1), ('127.0.0.1', 59937)) 2021-08-18 11:08:31,863 pysnmp: processIncomingMsg: generated maxSizeResponseScopedPDU 65379 securityStateReference 5169481 2021-08-18 11:08:31,863 pysnmp: prepareDataElements: SM returned securityEngineId , subtypeSpec , >, encoding iso-8859-1, payload [0x80004fb805646f...6e6e6572f1b62e40]> securityName , subtypeSpec , , >, encoding utf-8, payload [my-area]> 2021-08-18 11:08:31,864 pysnmp: prepareDataElements: received PDU request-id 384 replaced with unique ID 4758993 2021-08-18 11:08:31,864 pysnmp: prepareDataElements: cached by new stateReference 1083137 2021-08-18 11:08:31,864 pysnmp: receiveMessage: MP succeded 2021-08-18 11:08:31,864 pysnmp: receiveMessage: PDU GetNextRequestPDU: request-id=4758993 error-status=noError error-index=0 variable-bindings=VarBindList: VarBind: name=1.1.1234.2.1.1.1.2 =_BindValue: unSpecified= 2021-08-18 11:08:31,864 pysnmp: receiveMessage: pduType 2021-08-18 11:08:31,864 pysnmp: processPdu: stateReference 1083137, varBinds [(, payload [1.1.1234.2.1.1.1.2]>, , subtypeSpec >, encoding iso-8859-1, payload []>)] 2021-08-18 11:08:31,864 pysnmp: getMibInstrum: contextName b'', mibInstum 2021-08-18 11:08:31,866 pysnmp: __indexMib: rebuilt 2021-08-18 11:08:31,867 pysnmp: flipFlopFsm: input var-binds [(, payload [1.1.1234.2.1.1.1.2]>, , subtypeSpec >, encoding iso-8859-1, payload []>)] 2021-08-18 11:08:31,867 pysnmp: flipFlopFsm: state start status ok -> fsmState readTestNext 2021-08-18 11:08:31,867 pysnmp: isAccessAllowed: securityModel 2, securityName my-area, securityLevel 1, viewType read, contextName for variableName (1, 1, 1234, 2, 1, 1, 1, 2) 2021-08-18 11:08:31,868 pysnmp: flipFlopFsm: fun suceeded for 1.1.1234.2.1.1.1.2=, subtypeSpec >, encoding iso-8859-1, payload []> 2021-08-18 11:08:31,868 pysnmp: flipFlopFsm: state readTestNext status ok -> fsmState readGetNext 2021-08-18 11:08:31,868 pysnmp: isAccessAllowed: securityModel 2, securityName my-area, securityLevel 1, viewType read, contextName for variableName (1, 1, 1234, 2, 1, 1, 1, 2) 2021-08-18 11:08:31,868 pysnmp: readGetNext: (1, 1, 1234, 2, 1, 1, 1, 2, 0)=, subtypeSpec , >, encoding iso-8859-1, payload [Test 1]> 2021-08-18 11:08:31,868 pysnmp: readGet: (1, 1, 1234, 2, 1, 1, 1, 2, 0)=, subtypeSpec , >, encoding iso-8859-1, payload [Test 1]> 2021-08-18 11:08:31,870 pysnmp: getValue: returning , subtypeSpec , >, encoding iso-8859-1, payload [Test 1]> for (1, 1, 1234, 2, 1, 1, 1, 2, 0) 2021-08-18 11:08:31,870 pysnmp: flipFlopFsm: fun suceeded for 1.1.1234.2.1.1.1.2=, subtypeSpec >, encoding iso-8859-1, payload []> 2021-08-18 11:08:31,870 pysnmp: flipFlopFsm: state readGetNext status ok -> fsmState stop 2021-08-18 11:08:31,870 pysnmp: sendVarBinds: stateReference 1083137, errorStatus 0, errorIndex 0, varBinds [((1, 1, 1234, 2, 1, 1, 1, 2, 0), , subtypeSpec , >, encoding iso-8859-1, payload [Test 1]>)] 2021-08-18 11:08:31,870 pysnmp: returnResponsePdu: PDU ResponsePDU: request-id=4758993 error-status=noError error-index=0 variable-bindings=VarBindList: VarBind: name=1.1.1234.2.1.1.1.2.0 =_BindValue: value=ObjectSyntax: simple=SimpleSyntax: string-value=Test 1 2021-08-18 11:08:31,870 pysnmp: prepareResponseMessage: cache read msgID 4758993 transportDomain (1, 3, 6, 1, 6, 1, 1) transportAddress ('127.0.0.1', 59937) by stateReference 1083137 2021-08-18 11:08:31,871 pysnmp: prepareResponseMessage: using contextEngineId , subtypeSpec , >, encoding iso-8859-1, payload [0x80004fb805646f...6e6e6572f1b62e40]> contextName b'' 2021-08-18 11:08:31,871 pysnmp: generateResponseMsg: recovered community , encoding iso-8859-1, payload [public]> by securityStateReference 5169481 2021-08-18 11:08:31,871 pysnmp: generateResponseMsg: Message: version=version-2c community=public data=PDUs: response=ResponsePDU: request-id=384 error-status=noError error-index=0 variable-bindings=VarBindList: VarBind: name=1.1.1234.2.1.1.1.2.0 =_BindValue: value=ObjectSyntax: simple=SimpleSyntax: string-value=Test 1 2021-08-18 11:08:31,871 pysnmp: returnResponsePdu: MP suceeded 2021-08-18 11:08:31,872 pysnmp: sendMessage: sending transportAddress ('127.0.0.1', 59937) outgoingMessage 00000: 30 2E 02 01 01 04 06 70 75 62 6C 69 63 A2 21 02 00016: 02 01 80 02 01 00 02 01 00 30 15 30 13 06 09 29 00032: 89 52 02 01 01 01 02 00 04 06 54 65 73 74 20 31 2021-08-18 11:08:31,872 pysnmp: receiveMessage: processPdu succeeded 2021-08-18 11:08:31,873 pysnmp: receiveMessage: msgVersion 1, msg decoded 2021-08-18 11:08:31,874 pysnmp: prepareDataElements: Message: version=version-2c community=public data=PDUs: get-next-request=GetNextRequestPDU: request-id=385 error-status=noError error-index=0 variable-bindings=VarBindList: VarBind: name=1.1.1234.2.1.1.1.2.0 =_BindValue: unSpecified= 2021-08-18 11:08:31,874 pysnmp: _com2sec: securityName candidates for communityName 'public' are [(, subtypeSpec , , >, encoding utf-8, payload [my-area]>, , subtypeSpec , >, encoding iso-8859-1, payload [0x80004fb805646f...6e6e6572f1b62e40]>, , subtypeSpec , , >, encoding utf-8, payload []>)]; choosing securityName 'my-area' 2021-08-18 11:08:31,874 pysnmp: processIncomingMsg: looked up securityName , subtypeSpec , , >, encoding utf-8, payload [my-area]> securityModel 2 contextEngineId , subtypeSpec , >, encoding iso-8859-1, payload [0x80004fb805646f...6e6e6572f1b62e40]> contextName , subtypeSpec , , >, encoding utf-8, payload []> by communityName , encoding iso-8859-1, payload [public]> AND transportInformation ((1, 3, 6, 1, 6, 1, 1), ('127.0.0.1', 59937)) 2021-08-18 11:08:31,874 pysnmp: processIncomingMsg: generated maxSizeResponseScopedPDU 65379 securityStateReference 5169482 2021-08-18 11:08:31,875 pysnmp: prepareDataElements: SM returned securityEngineId , subtypeSpec , >, encoding iso-8859-1, payload [0x80004fb805646f...6e6e6572f1b62e40]> securityName , subtypeSpec , , >, encoding utf-8, payload [my-area]> [...] 2021-08-18 11:08:31,909 pysnmp: returnResponsePdu: MP suceeded 2021-08-18 11:08:31,909 pysnmp: sendMessage: sending transportAddress ('127.0.0.1', 59937) outgoingMessage 00000: 30 33 02 01 01 04 06 70 75 62 6C 69 63 A2 26 02 00016: 02 01 82 02 01 00 02 01 00 30 1A 30 18 06 09 29 00032: 89 52 02 01 01 01 03 00 04 0B 07 E5 08 12 0B 08 00048: 1B 03 2B 02 00 2021-08-18 11:08:31,910 pysnmp: receiveMessage: processPdu succeeded ```

Crosspost on StackOverflow: https://stackoverflow.com/q/68830377/9211114