pysnmp 无法接收来自不同机器的陷阱
pysnmp not able to receive trap from different machine
我用我的 VM ip (eth0-192.168.12.20) 代替本地主机 IP 来接收陷阱通知,如果从 VM 外部生成陷阱,我不会收到任何陷阱(我正在使用另一台机器的 snmptrap 命令)但是当我在 VM 接口 eth0 上执行 tcpdump 时,我可以看到 SNMP 数据。
如果我使用 snmptrap 命令从同一台机器生成陷阱,我可以通过 PySNMP 陷阱接收器脚本查看陷阱数据。
选项已尝试:
1.尝试将端口绑定到 0.0.0.0 以接收来自任何机器的陷阱
2. 在 pysnmp 中启用调试选项以获得解决问题的一些想法。从外部机器发送 snmptrap 时没有生成信息
The closest scenario 类似我的问题出现在下面link 没有最终解决方案。
代码:
SNMP v1 和 v2c:
from pysnmp.carrier.asynsock.dispatch import AsynsockDispatcher
from pysnmp.carrier.asynsock.dgram import udp, udp6
from pyasn1.codec.ber import decoder
from pysnmp.proto import api
from pysnmp.entity import engine, config
from pysnmp.entity.rfc3413 import ntfrcv
from pysnmp import debug
debug.setLogger(debug.Debug("all"))
### SNMPv2c/SNMPv1 setup
### Callback function for receiving notifications
def v2cv1CallBackFunc(snmpEngine, stateReference, contextEngineId, contextName,
varBinds, cbCtx):
transportDomain, transportAddress = snmpEngine.msgAndPduDsp.getTransportInfo(stateReference)
print transportDomain, transportAddress
# Get an execution context...
execContext = snmpEngine.observer.getExecutionContext(
'rfc3412.receiveMessage:request'
)
# ... and use inner SNMP engine data to figure out peer address
print('Notification from %s, ContextEngineId "%s", ContextName "%s"'
%('@'.join([str(x) for x in execContext['transportAddress']]),
contextEngineId.prettyPrint(), contextName.prettyPrint()))
for name, val in varBinds:
print('%s = %s' % (name.prettyPrint(), val.prettyPrint()))
# Create SNMP engine with autogenernated engineID and pre-bound
# to socket transport dispatcher
snmpEngine = engine.SnmpEngine()
# SNMPv1/2c setup
# 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)
# Transport setup
# UDP over IPv4, first listening interface/port
config.addSocketTransport(
snmpEngine,
udp.domainName + (1, ),
udp.UdpSocketTransport().openServerMode(('0.0.0.0', 162))
)
# Register SNMP Application at the SNMP engine
ntfrcv.NotificationReceiver(snmpEngine, v2cv1CallBackFunc)
snmpEngine.transportDispatcher.jobStarted(1) # this job would never finish
# Run I/O dispatcher which would receive queries and send confirmations
try:
snmpEngine.transportDispatcher.runDispatcher()
except:
snmpEngine.transportDispatcher.closeDispatcher()
raise
提前致谢
我在 IT 团队的帮助下发现了这个问题。基本上 API 工作正常。
firewalld 应用程序不允许数据包通过。所以在我将 SNMP 端口添加到防火墙例外列表后,它使我的代码正常工作。
我使用的命令:
- sudo firewall-cmd --add-port=161-162/udp --zone=public --permanent
- sudo systemctl 重启网络
- sudo systemctl reload firewalld
我用我的 VM ip (eth0-192.168.12.20) 代替本地主机 IP 来接收陷阱通知,如果从 VM 外部生成陷阱,我不会收到任何陷阱(我正在使用另一台机器的 snmptrap 命令)但是当我在 VM 接口 eth0 上执行 tcpdump 时,我可以看到 SNMP 数据。 如果我使用 snmptrap 命令从同一台机器生成陷阱,我可以通过 PySNMP 陷阱接收器脚本查看陷阱数据。
选项已尝试: 1.尝试将端口绑定到 0.0.0.0 以接收来自任何机器的陷阱 2. 在 pysnmp 中启用调试选项以获得解决问题的一些想法。从外部机器发送 snmptrap 时没有生成信息
The closest scenario 类似我的问题出现在下面link 没有最终解决方案。
代码: SNMP v1 和 v2c:
from pysnmp.carrier.asynsock.dispatch import AsynsockDispatcher
from pysnmp.carrier.asynsock.dgram import udp, udp6
from pyasn1.codec.ber import decoder
from pysnmp.proto import api
from pysnmp.entity import engine, config
from pysnmp.entity.rfc3413 import ntfrcv
from pysnmp import debug
debug.setLogger(debug.Debug("all"))
### SNMPv2c/SNMPv1 setup
### Callback function for receiving notifications
def v2cv1CallBackFunc(snmpEngine, stateReference, contextEngineId, contextName,
varBinds, cbCtx):
transportDomain, transportAddress = snmpEngine.msgAndPduDsp.getTransportInfo(stateReference)
print transportDomain, transportAddress
# Get an execution context...
execContext = snmpEngine.observer.getExecutionContext(
'rfc3412.receiveMessage:request'
)
# ... and use inner SNMP engine data to figure out peer address
print('Notification from %s, ContextEngineId "%s", ContextName "%s"'
%('@'.join([str(x) for x in execContext['transportAddress']]),
contextEngineId.prettyPrint(), contextName.prettyPrint()))
for name, val in varBinds:
print('%s = %s' % (name.prettyPrint(), val.prettyPrint()))
# Create SNMP engine with autogenernated engineID and pre-bound
# to socket transport dispatcher
snmpEngine = engine.SnmpEngine()
# SNMPv1/2c setup
# 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)
# Transport setup
# UDP over IPv4, first listening interface/port
config.addSocketTransport(
snmpEngine,
udp.domainName + (1, ),
udp.UdpSocketTransport().openServerMode(('0.0.0.0', 162))
)
# Register SNMP Application at the SNMP engine
ntfrcv.NotificationReceiver(snmpEngine, v2cv1CallBackFunc)
snmpEngine.transportDispatcher.jobStarted(1) # this job would never finish
# Run I/O dispatcher which would receive queries and send confirmations
try:
snmpEngine.transportDispatcher.runDispatcher()
except:
snmpEngine.transportDispatcher.closeDispatcher()
raise
提前致谢
我在 IT 团队的帮助下发现了这个问题。基本上 API 工作正常。
firewalld 应用程序不允许数据包通过。所以在我将 SNMP 端口添加到防火墙例外列表后,它使我的代码正常工作。
我使用的命令:
- sudo firewall-cmd --add-port=161-162/udp --zone=public --permanent
- sudo systemctl 重启网络
- sudo systemctl reload firewalld