def __init__(self, client_config=None): if not client_config: client_config = conpot_config # Create SNMP engine instance self.snmpEngine = engine.SnmpEngine() # user: usr-sha-aes, auth: SHA, priv AES config.addV3User( self.snmpEngine, 'usr-sha-aes128', config.usmHMACSHAAuthProtocol, 'authkey1', config.usmAesCfb128Protocol, 'privkey1' ) config.addTargetParams(self.snmpEngine, 'my-creds', 'usr-sha-aes128', 'authPriv') # Setup transport endpoint and bind it with security settings yielding # a target name (choose one entry depending of the transport needed). # UDP/IPv4 config.addSocketTransport( self.snmpEngine, udp.domainName, udp.UdpSocketTransport().openClientMode() ) config.addTargetAddr( self.snmpEngine, 'my-router', udp.domainName, (client_config.snmp_host, client_config.snmp_port), 'my-creds' )
def cfgCmdGen(self, authData, transportTarget, tagList=''): if self.__knownAuths.has_key(authData): paramsName = self.__knownAuths[authData] else: paramsName = 'p%s' % nextID() if isinstance(authData, CommunityData): config.addV1System( self.snmpEngine, authData.securityName, authData.communityName ) config.addTargetParams( self.snmpEngine, paramsName, authData.securityName, authData.securityLevel, authData.mpModel ) elif isinstance(authData, UsmUserData): config.addV3User( self.snmpEngine, authData.securityName, authData.authProtocol, authData.authKey, authData.privProtocol, authData.privKey ) config.addTargetParams( self.snmpEngine, paramsName, authData.securityName, authData.securityLevel ) else: raise error.PySnmpError('Unsupported SNMP version') self.__knownAuths[authData] = paramsName if not self.__knownTransports.has_key(transportTarget.transportDomain): transport = transportTarget.openClientMode() config.addSocketTransport( self.snmpEngine, transportTarget.transportDomain, transport ) self.__knownTransports[transportTarget.transportDomain] = transport k = transportTarget, tagList if self.__knownTransportAddrs.has_key(k): addrName = self.__knownTransportAddrs[k] else: addrName = 'a%s' % nextID() config.addTargetAddr( self.snmpEngine, addrName, transportTarget.transportDomain, transportTarget.transportAddr, paramsName, transportTarget.timeout * 100, transportTarget.retries, tagList ) self.__knownTransportAddrs[k] = addrName return addrName, paramsName
def test2(): from pysnmp.v4.proto.rfc1902 import ObjectName from pysnmp.entity import engine, config from pysnmp.carrier.asynsock.dgram import udp from pysnmp.entity.rfc3413 import cmdgen sysName = ObjectName("1.3.6.1.2.1.1.5.0") ip = "192.168.1.9" snmp_engine = engine.SnmpEngine() config.addV1System(snmp_engine, 'test-agent', "public") config.addTargetParams(snmp_engine, 'myParams', 'test-agent', 'noAuthNoPriv', 0) config.addTargetAddr( snmp_engine, 'myRouter', config.snmpUDPDomain, (ip, 161), 'myParams' ) config.addSocketTransport( snmp_engine, udp.domainName, udp.UdpSocketTransport().openClientMode() ) cb = {} def cbFun(sendRequestHandle, errorIndication, errorStatus, errorIndex, varBinds, cbCtx): cbCtx['errorIndication'] = errorIndication cbCtx['errorStatus'] = errorStatus cbCtx['errorIndex'] = errorIndex cbCtx['varBinds'] = varBinds cmdgen.GetCommandGenerator().sendReq(snmp_engine, 'myRouter', ((sysName, None),), cbFun, cb) lastmemusage = 0 lastrefs = None errors = 0 while (errors < 2): snmp_engine.transportDispatcher.runDispatcher() print cb['varBinds'][0][1] snmp_engine.transportDispatcher.closeDispatcher() #asynCommandGenerator.flushConfig() newmemusage = resource.getrusage(resource.RUSAGE_SELF)[2] memdiff = (newmemusage - lastmemusage) newrefs = get_refcounts() if memdiff > 0: print "Leaked %d Kb... printing refcount diff" % memdiff if lastrefs == None: print "No previous refcount, skipping" else: print_ref_diffs(lastrefs, newrefs) errors = errors + 1 gc.collect() lastrefs = newrefs lastmemusage = newmemusage #print resource.getrusage(resource.RUSAGE_SELF)[3] time.sleep(1)
def __init__(self, host, port, community): self.snmp = engine.SnmpEngine() self.snmp.registerTransportDispatcher(dispatch.TwistedDispatcher()) config.addV1System(self.snmp, 'my-area', community) config.addTargetParams(self.snmp, 'my-creds', 'my-area', 'noAuthNoPriv', 0) config.addSocketTransport(self.snmp, udp.domainName, udp.UdpTwistedTransport().openClientMode() ) config.addTargetAddr(self.snmp, 'my-router', udp.domainName, (host, port), 'my-creds')
def setTrapReceiver(self, host, community): config.addV1System(self._snmpEngine, 'nms-area', community) config.addVacmUser(self._snmpEngine, 2, 'nms-area', 'noAuthNoPriv', notifySubTree=(1, 3, 6, 1, 4, 1)) config.addTargetParams(self._snmpEngine, 'nms-creds', 'nms-area', 'noAuthNoPriv', 1) config.addTargetAddr(self._snmpEngine, 'my-nms', udp.domainName, (host, 162), 'nms-creds', tagList='all-my-managers') # set last parameter to 'notification' to have it send # informs rather than unacknowledged traps config.addNotificationTarget( self._snmpEngine, 'test-notification', 'my-filter', 'all-my-managers', 'trap')
def __init__(self, community, ip, version=1): self.__community = community self.__ip = ip self.__version = version self.__errorIndication = None self.__errorStatus = None self.__errorIndex = None self.__varBinds = None # self.__lock = threading.Lock() self.__snmp_engine = engine.SnmpEngine() config.addV1System(self.__snmp_engine, "test-agent", self.__community) config.addTargetParams(self.__snmp_engine, "myParams", "test-agent", "noAuthNoPriv", self.__version) config.addTargetAddr(self.__snmp_engine, "myRouter", config.snmpUDPDomain, (self.__ip, 161), "myParams") config.addSocketTransport(self.__snmp_engine, udp.domainName, udp.UdpSocketTransport().openClientMode())
def v3TargetName( self, engine, ip, port=161, authKey=None, privKey=None, authProtocol='MD5', privProtocol='DES', ): """Find/create target name for v1/v2 connection to given agent authProtocol -- one of None, 'MD5' or 'SHA' determining the hashing of the authorisation key (password) privProtocol -- one of None or 'DES', determining encryption of the messages sent to the agent authKey -- authorisation key (password) for the agent privKey -- key used to obscure requests from eavesdroppers """ if authKey is None: authProtocol = None if privKey is None: privProtocol = None authProtocol = self.AUTH_PROTOCOL_REGISTRY[ authProtocol ] privProtocol = self.PRIV_PROTOCOL_REGISTRY[ privProtocol ] key = ( authProtocol, authKey, privProtocol, privKey ) paramName = self._v3paramCache.get( key ) if paramName is None: nameID = self._newV3Name() name = 'v3user-%s'%(nameID) config.addV3User( engine, name, authProtocol=authProtocol, authKey=authKey, privProtocol=privProtocol, privKey=privKey ) if authProtocol is config.usmNoAuthProtocol: paramType = "noAuthNoPriv" elif privProtocol is config.usmNoPrivProtocol: paramType = "authNoPriv" else: paramType = "authPriv" paramName = 'v3param-%s'%(nameID) config.addTargetParams( engine, paramName, name, paramType, mpModel = 3 ) self._v3paramCache[ key ] = paramName return self._targetName( engine, ip, port, paramName )
def initTarget(host='127.0.0.1', port=162, community='LIC_OSS'): #global snmpEngine, snmpContext, ntfOrg # Create SNMP engine instance snmpEngine = engine.SnmpEngine() # SecurityName <-> CommunityName mapping config.addV1System(snmpEngine, 'my-area', community) # Specify security settings per SecurityName (SNMPv2c -> 1) config.addTargetParams(snmpEngine, 'my-creds', 'my-area', 'noAuthNoPriv', 1) # Setup transport endpoint and bind it with security settings yielding # a target name config.addSocketTransport( snmpEngine, udp.domainName, udp.UdpSocketTransport().openClientMode() ) config.addTargetAddr( snmpEngine, 'my-nms', udp.domainName, (host, port), 'my-creds', tagList='all-my-managers' ) # Specify what kind of notification should be sent (TRAP or INFORM), # to what targets (chosen by tag) and what filter should apply to # the set of targets (selected by tag) config.addNotificationTarget( snmpEngine, 'my-notification', 'my-filter', 'all-my-managers', 'trap' ) # Allow NOTIFY access to Agent's MIB by this SNMP model (2), securityLevel # and SecurityName config.addContext(snmpEngine, '') config.addVacmUser(snmpEngine, 2, 'my-area', 'noAuthNoPriv', (), (), (1,3,6)) # *** SNMP engine configuration is complete by this line *** # Create default SNMP context where contextEngineId == SnmpEngineId snmpContext = context.SnmpContext(snmpEngine) # Create Notification Originator App instance. ntfOrg = ntforg.NotificationOriginator(snmpContext) return snmpEngine, ntfOrg
def __init__(self): self.unReadyNodes = list() self.identifiers = dict() self.snmpEngine = engine.SnmpEngine() self.bcmdgen = cmdgen.BulkCommandGenerator() self.snmpEngine.registerTransportDispatcher(dispatch.TwistedDispatcher()) config.addV1System(self.snmpEngine, 'test-agent', SNMP_COMMUNITY) config.addTargetParams(self.snmpEngine, 'myParams', 'test-agent', 'noAuthNoPriv', 1) config.addSocketTransport( self.snmpEngine, udp.domainName, udp.UdpTwistedTransport().openClientMode() ) self.carbonFact = CarbonFactory(self) reactor.connectTCP(GRAPHITE_HOST, 2003, self.carbonFact)
def main(argv): # Create SNMP engine instance snmpEngine = engine.SnmpEngine() dispatcher = TornadoDispatcher() snmpEngine.registerTransportDispatcher(dispatcher) # SecurityName <-> CommunityName mapping config.addV1System(snmpEngine, 'my-area', 'public') # Specify security settings per SecurityName (SNMPv1 - 0, SNMPv2c - 1) config.addTargetParams(snmpEngine, 'my-creds', 'my-area', 'noAuthNoPriv', 1) # UDP/IPv4 config.addSocketTransport( snmpEngine, udp.domainName, udp.UdpSocketTransport().openClientMode() ) config.addTargetAddr( snmpEngine, 'my-router', udp.domainName, (argv[0], 161), 'my-creds', timeout=3.0, retryCount=1 ) cbCtx = dict(dispatcher=dispatcher) cmdGen = cmdgen.GetCommandGenerator() cmdGen.sendReq( snmpEngine, 'my-router', ( ('1.3.6.1.2.1.1.1.0', None), ), cbFun, cbCtx ) IOLoop.instance().start()
def v1TargetName( self, engine, ip, port=161, community='public', snmpVersion='2', ): """Find/create target name for v1/v2 connection to given agent""" key = (community,snmpVersion=='1') paramName = self._v1ParamCache.get( key ) if paramName is None: nameID = self._newV1Name() name = 'v1sys-%s'%(nameID) config.addV1System(engine, name, community) paramName = 'v1param-%s'%(nameID) if snmpVersion == '1': version = 0 else: version = 1 config.addTargetParams( engine, paramName, name, 'noAuthNoPriv', version ) self._v1ParamCache[ key ] = paramName return self._targetName( engine, ip, port, paramName )
def __init__(self, host, port, username, password, snmp_context): self.snmp_context = snmp_context self.snmp_engine = engine.SnmpEngine() # HiT7300 uses the user password for encryption (privacy protocol) pass phrase (PSK?) config.addV3User( self.snmp_engine, username, config.usmHMACMD5AuthProtocol, password, config.usmAesCfb128Protocol, password ) # pysnmp bug? # setting context doesn't affect the getCommandGenerator, so we don't set it # FIXME: report upstream and have cmdgen use context of snmpEngine!? # config.addContext(self.snmp_engine, 'tnms') # snmp_context = context.SnmpContext(self.snmp_engine) config.addTargetParams(self.snmp_engine, "myParams", username, "authPriv") # config.addTargetParams(self.snmp_engine, 'myParams', username, 'authPriv') config.addTargetAddr(self.snmp_engine, "myTarget", config.snmpUDPDomain, (host, int(port)), "myParams") config.addSocketTransport(self.snmp_engine, udp.domainName, udp.UdpSocketTransport().openClientMode()) self.cbCtx = {}
# # SNMPv3/USM setup (Manager role) # # user: usr-md5-none, auth: MD5, priv NONE config.addV3User( snmpEngine, 'usr-md5-none', config.usmHMACMD5AuthProtocol, 'authkey1' ) # # Transport target used by Manager # config.addTargetParams( snmpEngine, 'distant-agent-auth', 'usr-md5-none', 'authNoPriv' ) config.addTargetAddr( snmpEngine, 'distant-agent', udp.domainName + (2,), ('195.218.195.228', 161), 'distant-agent-auth', retryCount=0 ) # Default SNMP context config.addContext(snmpEngine, '') class CommandResponder(cmdrsp.CommandResponderBase): cmdGenMap = { v2c.GetRequestPDU.tagSet: cmdgen.GetCommandGenerator(), v2c.SetRequestPDU.tagSet: cmdgen.SetCommandGenerator(), v2c.GetNextRequestPDU.tagSet: cmdgen.NextCommandGeneratorSingleRun(),
initialOID = rfc1902.ObjectName('1.3.6.1.2.1.1') # Create SNMP engine instance snmpEngine = engine.SnmpEngine() # # SNMPv3/USM setup # # user: usr-none-none, auth: none, priv: none config.addV3User( snmpEngine, 'usr-none-none', ) config.addTargetParams(snmpEngine, 'my-creds', 'usr-none-none', 'noAuthNoPriv') # # Setup transport endpoint and bind it with security settings yielding # a target name # # UDP/IPv4 config.addTransport(snmpEngine, udp.DOMAIN_NAME, udp.UdpSocketTransport().openClientMode()) config.addTargetAddr(snmpEngine, 'my-router', udp.DOMAIN_NAME, ('104.236.166.95', 161), 'my-creds') # Error/response receiver
def trigger_trap(temp): # Create SNMP engine instance snmpEngine = engine.SnmpEngine() # SecurityName <-> CommunityName mapping config.addV1System(snmpEngine, 'my-area', 'federated') # Specify security settings per SecurityName (SNMPv2c -> 1) config.addTargetParams(snmpEngine, 'my-creds', 'my-area', 'noAuthNoPriv', 1) # Setup transport endpoint and bind it with security settings yielding # a target name config.addSocketTransport( snmpEngine, udp.domainName, udp.UdpSocketTransport().openClientMode() ) config.addTargetAddr( snmpEngine, 'my-nms', udp.domainName, ('34.215.95.184', 162), 'my-creds', tagList='all-my-managers' ) # Specify what kind of notification should be sent (TRAP or INFORM), # to what targets (chosen by tag) and what filter should apply to # the set of targets (selected by tag) config.addNotificationTarget( snmpEngine, 'my-notification', 'my-filter', 'all-my-managers', 'trap' ) # Allow NOTIFY access to Agent's MIB by this SNMP model (2), securityLevel # and SecurityName config.addContext(snmpEngine, '') config.addVacmUser(snmpEngine, 2, 'my-area', 'noAuthNoPriv', (), (), (1,3,6)) # *** SNMP engine configuration is complete by this line *** # Create default SNMP context where contextEngineId == SnmpEngineId snmpContext = context.SnmpContext(snmpEngine) # Create Notification Originator App instance. ntfOrg = ntforg.NotificationOriginator(snmpContext) # Build and submit notification message to dispatcher ntfOrg.sendNotification( snmpEngine, # Notification targets 'my-notification', # Trap OID (SNMPv2-MIB::coldStart) #(1,3,6,1,6,3,1,1,5,1), (1,3,6,1,4,1,8072,2,7,1,1,1,1,3,1), # ( (oid, value), ... ) ( ((1,3,6,1,4,1,8072,2,7,1,1,1,1,3,1), v2c.OctetString(temp)), ((1,3,6,1,2,1,1,5,0), v2c.OctetString('Reason: Admin brought down')) ) ) print('Notification is scheduled to be sent') # Run I/O dispatcher which would send pending message and process response snmpEngine.transportDispatcher.runDispatcher()
def snmpv3_getbulk(ip='',user='',hash_meth=None,hash_key=None,cry_meth=None,cry_key=None,oid='',num=10): #usmHMACMD5AuthProtocol - MD5 hashing #usmHMACSHAAuthProtocol - SHA hashing #usmNoAuthProtocol - no authentication #usmDESPrivProtocol - DES encryption #usm3DESEDEPrivProtocol - triple-DES encryption #usmAesCfb128Protocol - AES encryption, 128-bit #usmAesCfb192Protocol - AES encryption, 192-bit #usmAesCfb256Protocol - AES encryption, 256-bit #usmNoPrivProtocol - no encryption global maxRepetitions maxRepetitions = num hashval = None cryval = None model = None config.addTargetAddr(#添加目标,'yourDevice'(OID与处理方法),'my-creds'(用户,密码,安全模型),目的IP与端口号 snmpEngine, 'yourDevice', udp.domainName, (ip, 161), 'my-creds' ) #========================下面的操作在判断安全模型========================== #NoAuthNoPriv if hash_meth == None and cry_meth == None: hashval = config.usmNoAuthProtocol cryval = config.usmNoPrivProtocol model = 'noAuthNoPriv' #AuthNoPriv elif hash_meth != None and cry_meth == None: if hash_meth == 'md5': hashval = config.usmHMACMD5AuthProtocol elif hash_meth == 'sha': hashval = config.usmHMACSHAAuthProtocol else: print('哈希算法必须是md5 or sha!') return cryval = config.usmNoPrivProtocol model = 'authNoPriv' #AuthPriv elif hash_meth != None and cry_meth != None: if hash_meth == 'md5': hashval = config.usmHMACMD5AuthProtocol elif hash_meth == 'sha': hashval = config.usmHMACSHAAuthProtocol else: print('哈希算法必须是md5 or sha!') return if cry_meth == '3des': cryval = config.usm3DESEDEPrivProtocol elif cry_meth == 'des': cryval = config.usmDESPrivProtocol elif cry_meth == 'aes128': cryval = config.usmAesCfb128Protocol elif cry_meth == 'aes192': cryval = config.usmAesCfb192Protocol elif cry_meth == 'aes256': cryval = config.usmAesCfb256Protocol else: print('加密算法必须是3des, des, aes128, aes192 or aes256 !') return model = 'authPriv' #提供的参数不符合标准时给出提示 else: print('三种USM: NoAuthNoPriv, AuthNoPriv, AuthPriv.。请选择其中一种。') return #========================判断安全模型结束========================== config.addV3User(#添加用户与他的密钥 snmpEngine, user, hashval, hash_key, cryval, cry_key ) config.addTargetParams(snmpEngine, 'my-creds', user, model)#创建'my-creds',里边有用户和安全模型 # Prepare initial request to be sent cmdgen.BulkCommandGenerator().sendReq(snmpEngine,'yourDevice', 0, 1,((oid, None),),cbFun)#创建'yourDevice',有OID和处理方法cbFun # Run I/O dispatcher which would send pending queries and process responses snmpEngine.transportDispatcher.runDispatcher()#运行实例 return oid_list#返回oid_list
privProtocols[v3PrivProto], v3PrivKey) log.msg( 'SNMP version 3, Context EngineID: %s Context name: %s, SecurityName: %s, SecurityLevel: %s, Authentication key/protocol: %s/%s, Encryption (privacy) key/protocol: %s/%s' % (v3ContextEngineId and v3ContextEngineId.prettyPrint() or '<default>', v3Context and v3Context.prettyPrint() or '<default>', v3User, secLevel, v3AuthKey is None and '<NONE>' or v3AuthKey, v3AuthProto, v3PrivKey is None and '<NONE>' or v3PrivKey, v3PrivProto)) else: v3User = '******' secLevel = 'noAuthNoPriv' config.addV1System(snmpEngine, v3User, snmpCommunity) log.msg('SNMP version %s, Community name: %s' % (snmpVersion == 0 and '1' or '2c', snmpCommunity)) config.addTargetParams(snmpEngine, 'pms', v3User, secLevel, snmpVersion) if agentUDPv6Endpoint: config.addSocketTransport(snmpEngine, udp6.domainName, udp6.Udp6SocketTransport().openClientMode()) config.addTargetAddr(snmpEngine, 'tgt', udp6.domainName, agentUDPv6Endpoint, 'pms', timeout, retryCount) log.msg('Querying UDP/IPv6 agent at [%s]:%s' % agentUDPv6Endpoint) elif agentUNIXEndpoint: config.addSocketTransport(snmpEngine, unix.domainName, unix.UnixSocketTransport().openClientMode()) config.addTargetAddr(snmpEngine, 'tgt', unix.domainName, agentUNIXEndpoint, 'pms', timeout, retryCount) log.msg('Querying UNIX named pipe agent at %s' % agentUNIXEndpoint) elif agentUDPv4Endpoint: config.addSocketTransport(snmpEngine, udp.domainName,
# v1/2 setup config.addV1System(snmpEngine, 'dest-cmt', 'public') # v3 setup config.addV3User( snmpEngine, 'test-user', config.usmHMACMD5AuthProtocol, 'authkey1', config.usmDESPrivProtocol, 'privkey1' # config.usmAesCfb128Protocol, 'privkey1' ) # Transport targets used by Manager # Target 1, SNMPv3 setup config.addTargetParams(snmpEngine, 'v3-dest-1', 'test-user', 'authPriv') config.addTargetAddr( snmpEngine, 'tgt-v3-1', config.snmpUDPDomain + (2,), ('127.0.0.1', 161), 'v3-dest-1' ) # This is to map community to context name in incoming messages config.addV1System(snmpEngine, 'v2c-src-A', 'tgt-v3-1', contextName='tgt-v3-1') # Target 1, SNMPv2c setup config.addTargetParams(snmpEngine, 'v2c-dest-1', 'dest-cmt', 'noAuthNoPriv', 1) config.addTargetAddr( snmpEngine, 'tgt-v2c-1', config.snmpUDPDomain + (2,), ('127.0.0.1', 161), 'v2c-dest-1' ) # This is to map community to context name in incoming messages config.addV1System(snmpEngine, 'v2c-src-B', 'tgt-v2c-1', contextName='tgt-v2c-1')
def snmpv3_get(ip='', user='', hash_meth=None, hash_key=None, cry_meth=None, cry_key=None, oid=''): #usmHMACMD5AuthProtocol - MD5 hashing #usmHMACSHAAuthProtocol - SHA hashing #usmNoAuthProtocol - no authentication #usmDESPrivProtocol - DES encryption #usm3DESEDEPrivProtocol - triple-DES encryption #usmAesCfb128Protocol - AES encryption, 128-bit #usmAesCfb192Protocol - AES encryption, 192-bit #usmAesCfb256Protocol - AES encryption, 256-bit #usmNoPrivProtocol - no encryption hashval = None cryval = None model = None config.addTargetAddr(snmpEngine, 'yourDevice', udp.domainName, (ip, 161), 'my-creds') #NoAuthNoPriv if hash_meth == None and cry_meth == None: hashval = config.usmNoAuthProtocol cryval = config.usmNoPrivProtocol model = 'noAuthNoPriv' #AuthNoPriv elif hash_meth != None and cry_meth == None: if hash_meth == 'md5': hashval = config.usmHMACMD5AuthProtocol elif hash_meth == 'sha': hashval = config.usmHMACSHAAuthProtocol else: print('哈希算法必须是md5 or sha!') return cryval = config.usmNoPrivProtocol model = 'authNoPriv' #AuthPriv elif hash_meth != None and cry_meth != None: if hash_meth == 'md5': hashval = config.usmHMACMD5AuthProtocol elif hash_meth == 'sha': hashval = config.usmHMACSHAAuthProtocol else: print('哈希算法必须是md5 or sha!') return if cry_meth == '3des': cryval = config.usm3DESEDEPrivProtocol elif cry_meth == 'des': cryval = config.usmDESPrivProtocol elif cry_meth == 'aes128': cryval = config.usmAesCfb128Protocol elif cry_meth == 'aes192': cryval = config.usmAesCfb192Protocol elif cry_meth == 'aes256': cryval = config.usmAesCfb256Protocol else: print('加密算法必须是3des, des, aes128, aes192 or aes256 !') return model = 'authPriv' #提供的参数不符合标准时给出提示 else: print('三种USM: NoAuthNoPriv, AuthNoPriv, AuthPriv.。请选择其中一种。') return config.addV3User(snmpEngine, user, hashval, hash_key, cryval, cry_key) config.addTargetParams(snmpEngine, 'my-creds', user, model) # Prepare and send a request message cmdgen.GetCommandGenerator().sendReq(snmpEngine, 'yourDevice', ((oid, None), ), cbFun) # Run I/O dispatcher which would send pending queries and process responses snmpEngine.transportDispatcher.runDispatcher() return oid_list
from pysnmp.entity import engine, config from pysnmp.carrier.asynsock.dgram import udp from pysnmp.entity.rfc3413 import ntforg, context from pysnmp.proto.api import v2c # Create SNMP engine instance snmpEngine = engine.SnmpEngine() # SecurityName <-> CommunityName mapping config.addV1System(snmpEngine, 'my-area', 'public') # Specify security settings per SecurityName (SNMPv2c -> 1) config.addTargetParams(snmpEngine, 'my-creds', 'my-area', 'noAuthNoPriv', 1) # Setup transport endpoint and bind it with security settings yielding # a target name config.addSocketTransport(snmpEngine, udp.domainName, udp.UdpSocketTransport().openClientMode()) config.addTargetAddr(snmpEngine, 'my-nms', udp.domainName, ('10.135.32.108', 162), 'my-creds', tagList='all-my-managers') # Specify what kind of notification should be sent (TRAP or INFORM), # to what targets (chosen by tag) and what filter should apply to # the set of targets (selected by tag) config.addNotificationTarget(snmpEngine, 'my-notification', 'my-filter', 'all-my-managers', 'trap') # Allow NOTIFY access to Agent's MIB by this SNMP model (2), securityLevel
for coms in systems.values(): test = coms['device_community'] + '-' + coms['version'] if securityMappings.count(test) < 1: securityMappings.append(test) if coms['version'] == '1' or coms['version'] == '2c': bename = 'bea-v12-' + coms['device_community'] #securityname = 'beaa-' + coms['version'] + '-' + coms['device_community'] config.addV1System(snmpEngine, bename, coms['device_community']) print 'config.addV1System() ' + bename + ' community: ' + coms[ 'device_community'] if coms['version'] == '1': securityname = 'beaa-' + coms['version'] + '-' + coms[ 'device_community'] config.addTargetParams(snmpEngine, securityname, bename, 'noAuthNoPriv', 0) print 'Add Target Params::v1::' + securityname + '::' + bename else: securityname = 'beaa-' + coms['version'] + '-' + coms[ 'device_community'] config.addTargetParams(snmpEngine, securityname, bename, 'noAuthNoPriv', 1) print 'Add Target Params::v2c::' + securityname + '::' + bename else: bename = 'backend-area-v3-' + coms['authUser'] securityname = coms['version'] + '-' + coms['authUser'] + '-auth' #Add systems for coms in systems.values(): securityname = 'beaa-' + coms['version'] + '-' + coms['device_community'] config.addTargetAddr(snmpEngine,
"""# from pysnmp.entity import engine, config from pysnmp.carrier.asyncore.dgram import udp from pysnmp.entity.rfc3413 import ntforg from pysnmp.proto.api import v2c # Create SNMP engine instance snmpEngine = engine.SnmpEngine() # SNMPv2c: # SecurityName <-> CommunityName mapping config.addV1System(snmpEngine, 'my-area', 'public', transportTag='all-my-managers') # Specify security settings per SecurityName (SNMPv2c -> 1) config.addTargetParams(snmpEngine, 'my-creds-1', 'my-area', 'noAuthNoPriv', 1) # SNMPv3: config.addV3User( snmpEngine, 'usr-md5-none', config.usmHMACMD5AuthProtocol, 'authkey1' ) config.addTargetParams(snmpEngine, 'my-creds-2', 'usr-md5-none', 'authNoPriv') # Setup transport endpoint and bind it with security settings yielding # a target name config.addTransport( snmpEngine, udp.domainName, udp.UdpSocketTransport().openClientMode()
# from pysnmp.entity import engine, config from pysnmp.carrier.asynsock.dgram import udp from pysnmp.entity.rfc3413 import cmdgen # Create SNMP engine instance snmpEngine = engine.SnmpEngine() # # SNMPv3/USM setup # # user: usr-sha-aes, auth: SHA, priv AES config.addV3User(snmpEngine, 'usr-sha-aes', config.usmHMACSHAAuthProtocol, 'authkey1', config.usmAesCfb128Protocol, 'privkey1') config.addTargetParams(snmpEngine, 'my-creds', 'usr-sha-aes', 'authPriv') # # Setup transport endpoint and bind it with security settings yielding # a target name # # UDP/IPv4 config.addTransport(snmpEngine, udp.domainName, udp.UdpSocketTransport().openClientMode()) config.addTargetAddr(snmpEngine, 'my-router', udp.domainName, ('195.218.195.228', 161), 'my-creds') # Error/response receiver def cbFun(sendRequestHandle, errorIndication, errorStatus, errorIndex,
def configure(self, snmpEngine, authData, transportTarget, *options): cache = self._getCache(snmpEngine) if isinstance(authData, CommunityData): if authData.communityIndex not in cache['auth']: config.addV1System(snmpEngine, authData.communityIndex, authData.communityName, authData.contextEngineId, authData.contextName, authData.tag, authData.securityName) cache['auth'][authData.communityIndex] = authData elif isinstance(authData, UsmUserData): authDataKey = authData.userName, authData.securityEngineId if authDataKey not in cache['auth']: config.addV3User(snmpEngine, authData.userName, authData.authProtocol, authData.authKey, authData.privProtocol, authData.privKey, authData.securityEngineId, securityName=authData.securityName) cache['auth'][authDataKey] = authData else: raise error.PySnmpError('Unsupported authentication object') paramsKey = (authData.securityName, authData.securityLevel, authData.mpModel) if paramsKey in cache['parm']: paramsName, useCount = cache['parm'][paramsKey] cache['parm'][paramsKey] = paramsName, useCount + 1 else: paramsName = 'p%s' % self.nextID() config.addTargetParams(snmpEngine, paramsName, authData.securityName, authData.securityLevel, authData.mpModel) cache['parm'][paramsKey] = paramsName, 1 if transportTarget.transportDomain in cache['tran']: transport, useCount = cache['tran'][ transportTarget.transportDomain] transportTarget.verifyDispatcherCompatibility(snmpEngine) cache['tran'][ transportTarget.transportDomain] = transport, useCount + 1 elif config.getTransport(snmpEngine, transportTarget.transportDomain): transportTarget.verifyDispatcherCompatibility(snmpEngine) else: transport = transportTarget.openClientMode() config.addTransport(snmpEngine, transportTarget.transportDomain, transport) cache['tran'][transportTarget.transportDomain] = transport, 1 transportKey = (paramsName, transportTarget.transportDomain, transportTarget.transportAddr, transportTarget.tagList) if transportKey in cache['addr']: addrName, useCount = cache['addr'][transportKey] cache['addr'][transportKey] = addrName, useCount + 1 else: addrName = 'a%s' % self.nextID() config.addTargetAddr(snmpEngine, addrName, transportTarget.transportDomain, transportTarget.transportAddr, paramsName, transportTarget.timeout * 100, transportTarget.retries, transportTarget.tagList) cache['addr'][transportKey] = addrName, 1 return addrName, paramsName
def setTrapReceiver(self, host, community): config.addV1System(self._snmpEngine, 'nms-area',community) config.addVacmUser(self._snmpEngine, 2, 'nms-area','noAuthNoPriv', notifySubTree=(1,3,6,1,4,1)) config.addTargetParams(self._snmpEngine, 'nms-creds', 'nms-area','noAuthNoPriv',1) config.addTargetAddr(self._snmpEngine, 'my-nms', udp.domainName, (host, 162), 'nms-creds',tagList = 'all-my-managers') config.addNotificationTarget(self._snmpEngine, 'test-notification', 'my-filter', 'all-my-managers', 'trap')
def snmpv3_get(ip='', user='', hash_meth=None, hash_key=None, cry_meth=None, cry_key=None, oid=''): # usmHMACMD5AuthProtocol - MD5 hashing # usmHMACSHAAuthProtocol - SHA hashing # usmNoAuthProtocol - no authentication # usmDESPrivProtocol - DES encryption # usm3DESEDEPrivProtocol - triple-DES encryption # usmAesCfb128Protocol - AES encryption, 128-bit # usmAesCfb192Protocol - AES encryption, 192-bit # usmAesCfb256Protocol - AES encryption, 256-bit # usmNoPrivProtocol - no encryption # 添加目标,'yourDevice'(OID与处理方法),'my-creds'(用户,密码,安全模型),目的IP与端口号 config.addTargetAddr(snmpEngine, 'yourDevice', udp.domainName, (ip, 161), 'my-creds') # ========================下面的操作在判断安全模型========================== # NoAuthNoPriv if hash_meth is None and cry_meth is None: hashval = config.usmNoAuthProtocol # 配置HASH算法 cryval = config.usmNoPrivProtocol # 配置加密算法 model = 'noAuthNoPriv' # 配置安全模式 # AuthNoPriv elif hash_meth is not None and cry_meth is None: # 配置HASH算法 if hash_meth == 'md5': hashval = config.usmHMACMD5AuthProtocol elif hash_meth == 'sha': hashval = config.usmHMACSHAAuthProtocol else: print('哈希算法必须是md5 or sha!') return cryval = config.usmNoPrivProtocol # 配置加密算法 model = 'authNoPriv' # 配置安全模式 # AuthPriv elif hash_meth is not None and cry_meth is not None: # 配置HASH算法 if hash_meth == 'md5': hashval = config.usmHMACMD5AuthProtocol elif hash_meth == 'sha': hashval = config.usmHMACSHAAuthProtocol else: print('哈希算法必须是md5 or sha!') return # 配置加密算法 if cry_meth == '3des': cryval = config.usm3DESEDEPrivProtocol elif cry_meth == 'des': cryval = config.usmDESPrivProtocol elif cry_meth == 'aes128': cryval = config.usmAesCfb128Protocol elif cry_meth == 'aes192': cryval = config.usmAesCfb192Protocol elif cry_meth == 'aes256': cryval = config.usmAesCfb256Protocol else: print('加密算法必须是3des, des, aes128, aes192 or aes256 !') return model = 'authPriv' # 配置安全模式 # 提供的参数不符合标准时给出提示 else: print('三种USM: NoAuthNoPriv, AuthNoPriv, AuthPriv.。请选择其中一种。') return # ========================判断安全模型结束========================== # 添加用户与他的密钥 config.addV3User(snmpEngine, user, hashval, hash_key, cryval, cry_key) config.addTargetParams(snmpEngine, 'my-creds', user, model) # 创建'my-creds',里边有用户和安全模型 # Prepare and send a request message # 创建'yourDevice',有OID和处理方法cbFun cmdgen.GetCommandGenerator().sendReq(snmpEngine, 'yourDevice', ((oid, None), ), cb_fun) # Run I/O dispatcher which would send pending queries and process responses snmpEngine.transportDispatcher.runDispatcher() # 运行实例 return oid_list # 返回oid_list
from pysnmp.proto.api import v2c snmpEngine = engine.SnmpEngine() # v1/2 setup config.addV1System(snmpEngine, 'test-agent', 'public') # v3 setup config.addV3User( snmpEngine, 'test-user', config.usmHMACMD5AuthProtocol, 'authkey1', config.usmDESPrivProtocol, 'privkey1' ) # Transport params config.addTargetParams(snmpEngine, 'myParams', 'test-user', 'authPriv') #config.addTargetParams(snmpEngine, 'myParams', 'test-agent', 'noAuthNoPriv', 0) # Transport addresses config.addTargetAddr( snmpEngine, 'myNMS', config.snmpUDPDomain, ('127.0.0.1', 162), 'myParams', tagList='myManagementStations' ) # Notification targets config.addNotificationTarget( # snmpEngine, 'myNotifyName', 'myParams', 'myManagementStations', 'trap' snmpEngine, 'myNotifyName', 'myParams', 'myManagementStations', 'inform' ) # Setup transport endpoint
from pysnmp.carrier.asynsock.dgram import udp from pysnmp.entity.rfc3413 import cmdgen from pysnmp.proto import rfc1902 # Create SNMP engine instance snmpEngine = engine.SnmpEngine() # # SNMPv1 setup # # SecurityName <-> CommunityName mapping config.addV1System(snmpEngine, 'my-area', 'private') # Specify security settings per SecurityName (SNMPv1 - 0, SNMPv2c - 1) config.addTargetParams(snmpEngine, 'my-creds', 'my-area', 'noAuthNoPriv', 0) # # Setup transport endpoint and bind it with security settings yielding # a target name # # UDP/IPv4 config.addTransport( snmpEngine, udp.domainName, udp.UdpSocketTransport().openClientMode() ) config.addTargetAddr( snmpEngine, 'my-router', udp.domainName, ('195.218.195.228', 161),
"""# from pysnmp.entity import engine, config from pysnmp.carrier.asyncore.dgram import udp from pysnmp.entity.rfc3413 import ntforg from pysnmp.proto.api import v2c # Create SNMP engine instance snmpEngine = engine.SnmpEngine() # SNMPv2c: # SecurityName <-> CommunityName mapping config.addV1System(snmpEngine, 'my-area', 'public', transportTag='all-my-managers') # Specify security settings per SecurityName (SNMPv2c -> 1) config.addTargetParams(snmpEngine, 'my-creds-1', 'my-area', 'noAuthNoPriv', 1) # SNMPv3: config.addV3User( snmpEngine, 'usr-md5-none', config.usmHMACMD5AuthProtocol, 'authkey1' ) config.addTargetParams(snmpEngine, 'my-creds-2', 'usr-md5-none', 'authNoPriv') # Setup transport endpoint and bind it with security settings yielding # a target name config.addTransport( snmpEngine, udp.domainName, udp.UdpSocketTransport().openClientMode()
# Initial OID prefix initialOID = rfc1902.ObjectName('1.3.6.1.2.1.1') # Create SNMP engine instance snmpEngine = engine.SnmpEngine() # # SNMPv3/USM setup # # user: usr-none-none, auth: none, priv: none config.addV3User( snmpEngine, 'usr-none-none', ) config.addTargetParams(snmpEngine, 'my-creds', 'usr-none-none', 'noAuthNoPriv') # # Setup transport endpoint and bind it with security settings yielding # a target name # # UDP/IPv4 config.addTransport( snmpEngine, udp.domainName, udp.UdpSocketTransport().openClientMode() ) config.addTargetAddr( snmpEngine, 'my-router', udp.domainName, ('195.218.195.228', 161),
def cfgCmdGen(self, authData, transportTarget, tagList=null): if authData not in self.__knownAuths: if isinstance(authData, CommunityData): config.addV1System( self.snmpEngine, authData.securityName, authData.communityName, authData.contextEngineId, authData.contextName, tagList ) elif isinstance(authData, UsmUserData): config.addV3User( self.snmpEngine, authData.securityName, authData.authProtocol, authData.authKey, authData.privProtocol, authData.privKey, authData.contextEngineId ) else: raise error.PySnmpError('Unsupported authentication object') self.__knownAuths[authData] = 1 k = authData.securityName, authData.securityLevel, authData.mpModel if k in self.__knownParams: paramsName = self.__knownParams[k] else: paramsName = 'p%s' % nextID() config.addTargetParams( self.snmpEngine, paramsName, authData.securityName, authData.securityLevel, authData.mpModel ) self.__knownParams[k] = paramsName if transportTarget.transportDomain not in self.__knownTransports: transport = transportTarget.openClientMode() config.addSocketTransport( self.snmpEngine, transportTarget.transportDomain, transport ) self.__knownTransports[transportTarget.transportDomain] = transport k = paramsName, transportTarget, tagList if k in self.__knownTransportAddrs: addrName = self.__knownTransportAddrs[k] else: addrName = 'a%s' % nextID() config.addTargetAddr( self.snmpEngine, addrName, transportTarget.transportDomain, transportTarget.transportAddr, paramsName, transportTarget.timeout * 100, transportTarget.retries, tagList ) self.__knownTransportAddrs[k] = addrName return addrName, paramsName
def main(): class LogString(LazyLogString): GROUPINGS = [ ['callflow-id'], ['trunk-id'], [ 'server-snmp-engine-id', 'server-snmp-transport-domain', 'server-snmp-peer-address', 'server-snmp-peer-port', 'server-snmp-bind-address', 'server-snmp-bind-port', 'server-snmp-security-model', 'server-snmp-security-level', 'server-snmp-security-name', 'server-snmp-context-engine-id', 'server-snmp-context-name', 'server-snmp-pdu', 'server-snmp-entity-id' ], [ 'server-snmp-credentials-id', 'server-snmp-context-id', 'server-snmp-content-id', 'server-snmp-peer-id', 'server-classification-id' ], [ 'snmp-peer-id', 'snmp-bind-address', 'snmp-bind-port', 'snmp-peer-address', 'snmp-peer-port', 'snmp-context-engine-id', 'snmp-context-name', 'snmp-pdu' ], ] FORMATTERS = { 'server-snmp-pdu': LazyLogString.prettyVarBinds, 'snmp-pdu': LazyLogString.prettyVarBinds, } def snmpCbFun(snmpEngine, sendRequestHandle, errorIndication, rspPDU, cbCtx): trunkId, msgId, trunkReq, pluginIdList, reqCtx = cbCtx trunkRsp = { 'callflow-id': trunkReq['callflow-id'], 'snmp-pdu': rspPDU, } logCtx = LogString(trunkRsp) if errorIndication: log.info('received SNMP error-indication "%s"' % errorIndication, ctx=logCtx) trunkRsp['error-indication'] = errorIndication if rspPDU: reqPdu = trunkReq['server-snmp-pdu'] for pluginId in pluginIdList: if reqPdu.tagSet in rfc3411.notificationClassPDUs: st, rspPDU = pluginManager.processNotificationResponse( pluginId, snmpEngine, rspPDU, trunkReq, reqCtx) elif reqPdu.tagSet not in rfc3411.unconfirmedClassPDUs: st, rspPDU = pluginManager.processCommandResponse( pluginId, snmpEngine, rspPDU, trunkReq, reqCtx) else: log.error('ignoring unsupported PDU', ctx=logCtx) break if st == status.BREAK: log.debug('plugin %s inhibits other plugins' % pluginId, ctx=logCtx) break elif st == status.DROP: log.debug( 'received SNMP %s, plugin %s muted response' % (errorIndication and 'error' or 'response', pluginId), ctx=logCtx) trunkRsp['snmp-pdu'] = None break try: trunkingManager.sendRsp(trunkId, msgId, trunkRsp) except SnmpfwdError: log.error('received SNMP %s message, trunk message not sent "%s"' % (msgId, sys.exc_info()[1]), ctx=logCtx) return log.debug('received SNMP %s message, forwarded as trunk message #%s' % (errorIndication and 'error' or 'response', msgId), ctx=logCtx) # # The following needs proper support in pysnmp. Meanwhile - monkey patching! # def makeTargetAddrOverride(targetAddr): endpoints = [] def getTargetAddr(snmpEngine, snmpTargetAddrName): addrInfo = list(targetAddr(snmpEngine, snmpTargetAddrName)) if endpoints: peerAddr, bindAddr = endpoints.pop(), endpoints.pop() try: addrInfo[1] = addrInfo[1].__class__( peerAddr).setLocalAddress(bindAddr) except Exception: raise PySnmpError( 'failure replacing bind address %s -> %s for transport ' 'domain %s' % (addrInfo[1], bindAddr, addrInfo[0])) return addrInfo def updateEndpoints(bindAddr, peerAddr): endpoints.extend((bindAddr, peerAddr)) return getTargetAddr, updateEndpoints lcd.getTargetAddr, updateEndpoints = makeTargetAddrOverride( lcd.getTargetAddr) def trunkCbFun(trunkId, msgId, trunkReq): for key in tuple(trunkReq): if key != 'callflow-id': trunkReq['server-' + key] = trunkReq[key] del trunkReq[key] trunkReq['trunk-id'] = trunkId k = [ str(x) for x in (trunkReq['server-snmp-engine-id'], trunkReq['server-snmp-transport-domain'], trunkReq['server-snmp-peer-address'] + ':' + str(trunkReq['server-snmp-peer-port']), trunkReq['server-snmp-bind-address'] + ':' + str(trunkReq['server-snmp-bind-port']), trunkReq['server-snmp-security-model'], trunkReq['server-snmp-security-level'], trunkReq['server-snmp-security-name'], trunkReq['server-snmp-context-engine-id'], trunkReq['server-snmp-context-name']) ] k.append(snmpPduTypesMap.get(trunkReq['server-snmp-pdu'].tagSet, '?')) k.append('|'.join([ str(x[0]) for x in v2c.apiPDU.getVarBinds(trunkReq['server-snmp-pdu']) ])) k = '#'.join(k) for x, y in origCredIdList: if y.match(k): origPeerId = trunkReq[ 'server-snmp-entity-id'] = macro.expandMacro(x, trunkReq) break else: origPeerId = None k = [ str(x) for x in (trunkReq['server-snmp-credentials-id'], trunkReq['server-snmp-context-id'], trunkReq['server-snmp-content-id'], trunkReq['server-snmp-peer-id']) ] k = '#'.join(k) for x, y in srvClassIdList: if y.match(k): srvClassId = trunkReq[ 'server-classification-id'] = macro.expandMacro( x, trunkReq) break else: srvClassId = None logCtx = LogString(trunkReq) errorIndication = None peerIdList = routingMap.get( (origPeerId, srvClassId, macro.expandMacro(trunkId, trunkReq))) if not peerIdList: log.error('unroutable trunk message #%s' % msgId, ctx=logCtx) errorIndication = 'no route to SNMP peer configured' cbCtx = trunkId, msgId, trunkReq, (), {} if errorIndication: snmpCbFun(None, None, errorIndication, None, cbCtx) return pluginIdList = pluginIdMap.get( (origPeerId, srvClassId, macro.expandMacro(trunkId, trunkReq))) for peerId in peerIdList: peerId = macro.expandMacro(peerId, trunkReq) trunkReqCopy = trunkReq.copy() (snmpEngine, contextEngineId, contextName, bindAddr, bindAddrMacro, peerAddr, peerAddrMacro) = peerIdMap[peerId] if bindAddrMacro: bindAddr = macro.expandMacro(bindAddrMacro, trunkReqCopy), 0 if peerAddrMacro: peerAddr = macro.expandMacro(peerAddrMacro, trunkReqCopy), 161 if bindAddr and peerAddr: updateEndpoints(bindAddr, peerAddr) trunkReqCopy['snmp-peer-id'] = peerId trunkReqCopy['snmp-context-engine-id'] = contextEngineId trunkReqCopy['snmp-context-name'] = contextName trunkReqCopy['snmp-bind-address'], trunkReqCopy[ 'snmp-bind-port'] = bindAddr trunkReqCopy['snmp-peer-address'], trunkReqCopy[ 'snmp-peer-port'] = peerAddr logCtx.update(trunkReqCopy) pdu = trunkReqCopy['server-snmp-pdu'] if pluginIdList: reqCtx = {} cbCtx = trunkId, msgId, trunkReqCopy, pluginIdList, reqCtx for pluginNum, pluginId in enumerate(pluginIdList): if pdu.tagSet in rfc3411.notificationClassPDUs: st, pdu = pluginManager.processNotificationRequest( pluginId, snmpEngine, pdu, trunkReqCopy, reqCtx) elif pdu.tagSet not in rfc3411.unconfirmedClassPDUs: st, pdu = pluginManager.processCommandRequest( pluginId, snmpEngine, pdu, trunkReqCopy, reqCtx) else: log.error('ignoring unsupported PDU', ctx=logCtx) break if st == status.BREAK: log.debug('plugin %s inhibits other plugins' % pluginId, ctx=logCtx) cbCtx = trunkId, msgId, trunkReqCopy, pluginIdList[: pluginNum], reqCtx break elif st == status.DROP: log.debug( 'received trunk message #%s, plugin %s muted request' % (msgId, pluginId), ctx=logCtx) snmpCbFun(snmpEngine, None, None, None, cbCtx) return elif st == status.RESPOND: log.debug( 'received trunk message #%s, plugin %s forced immediate response' % (msgId, pluginId), ctx=logCtx) snmpCbFun(snmpEngine, None, None, pdu, cbCtx) return snmpMessageSent = False if pdu.tagSet in rfc3411.notificationClassPDUs: if pdu.tagSet in rfc3411.unconfirmedClassPDUs: try: notificationOriginator.sendPdu( snmpEngine, peerId, macro.expandMacro(contextEngineId, trunkReq), macro.expandMacro(contextName, trunkReq), pdu) snmpMessageSent = True except PySnmpError: errorIndication = 'failure sending SNMP notification' log.error('trunk message #%s, SNMP error: %s' % (msgId, sys.exc_info()[1]), ctx=logCtx) else: errorIndication = None # respond to trunk right away snmpCbFun(snmpEngine, None, errorIndication, None, cbCtx) else: try: notificationOriginator.sendPdu( snmpEngine, peerId, macro.expandMacro(contextEngineId, trunkReq), macro.expandMacro(contextName, trunkReq), pdu, snmpCbFun, cbCtx) snmpMessageSent = True except PySnmpError: log.error('trunk message #%s, SNMP error: %s' % (msgId, sys.exc_info()[1]), ctx=logCtx) elif pdu.tagSet not in rfc3411.unconfirmedClassPDUs: try: commandGenerator.sendPdu( snmpEngine, peerId, macro.expandMacro(contextEngineId, trunkReq), macro.expandMacro(contextName, trunkReq), pdu, snmpCbFun, cbCtx) snmpMessageSent = True except PySnmpError: errorIndication = 'failure sending SNMP command' log.error('trunk message #%s, SNMP error: %s' % (msgId, sys.exc_info()[1]), ctx=logCtx) # respond to trunk right away snmpCbFun(snmpEngine, None, errorIndication, None, cbCtx) else: log.error('ignoring unsupported PDU', ctx=logCtx) if snmpMessageSent: log.debug( 'received trunk message #%s, forwarded as SNMP message' % msgId, ctx=logCtx) # # Main script body starts here # helpMessage = """\ Usage: %s [--help] [--version ] [--debug-snmp=<%s>] [--debug-asn1=<%s>] [--daemonize] [--process-user=<uname>] [--process-group=<gname>] [--pid-file=<file>] [--logging-method=<%s[:args>]>] [--log-level=<%s>] [--config-file=<file>]""" % (sys.argv[0], '|'.join([ x for x in getattr(pysnmp_debug, 'FLAG_MAP', getattr(pysnmp_debug, 'flagMap', ())) if x != 'mibview' ]), '|'.join([ x for x in getattr(pyasn1_debug, 'FLAG_MAP', getattr(pyasn1_debug, 'flagMap', ())) ]), '|'.join(log.methodsMap), '|'.join(log.levelsMap)) try: opts, params = getopt.getopt(sys.argv[1:], 'hv', [ 'help', 'version', 'debug=', 'debug-snmp=', 'debug-asn1=', 'daemonize', 'process-user='******'process-group=', 'pid-file=', 'logging-method=', 'log-level=', 'config-file=' ]) except Exception: sys.stderr.write('ERROR: %s\r\n%s\r\n' % (sys.exc_info()[1], helpMessage)) return if params: sys.stderr.write('ERROR: extra arguments supplied %s\r\n%s\r\n' % (params, helpMessage)) return pidFile = '' cfgFile = CONFIG_FILE foregroundFlag = True procUser = procGroup = None loggingMethod = ['stderr'] loggingLevel = None for opt in opts: if opt[0] == '-h' or opt[0] == '--help': sys.stderr.write("""\ Synopsis: SNMP Proxy Forwarder: client part. Receives SNMP PDUs via one or many encrypted trunks established with the Forwarder's Agent part(s) running elsewhere and routes PDUs to built-in SNMP Managers for further transmission towards SNMP Agents. Can implement complex routing and protocol conversion logic through analyzing parts of SNMP messages and matching them against proxying rules. Documentation: http://snmplabs.com/snmpfwd/ %s """ % helpMessage) return if opt[0] == '-v' or opt[0] == '--version': import snmpfwd import pysnmp import pyasn1 sys.stderr.write("""\ SNMP Proxy Forwarder version %s, written by Ilya Etingof <*****@*****.**> Using foundation libraries: pysnmp %s, pyasn1 %s. Python interpreter: %s Software documentation and support at http://snmplabs.com/snmpfwd/ %s """ % (snmpfwd.__version__, hasattr(pysnmp, '__version__') and pysnmp.__version__ or 'unknown', hasattr(pyasn1, '__version__') and pyasn1.__version__ or 'unknown', sys.version, helpMessage)) return elif opt[0] == '--debug-snmp': pysnmp_debug.setLogger( pysnmp_debug.Debug(*opt[1].split(','), **dict(loggerName=PROGRAM_NAME + '.pysnmp'))) elif opt[0] == '--debug-asn1': pyasn1_debug.setLogger( pyasn1_debug.Debug(*opt[1].split(','), **dict(loggerName=PROGRAM_NAME + '.pyasn1'))) elif opt[0] == '--daemonize': foregroundFlag = False elif opt[0] == '--process-user': procUser = opt[1] elif opt[0] == '--process-group': procGroup = opt[1] elif opt[0] == '--pid-file': pidFile = opt[1] elif opt[0] == '--logging-method': loggingMethod = opt[1].split(':') elif opt[0] == '--log-level': loggingLevel = opt[1] elif opt[0] == '--config-file': cfgFile = opt[1] with daemon.PrivilegesOf(procUser, procGroup): try: log.setLogger(PROGRAM_NAME, *loggingMethod, **dict(force=True)) if loggingLevel: log.setLevel(loggingLevel) except SnmpfwdError: sys.stderr.write('%s\r\n%s\r\n' % (sys.exc_info()[1], helpMessage)) return try: cfgTree = cparser.Config().load(cfgFile) except SnmpfwdError: log.error('configuration parsing error: %s' % sys.exc_info()[1]) return if cfgTree.getAttrValue('program-name', '', default=None) != PROGRAM_NAME: log.error('config file %s does not match program name %s' % (cfgFile, PROGRAM_NAME)) return if cfgTree.getAttrValue('config-version', '', default=None) != CONFIG_VERSION: log.error( 'config file %s version is not compatible with program version %s' % (cfgFile, CONFIG_VERSION)) return random.seed() # # SNMPv3 CommandGenerator & NotificationOriginator implementation # origCredIdList = [] srvClassIdList = [] peerIdMap = {} pluginIdMap = {} routingMap = {} engineIdMap = {} commandGenerator = cmdgen.CommandGenerator() notificationOriginator = ntforg.NotificationOriginator() transportDispatcher = AsynsockDispatcher() transportDispatcher.registerRoutingCbFun(lambda td, t, d: td) transportDispatcher.setSocketMap() # use global asyncore socket map pluginManager = PluginManager(macro.expandMacros( cfgTree.getAttrValue('plugin-modules-path-list', '', default=[], vector=True), {'config-dir': os.path.dirname(cfgFile)}), progId=PROGRAM_NAME, apiVer=PLUGIN_API_VERSION) for pluginCfgPath in cfgTree.getPathsToAttr('plugin-id'): pluginId = cfgTree.getAttrValue('plugin-id', *pluginCfgPath) pluginMod = cfgTree.getAttrValue('plugin-module', *pluginCfgPath) pluginOptions = macro.expandMacros( cfgTree.getAttrValue('plugin-options', *pluginCfgPath, **dict(default=[], vector=True)), {'config-dir': os.path.dirname(cfgFile)}) log.info( 'configuring plugin ID %s (at %s) from module %s with options %s...' % (pluginId, '.'.join(pluginCfgPath), pluginMod, ', '.join(pluginOptions) or '<none>')) with daemon.PrivilegesOf(procUser, procGroup): try: pluginManager.loadPlugin(pluginId, pluginMod, pluginOptions) except SnmpfwdError: log.error('plugin %s not loaded: %s' % (pluginId, sys.exc_info()[1])) return for peerEntryPath in cfgTree.getPathsToAttr('snmp-peer-id'): peerId = cfgTree.getAttrValue('snmp-peer-id', *peerEntryPath) if peerId in peerIdMap: log.error('duplicate snmp-peer-id=%s at %s' % (peerId, '.'.join(peerEntryPath))) return log.info('configuring SNMP peer %s (at %s)...' % (peerId, '.'.join(peerEntryPath))) engineId = cfgTree.getAttrValue('snmp-engine-id', *peerEntryPath) if engineId in engineIdMap: snmpEngine, snmpContext, snmpEngineMap = engineIdMap[engineId] log.info('using engine-id: %s' % snmpEngine.snmpEngineID.prettyPrint()) else: snmpEngine = engine.SnmpEngine(snmpEngineID=engineId) snmpContext = context.SnmpContext(snmpEngine) snmpEngineMap = { 'transportDomain': {}, 'securityName': {}, 'credIds': set() } engineIdMap[engineId] = snmpEngine, snmpContext, snmpEngineMap log.info('new engine-id %s' % snmpEngine.snmpEngineID.prettyPrint()) transportDomain = cfgTree.getAttrValue('snmp-transport-domain', *peerEntryPath) transportDomain = rfc1902.ObjectName(str(transportDomain)) if (transportDomain[:len(udp.domainName)] != udp.domainName and udp6 and transportDomain[:len(udp6.domainName)] != udp6.domainName): log.error('unknown transport domain %s' % (transportDomain, )) return transportOptions = cfgTree.getAttrValue( 'snmp-transport-options', *peerEntryPath, **dict(default=[], vector=True)) bindAddr = cfgTree.getAttrValue('snmp-bind-address', *peerEntryPath) try: bindAddr, bindAddrMacro = endpoint.parseTransportAddress( transportDomain, bindAddr, transportOptions) except SnmpfwdError: log.error('bad snmp-bind-address specification %s at %s' % (bindAddr, '.'.join(peerEntryPath))) return if transportDomain in snmpEngineMap['transportDomain']: log.info('using transport endpoint with transport ID %s' % (transportDomain, )) else: if transportDomain[:len(udp.domainName)] == udp.domainName: transport = udp.UdpTransport() else: transport = udp6.Udp6Transport() snmpEngine.registerTransportDispatcher(transportDispatcher, transportDomain) t = transport.openClientMode(bindAddr) if 'transparent-proxy' in transportOptions: t.enablePktInfo() t.enableTransparent() elif 'virtual-interface' in transportOptions: t.enablePktInfo() config.addSocketTransport(snmpEngine, transportDomain, t) snmpEngineMap['transportDomain'][transportDomain] = bindAddr[ 0], bindAddr[1], transportDomain log.info( 'new transport endpoint at bind address [%s]:%s, options %s, transport ID %s' % (bindAddr[0], bindAddr[1], transportOptions and '/'.join(transportOptions) or '<none>', transportDomain)) securityModel = cfgTree.getAttrValue('snmp-security-model', *peerEntryPath) securityModel = rfc1902.Integer(securityModel) securityLevel = cfgTree.getAttrValue('snmp-security-level', *peerEntryPath) securityLevel = rfc1902.Integer(securityLevel) securityName = cfgTree.getAttrValue('snmp-security-name', *peerEntryPath) contextEngineId = cfgTree.getAttrValue('snmp-context-engine-id', *peerEntryPath, **dict(default=None)) contextName = cfgTree.getAttrValue('snmp-context-name', *peerEntryPath, **dict(default='')) if securityModel in (1, 2): if securityName in snmpEngineMap['securityName']: if snmpEngineMap['securityName'][ securityName] == securityModel: log.info('using security-name %s' % securityName) else: log.error( 'security-name %s already in use at security-model %s' % (securityName, securityModel)) return else: communityName = cfgTree.getAttrValue('snmp-community-name', *peerEntryPath) config.addV1System(snmpEngine, securityName, communityName, securityName=securityName) log.info( 'new community-name %s, security-model %s, security-name %s, security-level %s' % (communityName, securityModel, securityName, securityLevel)) snmpEngineMap['securityName'][securityName] = securityModel elif securityModel == 3: if securityName in snmpEngineMap['securityName']: if snmpEngineMap['securityName'][ securityName] == securityModel: log.info('using USM security-name: %s' % securityName) else: raise SnmpfwdError( 'security-name %s already in use at security-model %s' % (securityName, securityModel)) else: usmUser = cfgTree.getAttrValue('snmp-usm-user', *peerEntryPath) securityEngineId = cfgTree.getAttrValue( 'snmp-security-engine-id', *peerEntryPath, **dict(default=None)) if securityEngineId: securityEngineId = rfc1902.OctetString(securityEngineId) log.info( 'new USM user %s, security-model %s, security-level %s, ' 'security-name %s, security-engine-id %s' % (usmUser, securityModel, securityLevel, securityName, securityEngineId and securityEngineId.prettyPrint() or '<none>')) if securityLevel in (2, 3): usmAuthProto = cfgTree.getAttrValue( 'snmp-usm-auth-protocol', *peerEntryPath, **dict(default=config.usmHMACMD5AuthProtocol)) try: usmAuthProto = authProtocols[usmAuthProto.upper()] except KeyError: pass usmAuthProto = rfc1902.ObjectName(usmAuthProto) usmAuthKey = cfgTree.getAttrValue('snmp-usm-auth-key', *peerEntryPath) log.info( 'new USM authentication key: %s, authentication protocol: %s' % (usmAuthKey, usmAuthProto)) if securityLevel == 3: usmPrivProto = cfgTree.getAttrValue( 'snmp-usm-priv-protocol', *peerEntryPath, **dict(default=config.usmDESPrivProtocol)) try: usmPrivProto = privProtocols[usmPrivProto.upper()] except KeyError: pass usmPrivProto = rfc1902.ObjectName(usmPrivProto) usmPrivKey = cfgTree.getAttrValue( 'snmp-usm-priv-key', *peerEntryPath, **dict(default=None)) log.info( 'new USM encryption key: %s, encryption protocol: %s' % (usmPrivKey, usmPrivProto)) config.addV3User( snmpEngine, usmUser, usmAuthProto, usmAuthKey, usmPrivProto, usmPrivKey, ) else: config.addV3User(snmpEngine, usmUser, usmAuthProto, usmAuthKey, securityEngineId=securityEngineId) else: config.addV3User(snmpEngine, usmUser, securityEngineId=securityEngineId) snmpEngineMap['securityName'][securityName] = securityModel else: log.error('unknown security-model: %s' % securityModel) sys.exit(1) credId = '/'.join( [str(x) for x in (securityName, securityLevel, securityModel)]) if credId in snmpEngineMap['credIds']: log.info('using credentials ID %s...' % credId) else: config.addTargetParams( snmpEngine, credId, securityName, securityLevel, securityModel == 3 and 3 or securityModel - 1) log.info( 'new credentials %s, security-name %s, security-level %s, security-model %s' % (credId, securityName, securityLevel, securityModel)) snmpEngineMap['credIds'].add(credId) peerAddr = cfgTree.getAttrValue('snmp-peer-address', *peerEntryPath) try: peerAddr, peerAddrMacro = endpoint.parseTransportAddress( transportDomain, peerAddr, transportOptions, defaultPort=161) except SnmpfwdError: log.error('bad snmp-peer-address specification %s at %s' % (peerAddr, '.'.join(peerEntryPath))) return timeout = cfgTree.getAttrValue('snmp-peer-timeout', *peerEntryPath) retries = cfgTree.getAttrValue('snmp-peer-retries', *peerEntryPath) config.addTargetAddr(snmpEngine, peerId, transportDomain, peerAddr, credId, timeout, retries) peerIdMap[ peerId] = snmpEngine, contextEngineId, contextName, bindAddr, bindAddrMacro, peerAddr, peerAddrMacro log.info( 'new peer ID %s, bind address %s, peer address %s, timeout %s*0.01 secs, retries %s, credentials ID %s' % (peerId, bindAddrMacro or '<default>', peerAddrMacro or '%s:%s' % peerAddr, timeout, retries, credId)) duplicates = {} # TODO: rename orig-* into server-* and orig-snmp-peer-id into server-snmp-entity-id for origCredCfgPath in cfgTree.getPathsToAttr('orig-snmp-peer-id'): origCredId = cfgTree.getAttrValue('orig-snmp-peer-id', *origCredCfgPath) if origCredId in duplicates: log.error('duplicate orig-snmp-peer-id=%s at %s and %s' % (origCredId, '.'.join(origCredCfgPath), '.'.join( duplicates[origCredId]))) return duplicates[origCredId] = origCredCfgPath k = '#'.join( (cfgTree.getAttrValue('orig-snmp-engine-id-pattern', *origCredCfgPath), cfgTree.getAttrValue('orig-snmp-transport-domain-pattern', *origCredCfgPath), cfgTree.getAttrValue('orig-snmp-peer-address-pattern', *origCredCfgPath), cfgTree.getAttrValue('orig-snmp-bind-address-pattern', *origCredCfgPath), cfgTree.getAttrValue('orig-snmp-security-model-pattern', *origCredCfgPath), cfgTree.getAttrValue('orig-snmp-security-level-pattern', *origCredCfgPath), cfgTree.getAttrValue('orig-snmp-security-name-pattern', *origCredCfgPath), cfgTree.getAttrValue('orig-snmp-context-engine-id-pattern', *origCredCfgPath), cfgTree.getAttrValue('orig-snmp-context-name-pattern', *origCredCfgPath), cfgTree.getAttrValue('orig-snmp-pdu-type-pattern', *origCredCfgPath), cfgTree.getAttrValue('orig-snmp-oid-prefix-pattern', *origCredCfgPath))) log.info( 'configuring original SNMP peer ID %s (at %s), composite key: %s' % (origCredId, '.'.join(origCredCfgPath), k)) origCredIdList.append((origCredId, re.compile(k))) duplicates = {} for srvClassCfgPath in cfgTree.getPathsToAttr('server-classification-id'): srvClassId = cfgTree.getAttrValue('server-classification-id', *srvClassCfgPath) if srvClassId in duplicates: log.error('duplicate server-classification-id=%s at %s and %s' % (srvClassId, '.'.join(srvClassCfgPath), '.'.join( duplicates[srvClassId]))) return duplicates[srvClassId] = srvClassCfgPath k = '#'.join( (cfgTree.getAttrValue('server-snmp-credentials-id-pattern', *srvClassCfgPath), cfgTree.getAttrValue('server-snmp-context-id-pattern', *srvClassCfgPath), cfgTree.getAttrValue('server-snmp-content-id-pattern', *srvClassCfgPath), cfgTree.getAttrValue('server-snmp-peer-id-pattern', *srvClassCfgPath))) log.info( 'configuring server classification ID %s (at %s), composite key: %s' % (srvClassId, '.'.join(srvClassCfgPath), k)) srvClassIdList.append((srvClassId, re.compile(k))) del duplicates for pluginCfgPath in cfgTree.getPathsToAttr('using-plugin-id-list'): pluginIdList = cfgTree.getAttrValue('using-plugin-id-list', *pluginCfgPath, **dict(vector=True)) log.info('configuring plugin ID(s) %s (at %s)...' % (','.join(pluginIdList), '.'.join(pluginCfgPath))) for credId in cfgTree.getAttrValue('matching-orig-snmp-peer-id-list', *pluginCfgPath, **dict(vector=True)): for srvClassId in cfgTree.getAttrValue( 'matching-server-classification-id-list', *pluginCfgPath, **dict(vector=True)): for trunkId in cfgTree.getAttrValue('matching-trunk-id-list', *pluginCfgPath, **dict(vector=True)): k = credId, srvClassId, trunkId if k in pluginIdMap: log.error( 'duplicate snmp-credentials-id=%s and server-classification-id=%s and trunk-id=%s at plugin-id %s' % (credId, srvClassId, trunkId, ','.join(pluginIdList))) return else: log.info( 'configuring plugin(s) %s (at %s), composite key: %s' % (','.join(pluginIdList), '.'.join(pluginCfgPath), '/'.join(k))) for pluginId in pluginIdList: if not pluginManager.hasPlugin(pluginId): log.error( 'undefined plugin ID %s referenced at %s' % (pluginId, '.'.join(pluginCfgPath))) return pluginIdMap[k] = pluginIdList for routeCfgPath in cfgTree.getPathsToAttr('using-snmp-peer-id-list'): peerIdList = cfgTree.getAttrValue('using-snmp-peer-id-list', *routeCfgPath, **dict(vector=True)) log.info('configuring routing entry with peer IDs %s (at %s)...' % (','.join(peerIdList), '.'.join(routeCfgPath))) for credId in cfgTree.getAttrValue('matching-orig-snmp-peer-id-list', *routeCfgPath, **dict(vector=True)): for srvClassId in cfgTree.getAttrValue( 'matching-server-classification-id-list', *routeCfgPath, **dict(vector=True)): for trunkId in cfgTree.getAttrValue('matching-trunk-id-list', *routeCfgPath, **dict(vector=True)): k = credId, srvClassId, trunkId if k in routingMap: log.error( 'duplicate snmp-credentials-id=%s and server-classification-id=%s and trunk-id=%s at snmp-peer-id %s' % (credId, srvClassId, trunkId, ','.join(peerIdList))) return else: for peerId in peerIdList: if peerId not in peerIdMap: log.error('missing peer-id %s at %s' % (peerId, '.'.join(routeCfgPath))) return routingMap[k] = peerIdList trunkingManager = TrunkingManager(trunkCbFun) for trunkCfgPath in cfgTree.getPathsToAttr('trunk-id'): trunkId = cfgTree.getAttrValue('trunk-id', *trunkCfgPath) secret = cfgTree.getAttrValue('trunk-crypto-key', *trunkCfgPath, **dict(default='')) secret = secret and (secret * ((16 // len(secret)) + 1))[:16] log.info('configuring trunk ID %s (at %s)...' % (trunkId, '.'.join(trunkCfgPath))) connectionMode = cfgTree.getAttrValue('trunk-connection-mode', *trunkCfgPath) if connectionMode == 'client': trunkingManager.addClient( trunkId, parseTrunkEndpoint( cfgTree.getAttrValue('trunk-bind-address', *trunkCfgPath)), parseTrunkEndpoint( cfgTree.getAttrValue('trunk-peer-address', *trunkCfgPath), 30201), cfgTree.getAttrValue('trunk-ping-period', *trunkCfgPath, default=0, expect=int), secret) log.info( 'new trunking client from %s to %s' % (cfgTree.getAttrValue('trunk-bind-address', *trunkCfgPath), cfgTree.getAttrValue('trunk-peer-address', *trunkCfgPath))) if connectionMode == 'server': trunkingManager.addServer( parseTrunkEndpoint( cfgTree.getAttrValue('trunk-bind-address', *trunkCfgPath), 30201), cfgTree.getAttrValue('trunk-ping-period', *trunkCfgPath, default=0, expect=int), secret) log.info( 'new trunking server at %s' % (cfgTree.getAttrValue('trunk-bind-address', *trunkCfgPath))) transportDispatcher.registerTimerCbFun(trunkingManager.setupTrunks, random.randrange(1, 5)) transportDispatcher.registerTimerCbFun(trunkingManager.monitorTrunks, random.randrange(1, 5)) if not foregroundFlag: try: daemon.daemonize(pidFile) except Exception: log.error('can not daemonize process: %s' % sys.exc_info()[1]) return # Run mainloop log.info('starting I/O engine...') transportDispatcher.jobStarted(1) # server job would never finish # Python 2.4 does not support the "finally" clause with daemon.PrivilegesOf(procUser, procGroup, final=True): while True: try: transportDispatcher.runDispatcher() except (PySnmpError, SnmpfwdError, socket.error): log.error(str(sys.exc_info()[1])) continue except Exception: transportDispatcher.closeDispatcher() raise
secLevel, v3AuthKey is None and '<NONE>' or v3AuthKey, v3AuthProto, v3PrivKey is None and '<NONE>' or v3PrivKey, v3PrivProto)) else: v3User = '******' secLevel = 'noAuthNoPriv' config.addV1System(snmpEngine, v3User, snmpCommunity) log.info( 'SNMP version %s, Community name: ' '%s' % (snmpVersion == 0 and '1' or '2c', snmpCommunity)) config.addTargetParams(snmpEngine, 'pms', v3User, secLevel, snmpVersion) if agentUDPv6Endpoint: config.addSocketTransport( snmpEngine, udp6.domainName, udp6.Udp6SocketTransport().openClientMode()) config.addTargetAddr( snmpEngine, 'tgt', udp6.domainName, agentUDPv6Endpoint, 'pms', timeout, retryCount) log.info('Querying UDP/IPv6 agent at [%s]:%s' % agentUDPv6Endpoint) elif agentUNIXEndpoint: config.addSocketTransport( snmpEngine, unix.domainName,
'new USM encryption key: %s, encryption protocol: %s' % (usmPrivKey, usmPrivProto)) snmpEngineMap['securityName'][securityName] = securityModel config.addV3User(snmpEngine, usmUser, usmAuthProto, usmAuthKey, usmPrivProto, usmPrivKey) else: raise SnmpfwdError('unknown security-model: %s' % securityModel) credId = '/'.join( [str(x) for x in (securityName, securityLevel, securityModel)]) if credId in snmpEngineMap['credIds']: log.msg('using credentials ID %s...' % credId) else: config.addTargetParams(snmpEngine, credId, securityName, securityLevel, securityModel == 3 and 3 or securityModel - 1) log.msg( 'new credentials %s, security-name %s, security-level %s, security-model %s' % (credId, securityName, securityLevel, securityModel)) snmpEngineMap['credIds'].add(credId) peerAddrMacro = None peerAddr = cfgTree.getAttrValue('snmp-peer-address', *peerEntryPath) if 'transparent-proxy' in transportOptions or \ 'virtual-interface' in transportOptions: if '$' in peerAddr: peerAddrMacro = peerAddr peerAddr = '0.0.0.0', 0 else: try:
from pysnmp.entity.rfc3413 import cmdgen # Create SNMP engine instance snmpEngine = engine.SnmpEngine() # # SNMPv3/USM setup # # user: usr-sha-aes, auth: SHA, priv AES config.addV3User( snmpEngine, 'usr-sha-aes', config.usmHMACSHAAuthProtocol, 'authkey1', config.usmAesCfb128Protocol, 'privkey1' ) config.addTargetParams(snmpEngine, 'my-creds', 'usr-sha-aes', 'authPriv') # # Setup transport endpoint and bind it with security settings yielding # a target name # # UDP/IPv4 config.addTransport( snmpEngine, udp.domainName, udp.UdpSocketTransport().openClientMode() ) config.addTargetAddr( snmpEngine, 'my-router', udp.domainName, ('195.218.195.228', 161),
snmpEngine = engine.SnmpEngine() # v1/2 setup config.addV1System(snmpEngine, 'test-agent', 'public') # v3 setup config.addV3User( snmpEngine, 'test-user', config.usmHMACMD5AuthProtocol, 'authkey1', config.usmDESPrivProtocol, 'privkey1' ) # Transport params #config.addTargetParams(snmpEngine, 'myParams', 'test-user', 'authPriv') config.addTargetParams(snmpEngine, 'myParams', 'test-agent', 'noAuthNoPriv', 1) # Transport addresses config.addTargetAddr( snmpEngine, 'myRouter', config.snmpUDPDomain, ('127.0.0.1', 161), 'myParams' ) # Transport config.addSocketTransport( snmpEngine, config.snmpUDPDomain, udp.UdpSocketTransport().openClientMode() ) def cbFun(sendRequesthandle, errorIndication, errorStatus, errorIndex,
# SecurityName <-> CommunityName mapping config.addV1System(snmpEngine, 'my-area', 'public') # # SNMPv1 setup (Manager role) # # SecurityName <-> CommunityName <-> Transport mapping config.addV1System(snmpEngine, 'distant-area', 'public', transportTag='distant') # # Transport target used by Manager # # Specify security settings per SecurityName (SNMPv1 - 0, SNMPv2c - 1) config.addTargetParams(snmpEngine, 'distant-agent-auth', 'distant-area', 'noAuthNoPriv', 0) config.addTargetAddr( snmpEngine, 'distant-agent', udp.domainName + (2,), ('195.218.195.228', 161), 'distant-agent-auth', retryCount=0, tagList='distant' ) # Default SNMP context config.addContext(snmpEngine, '') class CommandResponder(cmdrsp.CommandResponderBase): cmdGenMap = { v2c.GetRequestPDU.tagSet: cmdgen.GetCommandGenerator(), v2c.SetRequestPDU.tagSet: cmdgen.SetCommandGenerator(), v2c.GetNextRequestPDU.tagSet: cmdgen.NextCommandGeneratorSingleRun(),
# # SNMPv3/USM setup (Manager role) # # user: usr-md5-none, auth: MD5, priv NONE config.addV3User( snmpEngine, remoteV3User, config.usmHMACMD5AuthProtocol, remoteV3AuthKey ) # # Transport target used by Manager # config.addTargetParams( snmpEngine, 'distant-agent', 'MD5User', 'authNoPriv' ) config.addTargetAddr( snmpEngine, 'net-snmp-agent', remoteTransportDomain, remoteTransportAddress, 'distant-agent', retryCount=0 ) # Default SNMP context config.addContext(snmpEngine, '') class CommandResponder(cmdrsp.CommandResponderBase): cmdGenMap = { v2c.GetRequestPDU.tagSet: cmdgen.GetCommandGenerator(), v2c.SetRequestPDU.tagSet: cmdgen.SetCommandGenerator(), v2c.GetNextRequestPDU.tagSet: cmdgen.NextCommandGeneratorSingleRun(), v2c.GetBulkRequestPDU.tagSet: cmdgen.BulkCommandGeneratorSingleRun() }
| $ snmptrap -v2c -c public demo.snmplabs.com 0 1.3.6.1.6.3.1.1.5.1 """ # from pysnmp.entity import engine, config from pysnmp.carrier.asyncore.dgram import udp from pysnmp.entity.rfc3413 import ntforg from pysnmp.proto.api import v2c # Create SNMP engine instance snmpEngine = engine.SnmpEngine() # SecurityName <-> CommunityName mapping config.addV1System(snmpEngine, "my-area", "public") # Specify security settings per SecurityName (SNMPv2c -> 1) config.addTargetParams(snmpEngine, "my-creds", "my-area", "noAuthNoPriv", 1) # Setup transport endpoint and bind it with security settings yielding # a target name config.addTransport(snmpEngine, udp.domainName, udp.UdpSocketTransport().openClientMode()) # Create named target config.addTargetAddr(snmpEngine, "my-nms", udp.domainName, ("195.218.195.228", 162), "my-creds") # *** SNMP engine configuration is complete by this line *** # Create SNMP v2c TRAP PDU with defaults trapPDU = v2c.TrapPDU() v2c.apiTrapPDU.setDefaults(trapPDU) # Set custom var-binds to TRAP PDU
def cfgCmdGen(self, authData, transportTarget): if isinstance(authData, CommunityData): if authData.communityIndex not in self.__knownAuths: config.addV1System( self.snmpEngine, authData.communityIndex, authData.communityName, authData.contextEngineId, authData.contextName, authData.tag, authData.securityName ) self.__knownAuths[authData.communityIndex] = authData elif isinstance(authData, UsmUserData): authDataKey = authData.userName, authData.securityEngineId if authDataKey not in self.__knownAuths: config.addV3User( self.snmpEngine, authData.userName, authData.authProtocol, authData.authKey, authData.privProtocol, authData.privKey, authData.securityEngineId, securityName=authData.securityName ) self.__knownAuths[authDataKey] = authData else: raise error.PySnmpError('Unsupported authentication object') paramsKey = authData.securityName, \ authData.securityLevel, \ authData.mpModel if paramsKey in self.__knownParams: paramsName, useCount = self.__knownParams[paramsKey] self.__knownParams[paramsKey] = paramsName, useCount + 1 else: paramsName = 'p%s' % nextID() config.addTargetParams( self.snmpEngine, paramsName, authData.securityName, authData.securityLevel, authData.mpModel ) self.__knownParams[paramsKey] = paramsName, 1 if transportTarget.transportDomain in self.__knownTransports: transportTarget.verifyDispatcherCompatibility(self.snmpEngine) transport, useCount = self.__knownTransports[transportTarget.transportDomain] self.__knownTransports[transportTarget.transportDomain] = transport, useCount + 1 else: transport = transportTarget.openClientMode() config.addTransport( self.snmpEngine, transportTarget.transportDomain, transport ) self.__knownTransports[transportTarget.transportDomain] = transport, 1 transportKey = ( paramsName, transportTarget.transportDomain, transportTarget.transportAddr, transportTarget.tagList ) if transportKey in self.__knownTransportAddrs: addrName, useCount = self.__knownTransportAddrs[transportKey] self.__knownTransportAddrs[transportKey] = addrName, useCount + 1 else: addrName = 'a%s' % nextID() config.addTargetAddr( self.snmpEngine, addrName, transportTarget.transportDomain, transportTarget.transportAddr, paramsName, transportTarget.timeout * 100, transportTarget.retries, transportTarget.tagList ) self.__knownTransportAddrs[transportKey] = addrName, 1 return addrName, paramsName
def configure(self, snmpEngine, authData, transportTarget, *options): cache = self._getCache(snmpEngine) if isinstance(authData, CommunityData): if authData.communityIndex not in cache['auth']: config.addV1System( snmpEngine, authData.communityIndex, authData.communityName, authData.contextEngineId, authData.contextName, authData.tag, authData.securityName ) cache['auth'][authData.communityIndex] = authData elif isinstance(authData, UsmUserData): authDataKey = authData.userName, authData.securityEngineId if authDataKey not in cache['auth']: config.addV3User( snmpEngine, authData.userName, authData.authProtocol, authData.authKey, authData.privProtocol, authData.privKey, authData.securityEngineId, securityName=authData.securityName ) cache['auth'][authDataKey] = authData else: raise error.PySnmpError('Unsupported authentication object') paramsKey = (authData.securityName, authData.securityLevel, authData.mpModel) if paramsKey in cache['parm']: paramsName, useCount = cache['parm'][paramsKey] cache['parm'][paramsKey] = paramsName, useCount + 1 else: paramsName = 'p%s' % self.nextID() config.addTargetParams( snmpEngine, paramsName, authData.securityName, authData.securityLevel, authData.mpModel ) cache['parm'][paramsKey] = paramsName, 1 if transportTarget.transportDomain in cache['tran']: transport, useCount = cache['tran'][transportTarget.transportDomain] transportTarget.verifyDispatcherCompatibility(snmpEngine) cache['tran'][transportTarget.transportDomain] = transport, useCount + 1 elif config.getTransport(snmpEngine, transportTarget.transportDomain): transportTarget.verifyDispatcherCompatibility(snmpEngine) else: transport = transportTarget.openClientMode() config.addTransport( snmpEngine, transportTarget.transportDomain, transport ) cache['tran'][transportTarget.transportDomain] = transport, 1 transportKey = (paramsName, transportTarget.transportDomain, transportTarget.transportAddr, transportTarget.tagList) if transportKey in cache['addr']: addrName, useCount = cache['addr'][transportKey] cache['addr'][transportKey] = addrName, useCount + 1 else: addrName = 'a%s' % self.nextID() config.addTargetAddr( snmpEngine, addrName, transportTarget.transportDomain, transportTarget.transportAddr, paramsName, transportTarget.timeout * 100, transportTarget.retries, transportTarget.tagList ) cache['addr'][transportKey] = addrName, 1 return addrName, paramsName
def __init__(self, mibPath, temperatureValue, snmpRelays, criticalStatus=True): from types import ListType, TupleType,StringTypes from re import compile,search from socket import gethostbyname extractPaths=compile(r'[,:]') checkIP=compile(r'(\d{1,3}\.){3}\d{1,3}') # Create SNMP engine instance self.snmpEngine = engine.SnmpEngine() if not temperatureValue: raise ValueError, 'A temperature must be provided' self.temperature=temperatureValue #print "============>mibPath type: %s" %type(mibPath) if type(mibPath) in StringTypes: mibPathTuple=tuple(extractPaths.split(mibPath)) elif type(mibPath) in (ListType, TupleType): mibPathTuple=tuple(mibPath) else: mibPathTuple=('/usr/local/share/snmp/python/',) mibBuilder = self.snmpEngine.msgAndPduDsp.mibInstrumController.mibBuilder #print mibPathTuple mibSources = mibBuilder.getMibPath() + mibPathTuple mibBuilder.setMibPath(*mibSources) mibBuilder.loadModules( 'USC-IGFAE-MIB' ) if type(snmpRelays) in StringTypes: snmpRelays=snmpRelays.split(',') elif not type(snmpRelays) in (ListType,TupleType): raise TypeError, 'The list of SNMP relays must be a string or a list or tuple of strings' (temperatureCritical, temperatureOK, self.roomTemp) = mibBuilder.importSymbols('USC-IGFAE-MIB','temperatureCritical', 'temperatureOK', 'roomTemp' ) # SecurityName <-> CommunityName mapping config.addV1System(self.snmpEngine, 'Arduino', 'ups') # Specify security settings per SecurityName (SNMPv2c -> 1) config.addTargetParams(self.snmpEngine, 'creds', 'Arduino', 'noAuthNoPriv', 0) # Setup transport endpoint and bind it with security settings yielding # a target name config.addSocketTransport( self.snmpEngine, udp.domainName, udp.UdpSocketTransport().openClientMode() ) index=0 for machine in snmpRelays: index=index+1 if not checkIP.match(machine): try: machine=gethostbyname(machine) except: continue #print "==============>SNMP relay IP: %s" % machine config.addTargetAddr( self.snmpEngine, 'NMS%s' % index, udp.domainName, (machine, 162), 'creds', tagList='managers' ) # Specify what kind of notification should be sent (TRAP or INFORM), # to what targets (chosen by tag) and what filter should apply to # the set of targets (selected by tag) config.addNotificationTarget( self.snmpEngine, 'sendShutdownTrap', 'my-filter', 'managers', 'trap' ) # Allow NOTIFY access to Agent's MIB by this SNMP model (2), securityLevel # and SecurityName config.addContext(self.snmpEngine, '') config.addVacmUser(self.snmpEngine, 1, 'Arduino', 'noAuthNoPriv', (), (), (1,3,6)) # *** SNMP engine configuration is complete by this line *** # Create default SNMP context where contextEngineId == SnmpEngineId snmpContext = context.SnmpContext(self.snmpEngine) if criticalStatus: self.trap=temperatureCritical else: self.trap=temperatureOK # Create Notification Originator App instance. ntforg.NotificationOriginator.__init__(self,snmpContext)