November 26, 2008

Pipe your log through a socket

The idea behind this hack is to log a syslog event, send to a fifo extension pipe, and through the use of socket client, send it to a server listening on a specific port.

I decided to write my “log notification” server in C#, actually it was destined for a Windows machine, so I though “why not” :)

So here it goes, in C#

[sourcecode language=‘c#’]

using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Net.Sockets; using System.Net; using System.Threading;

namespace ServerCli { class Program { static void Main(string[] args) { Thread myThread = new Thread(new ThreadStart(socketInit)); myThread.Start(); }

static void socketInit() { IPAddress ip = IPAddress.Parse(“192.168.2.107”); TcpListener ListInit = new TcpListener(ip, 8085); ListInit.Start(); Console.WriteLine(“local End point is :” ListInit.LocalEndpoint); while (Thread.CurrentThread.IsAlive) { try { Socket s = myList.AcceptSocket(); byte[] b = new byte[200]; int k = s.Receive(b); String data = “”; for (int i = 0; i < k; i++) data += Convert.ToChar(b[i]); Console.WriteLine(data); s.Close(); } catch (Exception e) { Console.WriteLine(“Error….. ” + e.StackTrace); } } ListInit.Stop(); } } }

[/sourcecode]

Ok so, this could really be improved, but you get the picture… :p

Now we need to edit syslog.conf to set our event log to pipe to our fifo extension (which we still need to create)

So… mkfifo /var/log/mySecureLog

vi /etc/syslog.conf

and add

youreventLog. |/var/log/mySecureLog

In my case, i used authpriv.warning … so that I get a notification whenever a fail login takes place on the server.

Save your file, restart syslog and now, we need to write our client, which will “cat” the fifo extension and send it to our socket connection.

I used perl here…

[sourcecode language=‘php’]

#!/usr/bin/perl -w use strict; use IO::Socket;

my $uname = uname -n;

open(LOGFILE, “cat /var/log/mySecureLog |”) || die “oups: $!“; while (my $line =

) { my $conn = IO::Socket::INET->new( Proto => “tcp”, PeerAddr => “192.168.2.107”, PeerPort => “8085”, ) or die “cannot connect”;

$conn->send($line); }

[/sourcecode]

Yes I know! pretty basic script, but you still get the picture ;-)

and that’s it… so what? lanch the server, launch the perl script (client)… try an ssh connection to the server with a false username/password and look :)

Any further mods are welcome! feel free to post back with your own tweaks! As I said earlier! this is just to give the idea for further possibilities.