非常に大規模なネットワーク(約5000のネットワークデバイス)のネットワーク監視ソリューションを実装しています。ネットワーク上のすべてのデバイスからSNMPトラップを1つのボックスに送信し(技術的には、これはおそらくHAのペアのボックスになります)、そのボックスでSNMPトラップを実際の処理ボックスに渡します。これにより、複数のバックエンドボックスでトラップを処理し、それらのバックエンドボックス間で負荷を分散できます。
必要な重要な機能の1つは、トラップの送信元アドレスに応じて、トラップを特定のボックスに転送する機能です。これを処理する最良の方法について何か提案はありますか?
私たちが検討したことには、次のものがあります。
私たちは現在、トラップを受信するように構成されたIPTablesを備えたLinuxボックスを使用して最後のソリューションを実装およびテストしています。次に、トラップの送信元アドレスに応じて、宛先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
これは、基本的なトラップルーティングに優れた効率で機能するはずですが、IPTableを使用してフィルター処理できるものに完全に制限されているため、将来の柔軟性に懸念があります。
本当にに似ているが、「必須」ではないもう1つの機能は、UDPパケットを複製またはミラーリングする機能です。 1つの着信トラップを取得して複数の宛先にルーティングできると、非常に便利です。
誰かがSNMPトラップ(またはNetflow、一般的なUDPなど)の負荷分散のために上記の可能な解決策のいずれかを試しましたか?または、これを解決するための他の代替案を誰かが考えることができますか?
同僚が私に見せた samplicator 。このツールは、私が探していた完璧なソリューションのように見えます。ツールのWebサイトから:
この単純なプログラムは、ネットワークポートでUDPデータグラムをリッスンし、これらのデータグラムのコピーを一連の宛先に送信します。オプションで、サンプリングを実行できます。つまり、すべてのパケットを転送するのではなく、1をNで転送します。別のオプションは、IP送信元アドレスを「スプーフィング」して、コピーがリレーではなく元の送信元から送信されているように見せることです。現在、IPv4のみをサポートしています。
配布に使用できます。複数の受信者へのNetflowパケット、SNMPトラップ(インフォームではない)、またはSyslogメッセージ。
私がソリューションを自分で実装するつもりです。あなたが望むほど具体的なものを見つけるかどうかはわかりません。
Rubyなどの高水準言語を使用して、バランスルールとトラップリスナーを実装します。たとえば、 this librariesseems = 簡単 。
トラップを聞く:
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
デーモンを構築するには、 daemon-kit Ruby gem。
シンプルに保ち、適切なオブジェクトを定義すれば、それほど労力をかけずにソフトウェアを保守できます。
あなたの主な問題は、トラップを受信しているデバイスの実際のIPをどのようにして知るかです。
SNMP v1を使用している場合は、トラップのヘッダーからIPを取得できます。 v2またはv3トラップを使用している場合は、snmpengine IDを以前にデバイスからフェッチしたIPに関連付ける必要があります。 Engineidは通常、ほとんどのSNMP実装で必須の構成項目ではないため、それだけでは完全に依存することはできません。
フォールバックは、udpパケットヘッダーのソースIPを使用できることです。もちろん、これが失敗するのは、トラップが別のEMS/NMSを経由してルーティングされている場合、またはデバイスとmgmtアプリケーションの間にNATがある場合です。
他のNMSからのNAT /転送トラップをサポートする必要がない場合は、udpパケットのコピーを作成し、IPに基づいてルーティングします
これをサポートする必要がある場合は、SNMPトラップを解析してv2/v3のエンジンIDの一致を確認する必要があります。v1の場合は、SNMPヘッダーのagent-addressフィールドから読み取ることができます。
もう1つの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に送信され、その後10.0.0.2、10.0.0.3、10.0.0.4にリダイレクトされます]
1パケット長のSNMPトラップがある限り-これは負荷を適切に分散するはずです-この場合は3台のマシンにまたがります。 [私はテストしていませんが]。
Chmeeeからの答えは正しい方法だと思います。プロセスのできるだけ早い段階でUDPとSNMPを取り除くと、それらを管理するのはひどいものになります。
現在、すべてのイベント(トラップを含む)をJMSキューに入れ、エンタープライズメッセージングの驚異のすべてを使用してロードバランシングとフェイルオーバーを行うシステムを構築しています。
あなたの主な問題は、トラップを受信しているデバイスの実際のIPをどのようにして知るかです。
元の送信者のIPを取得するには、このパッチでsnmptrapdにパッチを適用してみてください https://sourceforge.net/p/net-snmp/patches/1320/#6afe 。
これによりペイロードが変更されるため、IPヘッダーはそのまま維持され、ルーティングやNAT処理に組み込まれません。