我正在为一个非常大的networking(大约5000个networking设备)实施networking监控解决scheme。 我们希望我们networking上的所有设备都将SNMP陷阱发送到一个盒子(技术上这可能是HA盒子对),然后让该盒子将SNMP陷阱传递到真正的处理盒。 这将允许我们有多个后端处理陷阱,并在这些后端盒子之间分配负载。
我们需要的一个关键特性是能够根据陷阱的源地址将陷阱转发到特定的盒子。 任何build议为最好的方式来处理这个?
在我们考虑的事情中有:
我们目前已经实施并正在testing最后一个解决scheme,使用配有IPTables的Linux机箱来configuration接收陷阱,然后根据陷阱的源地址,用目标nat(DNAT)重写它,以便将数据包发送到正确的服务器。 例如:
# Range: 10.0.0.0/19 Site: abc01 Destination: foo01 iptables -t nat -A PREROUTING -p udp --dport 162 -s 10.0.0.0/19 -j DNAT --to-destination 10.1.2.3 # Range: 10.0.33.0/21 Site: abc01 Destination: foo01 iptables -t nat -A PREROUTING -p udp --dport 162 -s 10.0.33.0/21 -j DNAT --to-destination 10.1.2.3 # Range: 10.1.0.0/16 Site: xyz01 Destination: bar01 iptables -t nat -A PREROUTING -p udp --dport 162 -s 10.1.0.0/16 -j DNAT --to-destination 10.3.2.1
对于基本的陷阱路由,这应该具有极高的效率,但是这使得我们完全局限于我们可以用IPTables进行加工和过滤,所以我们关心未来的灵活性。
我们真正喜欢的另一个function,但不是“必须拥有”的function是能够复制或镜像UDP数据包。 能够接收一个陷阱并将其路由到多个目的地将是非常有用的。
有没有人尝试过上述任何可能的解决scheme的SNMP陷阱(或Netflow的,一般的UDP等)负载平衡? 或者任何人都可以想出其他的办法来解决这个问题吗?
一位同事刚刚向我展示了samplicator 。 这个工具看起来只是一个完美的解决scheme,我一直在寻找。 从工具的网站:
这个简单的程序监听networking端口上的UDP数据报,并将这些数据报的副本发送到一组目的地。 可选地,它可以执行采样,而不是转发每个数据包,只能在N中转发1个数据。另一个select是它可以“欺骗”IP源地址,使得副本看起来来自原始源而不是中继。 目前只支持IPv4。
它可以用来分发例如Netflow数据包,SNMP陷阱(但不是通知)或Syslog消息到多个接收器。
我会自己去执行解决scheme,因为我不知道你是否会find你想要的东西。
我会使用像ruby这样的高级语言来实现平衡规则,甚至陷阱监听器。 例如,使用这个库 似乎 很容易 。
听陷阱:
m = SNMP::TrapListener.new(:Port => 1062, :Community => 'public') do |manager| manager.on_trap_default { |trap| p trap } end m.join
您应该在on_trap_default
块中添加平衡逻辑。
发送陷阱:
Manager.open(:Version => :SNMPv1) do |snmp| snmp.trap_v1( "enterprises.9", "10.1.2.3", :enterpriseSpecific, 42, 12345, [VarBind.new("1.3.6.1.2.3.4", Integer.new(1))]) end
要构build守护进程,您可以使用守护进程套件rubygem。
如果你保持简单并定义好的对象,你可以毫不费力地维护软件。
你的主要问题是,你怎么知道你收到陷阱的设备的实际ip?
如果您使用的是SNMP v1,则可以从陷阱的头部获取ip。 如果您使用的是v2或v3陷阱,则需要将snmpengine id与先前从设备中获取的ip相关联。 对于大多数SNMP实现来说,Engineid通常不是一个强制的configuration项目,因此你不能完全依靠这个。
回退是你可以使用udp包头中的源IP。 当然,如果你的陷阱通过另一个EMS / NMS路由,或者你的设备和你的mgmt应用程序之间有一个NAT,这将会失败。
如果不需要从其他NMS支持NAT /转发陷阱,那么只需要制作udp数据包的副本,并根据ip进行路由
如果您需要支持该function,则必须parsingSNMP陷阱并检查引擎ID是否匹配v2 / v3,对于v1,您可以从SNMP头中的代理地址字段读取它。
一个基于netfilter的黑客:
iptables -t nat -A PREROUTING -d 10.0.0.1 -p udp --dport 162 -m random --average 33 -j DNAT --to-destination 10.0.0.2:162 iptables -t nat -A PREROUTING -d 10.0.0.1 -p udp --dport 162 -m random --average 33 -j DNAT --to-destination 10.0.0.3:162 # everything else goes to other consumer iptables -t nat -A PREROUTING -d 10.0.0.1 -p udp --dport 162 -j DNAT --to-destination 10.0.0.4:162
[假设 – 所有陷阱都发送到10.0.0.1,然后将它们redirect到10.0.0.2,10.0.0.3,10.0.0.4]
只要你有一个包长的snmp陷阱 – 这应该传播负载很好 – 在这种情况下跨3台机器。 [虽然我没有testing过]。
我认为chmeee的答案是正确的。 在这个过程中尽早摆脱UDP和SNMP,他们是可怕的pipe理。
我现在正在构build一个将所有事件(包括陷阱)放到JMS队列中的系统,然后使用企业消息传递的所有奇迹来执行负载平衡和故障转移。
你的主要问题是,你怎么知道你收到陷阱的设备的实际ip?
要获得原始发件人的IP,您可以尝试使用此修补程序修补snmptrapd – https://sourceforge.net/p/net-snmp/patches/1320/#6afe 。
这修改了有效负载,所以IP头将保持不变,所以它们不会进入路由和/或NAT。