<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 TRANSITIONAL//EN">
<HTML>
<HEAD>
  <META HTTP-EQUIV="Content-Type" CONTENT="text/html; CHARSET=UTF-8">
  <META NAME="GENERATOR" CONTENT="GtkHTML/3.28.3">
  <TITLE>@@weblog</TITLE>
</HEAD>
<BODY>
<BR>
<BR>
<H1>
<B><FONT SIZE="6"><A HREF="http://bazsi.blogs.balabit.com/2010/10/syslog-ng-correllation-updated/">syslog-ng correllation updated</A></FONT></B>
</H1>
I&#8217;m trying to push syslog-ng 3.2beta1 out on the door, but as I was writing the NEWS entry I had to realize that the latest state of the patterndb correllation functions are undocumented so far. So here goes a blog post which tries to summarize how it works, so that I can include it in the NEWS entry :)<BR>
<BR>
My previous post on the topic used a syntax that included explicit &#8220;store&#8221; and &#8220;join&#8221; elements, but I&#8217;ve decided to drop those, as they stood in the way for some more juicy functionality. What remained is that the correllation is still focused around a &#8220;correllation state&#8221;, or as I&#8217;ve called internally a <B>&#8220;context&#8221;</B>.<BR>
<BR>
A context consists of a series of log messages related to each other in some way. As new messages come in, they may be associated with a context (e.g. added to the context). Also, when an incoming message is identified it can trigger some actions to be performed. And these actions can use all the information that was stored previously in the context.<BR>
<BR>
Let&#8217;s see how this work out with concrete examples: each rule in the patterndb has a &#8220;context-id&#8221; attribute telling db-parser() which context the given message should be associated with.<BR>
<BR>
This example covers an SSH login message:<BR>
<BR>
<PRE>
&lt;rule id=&#8221;&#8230;&#8221; <B>context-id=&#8221;$HOST:$PROGRAM:$PID&#8221;</B> context-timeout=&#8221;86400&#8243; context-scope=&#8221;global&#8221;&gt;
&nbsp; &lt;patterns&gt;
&nbsp;&nbsp;&nbsp; &lt;pattern&gt;Accepted @ESTRING:usracct.authmethod: @for @ESTRING:usracct.username: @from @ESTRING:usracct.device: @port @ESTRING:: @@ANYSTRING:usracct.service@&lt;/pattern&gt;
&nbsp; &lt;/patterns&gt;
&nbsp; &#8230;
&lt;/rule&gt;
</PRE>
<BR>
Since multiple rules can reference the same context, multiple different kind of messages may be added into the same context as a result. E.g. the logout event looks like this:
<PRE>

&lt;rule <B>context-id=&#8221;$HOST:$PROGRAM:$PID&#8221;</B> context-timeout=&#8221;0&#8243; context-scope=&#8221;global&#8221;&gt;
&nbsp; &lt;patterns&gt;
&nbsp;&nbsp;&nbsp; &lt;pattern&gt;pam_unix(sshd:session): session closed for user @ANYSTRING:usracct.username:@&lt;/pattern&gt;
&nbsp; &lt;/patterns&gt;
&nbsp; &#8230;
&lt;/rule&gt;
</PRE>
<BR>
As you can see a &#8220;session&#8221; is identified using the triplet ($HOST, $PROGRAM, $PID) and these two rules correllate the login/logout events into the same context, which means that you can create a derived event that contains information from both of them.<BR>
<BR>
Please note that it is fairly common that messages only need to be correllated if they originate from the same host: e.g. this SSH login message needs only to be correllated to its logout counterpart if they both originate from the same host. In the previous example this was achieved using explicit macros in the context-id attribute, however since this is quite often the case, this was worked into a function of its own right: each rule can have a context-scope attribute:<BR>
<BR>
<PRE>
&lt;rule id=&#8221;&#8230;&#8221; <B>context-scope=&#8221;process&#8221;</B> context-id=&#8221;ssh-login&#8221; context-timeout=&#8221;5&#8243;&gt;
&lt;/rule&gt;
</PRE>
<BR>
The context-scope tells syslog-ng which messages need to be considered when looking for correllations:<BR>
<BR>
<UL>
    <LI>process: only consider messages that have matching $HOST, $PROGRAM and $PID values
    <LI>program: only consider messages that have matching $HOST and $PROGRAM values
    <LI>host: only consider messages that have matching $HOST values
    <LI>global: any kind of message is fine
</UL>
<BR>
The default is to use &#8220;process&#8221;, which means that if it is true that the same process is emitting all the messages that you want to correllate, then you don&#8217;t need to use a variable part in your context-id attribute. But it is also important to know that it is way faster to specify the scope this way than it&#8217;d be to add all relevant macros to your context-id attribute.<BR>
<BR>
So far so good, we have all the functions that we used to have with the previous versions of the functionality. But I mentioned something about &#8220;actions&#8221; to be performed. Until now a patterndb rule basically only identified the incoming message, possibly associated tags and name-value pairs, but didn&#8217;t perform anything else. This is being changed: one or more actions can be associated with a patterndb rule in order to make it possible to react to more complex situations.<BR>
<BR>
Here&#8217;s an example action:<BR>
<BR>
<PRE>
&lt;action rate=&#8221;1/86400&#8243;&gt;
&nbsp; &lt;message&gt;
&nbsp;&nbsp;&nbsp; &lt;values&gt;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;value name=&#8221;MESSAGE&#8221;&gt;a patterndb rule matched&lt;/value&gt;
&nbsp;&nbsp;&nbsp; &lt;/values&gt;
&nbsp; &lt;/message&gt;
&lt;/action&gt;
</PRE>
<BR>
Right now the only real response to a message is to generate another message, but this allows us to do a couple of powerful transformations, especially with the following options that you can specify for an action tag:<BR>
<BR>
<UL>
    <LI>condition: specifies a syslog-ng filter expression that needs to be matched in order to really perform the action. It is evaluated on the current message that matched the rule.
    <LI>rate: &lt;num&gt;/&lt;period&gt; specifies how much messages are to be generated (num), in the specified time period (period). Excess messages are dropped. For example: &#8220;1/60&#8243; allows 1 message / minute. Rates apply&nbsp; to the given scope for the given rule/action. E.g. context-scope=&#8221;host&#8221;, rate=&#8221;1/60&#8243; means that one message gets generated for _each host_ per minute.
    <LI>trigger: specifies when to execute the action, there are two possible triggers right now: 
    <UL>
        <LI>match: execute immediately once the rule matches
        <LI>timeout: execute when the correllation timer expires
    </UL>
</UL>
<BR>
I&#8217;d like to highlight two things:<BR>
<BR>
<UL>
    <LI>it is possible to react to the expiration of a correllation timer (e.g. trigger=&#8221;timeout&#8221;)
    <LI>it is possible to generate a message only in case a given condition is met (e.g. &#8220;$PID&#8221; == &#8220;&#8221;)
</UL>
<BR>
Right now new messages are posted to the internal() driver. This is not the way I wanted it to be, but doing my original plan would require an enormous refactorization of the code, and it is too late for that too happen. My original idea was to let the db-parser() emit multiple messages, but since the current state of affairs in syslog-ng assumes that only sources generate messages, that needs a lot of work. But hey, we need something to do for syslog-ng 3.3, right?<BR>
<BR>
<BR>
<BR>
</BODY>
</HTML>