<?xml version="1.0" encoding="UTF-8"?><rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Logging &#8211; Johnny Morano&#039;s Tech Articles</title>
	<atom:link href="https://jmorano.moretrix.com/tag/logging/feed/" rel="self" type="application/rss+xml" />
	<link>https://jmorano.moretrix.com</link>
	<description>Ramblings of an old-fashioned space cowboy</description>
	<lastBuildDate>Sat, 09 Apr 2022 07:06:57 +0000</lastBuildDate>
	<language>en-US</language>
	<sy:updatePeriod>
	hourly	</sy:updatePeriod>
	<sy:updateFrequency>
	1	</sy:updateFrequency>
	<generator>https://wordpress.org/?v=6.6.2</generator>

<image>
	<url>https://jmorano.moretrix.com/wp-content/uploads/2022/04/cropped-jmorano_emblem-32x32.png</url>
	<title>Logging &#8211; Johnny Morano&#039;s Tech Articles</title>
	<link>https://jmorano.moretrix.com</link>
	<width>32</width>
	<height>32</height>
</image> 
	<item>
		<title>Perl script to monitor the rate of logs</title>
		<link>https://jmorano.moretrix.com/2022/04/perl-script-to-monitor-the-rate-of-logs/</link>
					<comments>https://jmorano.moretrix.com/2022/04/perl-script-to-monitor-the-rate-of-logs/#respond</comments>
		
		<dc:creator><![CDATA[Johnny Morano]]></dc:creator>
		<pubDate>Thu, 07 Apr 2022 12:39:50 +0000</pubDate>
				<category><![CDATA[Blog]]></category>
		<category><![CDATA[Development]]></category>
		<category><![CDATA[Perl]]></category>
		<category><![CDATA[Dev]]></category>
		<category><![CDATA[DevOps]]></category>
		<category><![CDATA[IPTables]]></category>
		<category><![CDATA[Linux]]></category>
		<category><![CDATA[Logging]]></category>
		<guid isPermaLink="false">https://jmorano.moretrix.com/?p=1399</guid>

					<description><![CDATA[In a previous article (IPTables Logging in JSON with NFLOG and ulogd2) we learned how to log certain&#8230;]]></description>
										<content:encoded><![CDATA[
<p>In a previous article (<a href="https://jmorano.moretrix.com/2022/03/logging-in-iptables-with-nflog-and-ulogd2/" data-type="post" data-id="1308">IPTables Logging in JSON with NFLOG and ulogd2</a>) we learned how to log certain IPTables rules to JSON log files.</p>



<p>Monitoring the logs in real-time on the command line, can also be very useful when debugging either the rules themselves or when analyzing certain issues. Rather than just looking at the logs, in some situations it might be useful to track the rate of the log messages. A self-written Perl script can be useful as it allows to be flexible when it comes to:</p>



<ul class="wp-block-list"><li>parsing logs</li><li>formatting the output (with colors or tables or &#8230;)</li><li>calculating statistics</li><li>&#8230;</li></ul>



<p>The following Perl script uses a few modules which need to be present:</p>



<pre class="EnlighterJSRAW" data-enlighter-language="python" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">use IO::Async::Timer::Periodic;
use IO::Async::Loop;
use Time::HiRes qw/time/;
use Term::ANSIColor qw(:constants);
use Getopt::Long;</pre>



<p>The first two modules can be installed on Debian systems with:</p>



<pre class="EnlighterJSRAW" data-enlighter-language="generic" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">apt install libio-async-perl</pre>



<p>The others are part of the normal Perl packages and do not require any extra installation.</p>



<p>Next the script will use a polling mechanism to read from standard output at fixed intervals, to calculate the rate of the unique log lines. The default polling rate is set to 2 seconds but it can be managed through command line parameters:</p>



<pre class="EnlighterJSRAW" data-enlighter-language="python" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">my $last_poll_time = time;

my $poll_rate = 2;
GetOptions (
    'p|pollrate=i' => \$poll_rate,
);

my $loop = IO::Async::Loop->new;
my $timer = IO::Async::Timer::Periodic->new(
   interval => $poll_rate,
   on_tick  => \&amp;log_rate
);

$timer->start;
$loop->add( $timer );
$loop->run;</pre>



<p>Finally, the script will define a subroutine called <code>log_rate</code>, which will read from standard output (or even a file) at each poll interval. Important is of course that the log lines from standard output do not contain unique data such as timestamps. The output must be as generic as possible.</p>



<p>Example:</p>



<pre class="EnlighterJSRAW" data-enlighter-language="generic" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">tail -qf /var/log/ulog/blocked_detailed.json /var/log/ulog/blocked.json /var/log/ulog/passed.json  | jq -r --unbuffered '."oob.prefix"' 
blocked: invalid state
blocked: invalid state
blocked: invalid state
blocked: invalid state
blocked: invalid state
action=blocked
action=blocked
action=blocked
action=blocked
action=blocked
action=passed
action=passed
action=passed
action=passed</pre>



<p>The code snippit for <code>log_rate</code> could contain:</p>



<pre class="EnlighterJSRAW" data-enlighter-language="python" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">sub log_rate {
    local $SIG{ALRM} = sub { die time, " time exceeded to read STDIN\n" };

    alarm($poll_rate);
    my $h;
    eval {
        local $| = 1;
        while (my $line = &lt;>) {
            chomp($line);
            $h->{$line}++;
        }
    };
    alarm(0);

    return unless keys %$h;

    my $delta_time = time - $last_poll_time;
    print DARK WHITE . sprintf("%d: ", time) . RESET;
    print( BOLD WHITE . $_ ." [" . GREEN . sprintf("%.2f/s", $h->{$_}/$delta_time) . BOLD WHITE "] | " . RESET) foreach keys %$h; 
    print "\n";

    $last_poll_time = time;
}</pre>



<p><mark style="background-color:rgba(0, 0, 0, 0)" class="has-inline-color has-vivid-red-color">Line 2</mark> will start with declaring the &#8220;<code>ALARM</code>&#8221; signal. This signal is called when the <code>alarm</code> timeout has been reached (see further below).</p>



<p><mark style="background-color:rgba(0, 0, 0, 0)" class="has-inline-color has-vivid-red-color">Line 4</mark> defines the <code>alarm</code> timeout in seconds: meaning: if everything below<mark style="background-color:rgba(0, 0, 0, 0)" class="has-inline-color has-vivid-red-color"> line 4</mark> (until the next <code>alarm</code> line) takes longer than the defined timeout in seconds, the &#8220;ALRM&#8221; signal handler defined at <mark style="background-color:rgba(0, 0, 0, 0)" class="has-inline-color has-vivid-red-color">line 2</mark> will be called, which basically stops the code execution with a <code>die</code> (which in theory should stop the script with an <code>exit 1</code>).</p>



<p><mark style="background-color:rgba(0, 0, 0, 0)" class="has-inline-color has-vivid-red-color">Line 5</mark> defines a hash reference which is required down below, to temporarily store unique log lines.</p>



<p><mark style="background-color:rgba(0, 0, 0, 0)" class="has-inline-color has-vivid-red-color">Line 6</mark> until <mark style="background-color:rgba(0, 0, 0, 0)" class="has-inline-color has-vivid-red-color">12</mark> define an <code>eval</code> block. The <code>eval</code> block will catch the ALRM signal <code>die</code> (once reached) without stopping the script with an <code>exit 1</code>. Inside the <code>eval</code> block, the standard output will be read with the diamond operator (<code>&lt;></code>) and unique lines will be counted and stored in the <code>$h</code> hash reference.</p>



<p><mark style="background-color:rgba(0, 0, 0, 0)" class="has-inline-color has-vivid-red-color">Line 13</mark>, right after the <code>eval</code> block, sets to <code>alarm</code> timeout to 0 again, which means it is disabled. This allows that only execution of the <code>eval</code> block will be evaluated for timeout. </p>



<p><mark style="background-color:rgba(0, 0, 0, 0)" class="has-inline-color has-vivid-red-color">Line 15</mark> ensures that only when log lines were discovered and stored in the temporary hash-ref<code> $h</code>, that rates will be printed to the screen.</p>



<p>The rest of the code will take care of printing the discovered log lines with their rates to the screen. Colors from <code>Term::ANSIColor</code> are used to make the output more vivid.</p>



<p>Example output:</p>



<figure class="wp-block-image size-full"><img fetchpriority="high" decoding="async" width="911" height="285" src="https://jmorano.moretrix.com/wp-content/uploads/2022/04/Screenshot-from-2022-04-06-14-14-00.png" alt="" class="wp-image-1405" srcset="https://jmorano.moretrix.com/wp-content/uploads/2022/04/Screenshot-from-2022-04-06-14-14-00.png 911w, https://jmorano.moretrix.com/wp-content/uploads/2022/04/Screenshot-from-2022-04-06-14-14-00-300x94.png 300w, https://jmorano.moretrix.com/wp-content/uploads/2022/04/Screenshot-from-2022-04-06-14-14-00-768x240.png 768w" sizes="(max-width: 911px) 100vw, 911px" /></figure>



<p>The full version of the script can be found at: <a href="https://github.com/insani4c/perl_tools/tree/master/log_rate" target="_blank" rel="noreferrer noopener">https://github.com/insani4c/perl_tools/tree/master/log_rate</a></p>
]]></content:encoded>
					
					<wfw:commentRss>https://jmorano.moretrix.com/2022/04/perl-script-to-monitor-the-rate-of-logs/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>IPTables Logging in JSON with NFLOG and ulogd2</title>
		<link>https://jmorano.moretrix.com/2022/03/logging-in-iptables-with-nflog-and-ulogd2/</link>
					<comments>https://jmorano.moretrix.com/2022/03/logging-in-iptables-with-nflog-and-ulogd2/#comments</comments>
		
		<dc:creator><![CDATA[Johnny Morano]]></dc:creator>
		<pubDate>Thu, 31 Mar 2022 08:00:00 +0000</pubDate>
				<category><![CDATA[Blog]]></category>
		<category><![CDATA[IPTables]]></category>
		<category><![CDATA[Linux]]></category>
		<category><![CDATA[Logging]]></category>
		<category><![CDATA[nflog]]></category>
		<category><![CDATA[SysAdmin]]></category>
		<category><![CDATA[ulogd2]]></category>
		<guid isPermaLink="false">https://jmorano.moretrix.com/?p=1308</guid>

					<description><![CDATA[Logging with IPTables requires the use of an extra IPTables extension called NFLOG (https://manpages.debian.org/experimental/iptables/iptables-extensions.8.en.html#NFLOG) and a separate daemon&#8230;]]></description>
										<content:encoded><![CDATA[
<p>Logging with IPTables requires the use of an extra IPTables extension called <code>NFLOG</code> (<a rel="noreferrer noopener" href="https://manpages.debian.org/experimental/iptables/iptables-extensions.8.en.html#NFLOG" target="_blank">https://manpages.debian.org/experimental/iptables/iptables-extensions.8.en.html#NFLOG</a>) and a separate daemon process, called <code>ulogd2</code> (<a rel="noreferrer noopener" href="https://www.netfilter.org/projects/ulogd/index.html" target="_blank">https://www.netfilter.org/projects/ulogd/index.html</a>). Ulogd2 reads out the packets sent to the above mentioned extension and stores them in local files or databases.</p>



<p>First, install the <code>ulogd2</code> package (example is based on Debian/ Ubuntu):</p>



<pre class="EnlighterJSRAW" data-enlighter-language="shell" data-enlighter-theme="monokai" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">apt install ulogd2
</pre>



<p>Example: log and drop packets which have an invalid state</p>



<pre class="EnlighterJSRAW" data-enlighter-language="shell" data-enlighter-theme="monokai" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group=""># Log and drop all invalid packets                                                                                                                                                                                         
iptables -A INPUT -m conntrack --ctstate INVALID -j NFLOG --nflog-group 123 --nflog-prefix "packet with invalid state"
iptables -A INPUT -m conntrack --ctstate INVALID -j DROP
</pre>



<p>To log all those packets to a file in JSON format, <code>ulogd2</code> requires the following configuration at <code>/etc/ulogd.conf</code></p>



<pre class="EnlighterJSRAW" data-enlighter-language="ini" data-enlighter-theme="monokai" data-enlighter-highlight="" data-enlighter-linenumbers="true" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">[global]                                                                                                                                                                                                           
logfile="syslog"
loglevel=3                                                                                                                                                                                                                   
plugin="/usr/lib/x86_64-linux-gnu/ulogd/ulogd_inppkt_NFLOG.so"
plugin="/usr/lib/x86_64-linux-gnu/ulogd/ulogd_filter_IFINDEX.so"
plugin="/usr/lib/x86_64-linux-gnu/ulogd/ulogd_filter_IP2STR.so"
plugin="/usr/lib/x86_64-linux-gnu/ulogd/ulogd_filter_IP2BIN.so"
plugin="/usr/lib/x86_64-linux-gnu/ulogd/ulogd_filter_PRINTPKT.so"
plugin="/usr/lib/x86_64-linux-gnu/ulogd/ulogd_filter_HWHDR.so"
plugin="/usr/lib/x86_64-linux-gnu/ulogd/ulogd_raw2packet_BASE.so"
plugin="/usr/lib/x86_64-linux-gnu/ulogd/ulogd_output_JSON.so"

stack=log1:NFLOG,base1:BASE,ifi1:IFINDEX,ip2str1:IP2STR,mac2str1:HWHDR,json1:JSON

[log1]
group=123

[json1]
sync=1
file="/var/log/ulog/netfilter_log.json"</pre>



<p>After creating the configuration file, ensure that <code>ulogd2</code> is restarted and that the directory <code>/var/log/ulog</code> exists</p>



<pre class="EnlighterJSRAW" data-enlighter-language="shell" data-enlighter-theme="monokai" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">mkdir /var/log/ulog
chown ulog /var/log/ulog
systemctl restart ulogd2.service</pre>



<p>Once the above created rule matches, a JSON log line will be written to disk:</p>



<pre class="EnlighterJSRAW" data-enlighter-language="json" data-enlighter-theme="monokai" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">tail -1 /var/log/ulog/netfilter_log.json | jq
{
  "timestamp": "2022-03-30T14:46:20.527282+0200",
  "dvc": "Netfilter",
  "raw.pktlen": 52,
  "raw.pktcount": 1,
  "oob.prefix": "packet with invalid state",
  "oob.time.sec": 1648644380,
  "oob.time.usec": 527282,
  "oob.mark": 0,
  "oob.ifindex_in": 2,
  "oob.hook": 1,
  "raw.mac_len": 14,
  "oob.family": 2,
  "oob.protocol": 2048,
  "raw.label": 0,
  "raw.type": 1,
  "raw.mac.addrlen": 6,
  "ip.protocol": 6,
  "ip.tos": 0,
  "ip.ttl": 116,
  "ip.totlen": 52,
  "ip.ihl": 5,
  "ip.csum": 41779,
  "ip.id": 16049,
  "ip.fragoff": 16384,
  "src_port": 58662,
  "dest_port": 445,
  "tcp.seq": 3872158206,
  "tcp.ackseq": 0,
  "tcp.window": 8192,
  "tcp.offset": 0,
  "tcp.reserved": 0,
  "tcp.urg": 0,
  "tcp.ack": 0,
  "tcp.psh": 0,
  "tcp.rst": 0,
  "tcp.syn": 1,
  "tcp.fin": 0,
  "tcp.res1": 0,
  "tcp.res2": 0,
  "tcp.csum": 60039,
  "oob.in": "eth0",
  "oob.out": "",
  "src_ip": "181.122.165.177",
  "dest_ip": "1.1.1.1",
  "mac.saddr.str": "94:f7:ad:4f:81:fc",
  "mac.daddr.str": "aa:aa:aa:aa:aa:aa",
  "mac.str": "aa:aa:aa:aa:aa:aa:94:f7:ad:4f:81:fc:08:00"
}</pre>
]]></content:encoded>
					
					<wfw:commentRss>https://jmorano.moretrix.com/2022/03/logging-in-iptables-with-nflog-and-ulogd2/feed/</wfw:commentRss>
			<slash:comments>1</slash:comments>
		
		
			</item>
	</channel>
</rss>
