darkzonesd
Goto Top

SNMP Traps empfangen und interpretieren

Guten Morgen zusammen,

wir würden gerne bei uns in der Firma PortSecurity Violations festhalten und per E-Mail informiert werden sobald ein solches Event eine SNMP Trap auslöst. Nun habe ich mir das zur Aufgabe gemacht und führe testweise ein Programm aus das SNMP Traps von unserem PRTG Server aus abfängt. Leider würde ich es über den SNMP Trap Receiver der bei PRTG eingebaut ist gerne direkt abfragen können, nur leider schaltet dieser Sensor nur für etwa 5 Sekunden auf Error um sobald er eine Trap erhält und schafft es nicht rechtzeitig eine E-Mail zu versenden auch wenn er auf "Inform immerdiatley" steht.

Nun war die Idee eine kleine Anwendung zu schreiben die auf 0.0.0.0:162 SNMP Traps empfängt und dann als Service auf dem "SNMP Receiver Server" laufen zu lassen. Es handelt sich bei dem Switch um einen HP (Aruba) HP 2530-24G-PoEP (J9773A), die MIB und OID Dokumentation lässt leider sehr zu wünschen übrig (vemutlich aufgrund der Aruba akquirierung), nach einiger Zeit suchen habe ich folgende OID gefunden:

1.3.6.1.4.1.11.2.3.7.11.12.1.3.1.17.0 - sn sw violator port number
The port number of the switch or router that received a violator packet. It is included in the locked address violation trap. The bit 0 to bit 7: port number. The bit 8 to bit 11: slot number (slot for chassis only).

Das Programm funktioniert insofern das ich über die OID, die Port Nummer des Switches auslesen kann, nur leider schafft es das Programm per gesendeter Meldung vom Switch die Meldung 3 mal zu empfangen. Ich habe versucht anhand des Timestamps des Pakets dafür zu sorgen das er die selben Pakete maximal 1 mal verarbeitet, leider haben diese Pakete aber immer einen unterschiedlichen Timestamp und können deshalb nicht eindeutig von einander unterschieden werden.

Jetzt bin ich an einem Punkt andem ich nichtmehr weiter komme, und nicht verstehe warum hier mehrere Paket pro "PortSecurity Violation" empfangen werden. Liegt es am Switch der 3 Meldungen sendet, verstehe ich das SNMP Protokoll falsch oder hänge ich im Program noch in einer Schleife? wenn jemand weiter weiß wäre ich sehr dankbar.

Switch Meldung:
sw-meldung
Programm-Output:
program-output
Sourcecode:
internal class Program
    {
        public static HashSet<string> processedTraps = new HashSet<string>();
        static void Main(string[] args)
        {

            int port;
            string targetOidPrefix = "1.3.6.1.4.1.11.2.14.2.10.2.1.3";  
            string targetValue = null;

            if (args.Length == 0)
            {
                port = 162;
            }
            else
            {
                 port = int.Parse(args[0]);
            }
            // Construct a socket and bind it to the trap manager port 162 
            Socket socket = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp);
            Console.WriteLine("Creating Socket..");  
            IPEndPoint ipep = new IPEndPoint(IPAddress.Any, port);
            Console.WriteLine("Setting Socket Configuration..");  
            EndPoint ep = (EndPoint)ipep;
            socket.Bind(ep);
            Console.WriteLine($"Binding Socket on Address: {ipep.Address} using Port: {ipep.Port}");  
           
            // Disable timeout processing. Just block until packet is received 
            socket.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReceiveTimeout, 0);
            bool run = true;
            int inlen = -1;
            while (run)
            {
                Console.WriteLine($"Listening on Port: {ipep.Port}...");  
                byte[] indata = new byte[16 * 1024];
                // 16KB receive buffer int inlen = 0;
                IPEndPoint peer = new IPEndPoint(IPAddress.Any, 0);
                EndPoint inep = (EndPoint)peer;
                try
                {
                    inlen = socket.ReceiveFrom(indata, ref inep);
                }
                catch (Exception ex)
                {
                    Console.WriteLine("Exception {0}", ex.Message);  
                    inlen = -1;
                }
                if (inlen > 0)
                {
                    // Check protocol version int 
                    int ver = SnmpPacket.GetProtocolVersion(indata, inlen);
                    if (ver == (int)SnmpVersion.Ver1)
                    {
                        // Parse SNMP Version 1 TRAP packet 
                        SnmpV1TrapPacket pkt = new SnmpV1TrapPacket();
                        pkt.decode(indata, inlen);

                        string swAddress = pkt.Pdu.AgentAddress.ToString();
                        string trapIdentifier = pkt.Pdu.TimeStamp.ToString();

                        if (!processedTraps.Contains(trapIdentifier))
                        {
                            Console.WriteLine("Trap not found in Hashset, processing..");  
                            Console.WriteLine("Hashset with timestamps:");  
                            Console.WriteLine("-----------------------------");  
                            foreach (String s in processedTraps)
                            {
                                Console.WriteLine(s);
                            }
                            Console.WriteLine("-----------------------------");  

                            foreach (Vb v in pkt.Pdu.VbList)
                            {
                                if (v.Oid.ToString().StartsWith(targetOidPrefix))
                                {
                                    Console.WriteLine("Found a matching OID. Paket has a timestamp of: {0}", pkt.Pdu.TimeStamp.ToString());  
                                    targetValue = v.Value.ToString();
                                    break; // Exit the loop once the value is found
                                }
                            }

                            if (targetValue != null)
                            {
                                Console.WriteLine("Value for OID starting with {0}: {1}", targetOidPrefix, targetValue);  

                            }
                            else
                            {
                                Console.WriteLine("No value found for OID starting with {0}", targetOidPrefix);  
                            }

                            Console.WriteLine("** End of SNMP Version 1 TRAP data.");  

                            processedTraps.Add(trapIdentifier);
                            Console.WriteLine("Hashset with timestamps after processing:");  
                            Console.WriteLine("-----------------------------");  
                            foreach (String s in processedTraps)
                            {
                                Console.WriteLine(s);
                            }
                            Console.WriteLine("-----------------------------");  
                        }
                        else
                        {
                            Console.WriteLine("Trap already processed: {0}", trapIdentifier);  
                        }
                            
                    }
                }
                else
                {
                    if (inlen == 0)
                        Console.WriteLine("Zero length packet received.");  
                }
            }
        }
    }

Content-Key: 72507260020

Url: https://administrator.de/contentid/72507260020

Printed on: April 27, 2024 at 09:04 o'clock

Member: DarkZoneSD
Solution DarkZoneSD Feb 09, 2024 at 08:11:14 (UTC)
Goto Top
Ich habe den Fehler gefunden..

Sobald er einmal ein Paket mit einer matching OID gefunden hat wird string targetValue von "null" auf den gefundenen Wert gesetzt. Wird aber nie auf null zurück geschrieben, heißt sobald er einmal ein paket gefunden hat, wird bei jedem nachfolgenden Paket in die Kondition
if (targetValue != null)
    {
        Console.WriteLine("Value for OID starting with {0}: {1}", targetOidPrefix, targetValue);    
    }
gesprungen, die dann den Wert ausgibt..

Ist denn schon wieder Montag? 🥱

Viele Grüße und ein schönes Wochenende..