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

Reply via email to