hi Clayton, Also, for completeness, here’s what worked for our user. > > This rule detects a BGP routing tunnel going down. The rule then waits for > a matching "Up" event from the same host with the same neighbor IP. Once > detected, it then measures the total time the route was down and generates > a new event. > > In the rule, this user’s company also uses the hostname to extract the > location ID (they have stores across the US) and the BGP Tunnel ID. > > The hostname reverse lookups are something like 1234lo5678.foo.com > > These generated events then go into a LogZilla trigger to kick off an > automation. Cool stuff. >
> > Sample events: > > %BGP-5-ADJCHANGE: neighbor 10.1.0.1 Down BGP Notification received > > %BGP-5-ADJCHANGE: neighbor 10.1.0.1 Up > > > > type=Single > > ptype=SubStr > > pattern=SEC_STARTUP > > context=SEC_INTERNAL_EVENT > > continue=TakeNext > > desc=Load the Socket module and terminate if it is not found > > action=eval %ret (require Socket); \ > > if %ret ( logonly Socket module loaded ) else ( eval %o exit(1) ) > > > > type=Pair > > ptype=RegExp > > continue=dontcont > > pattern=neighbor \*?(\d+\.\d+\.\d+\.\d+) Down > > varmap= nip=1 > > desc=BGP Neighbor $1 Down > > action=lcall %hostname $1 -> ( sub { my $host = scalar > gethostbyaddr(Socket::inet_aton($_[0]), Socket::AF_INET); if > (!defined($host)) { $host = $_[0]; } return $host; } ); \ > > eval %storenumber ( if ("%hostname" =~ /(\d+)lo/) { "$$1"; } else { > "NA"; } ); \ > > eval %tunnel ( if ("%hostname" =~ /lo(\d+)/) { "$$1"; } else { "NA"; } > ); \ > > eval %TS (time()); \ > > tcpsock 10.1.0.1:514 SEC BGP Neighbor status="Down" > hostname="%hostname" store="%storenumber" tunnel="%tunnel" > ECRule="01-bgp-flap-detection" ECRulenum="1"%{.nl}; > > ptype2=RegExp > > pattern2=neighbor $+{nip} Up > > desc2=BGP Neighbor $1 Up > > action2=eval %TT ( time() - %TS ); \ > > tcpsock 10.1.0.1:514 SEC BGP Neighbor status="Up" > hostname="%hostname" store="%storenumber" tunnel="%tunnel" downtime="%TT" > ECRule="01-bgp-flap-detection" ECRulenum="2"%{.nl} > > thanks for sharing the ruleset with the mailing list! I have one small side note -- is it possible to have several "neighbor <IP> Down" error conditions for different IP addresses that are open in parallel? If so, each "neighbor <IP> Down" event will overwrite the values of %hostname, %storenumber and other action list variables, and when error conditions are resolved, most recent values are reported for all conditions. For resolving this issue, it is best to store those values in match variables, since they are unique for each event correlation operation. Storing all relevant data in match variables has one additional benefit -- all event processing takes place in event matching pattern (albeit more complex than a regular expression), and rest of the rule definition becomes more simple. So here is another version of this ruleset: type=Single ptype=SubStr pattern=SEC_STARTUP context=SEC_INTERNAL_EVENT desc=Load the Socket module and terminate if it is not found action=eval %ret (require Socket); \ if %ret ( logonly Socket module loaded ) else ( eval %o exit(1) ) type=Pair ptype=PerlFunc pattern=sub { my(%var); \ if ($_[0] !~ /neighbor \*?(\d+\.\d+\.\d+\.\d+) Down/) { return 0; } \ $var{"nip"} = $1; $var{"ts"} = time(); \ $var{"hostname"} = scalar gethostbyaddr(Socket::inet_aton($var{"nip"}), Socket::AF_INET); \ if (!defined($var{"hostname"})) { $var{"hostname"} = $var{"nip"} }; \ $var{"storenumber"} = "NA"; $var{"tunnel"} = "NA"; \ if ($var{"hostname"} =~ /(\d+)lo/) { $var{"storenumber"} = $1; } \ if ($var{"hostname"} =~ /lo(\d+)/) { $var{"tunnel"} = $1; } \ return \%var; } desc=BGP Neighbor $+{nip} Down action=tcpsock 10.1.0.1:514 SEC BGP Neighbor status="Down" hostname="$+{hostname}" store="$+{storenumber}" tunnel="$+{tunnel}" ECRule="01-bgp-flap-detection" ECRulenum="1"%{.nl}; ptype2=RegExp pattern2=neighbor $+{nip} Up desc2=BGP Neighbor %+{nip} Up action2=lcall %TT %+{ts} -> ( sub { time() - $_[0] } ); \ tcpsock 10.1.0.1:514 SEC BGP Neighbor status="Up" hostname="%+{hostname}" store="%+{storenumber}" tunnel="%+{tunnel}" downtime="%TT" ECRule="01-bgp-flap-detection" ECRulenum="2"%{.nl} This ruleset uses PerlFunc pattern for not only matching the "neighbor <IP> Down" event and setting the $+{nip} match variable, but it consolidates all Perl code fragments from the rule into a single function which also sets $+{hostname}, $+{storenumber}, $+{tunnel} and $+{ts} match variables. The match variables are created by storing all data in a Perl hash, and returning a reference to this hash from the pattern function (that's a standard way for creating named match variables in a PerlFunc pattern). This rule definition is able to handle simultaneous error conditions for several IP addresses, and also uses the same naming scheme for all relevant data which is perhaps more clear. (The only exception is %TT action list variable which is used for calculating the downtime, but it is essentially a temporary variable which can be overwritten by other event correlation operation after its use.) Finally, my apologies for providing several solutions for the same problem, but I wanted to fully clarify what are the advantages and disadvantages of each solution. > > > > I’ve said this 1000’s of times over the years Risto, but once more. > Thanks for making such an awesome tool! > It is great to hear that you have found sec useful -- hearing positive feedback from sec users is really important to me :) kind regards, risto > >
_______________________________________________ Simple-evcorr-users mailing list Simple-evcorr-users@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/simple-evcorr-users