# Syslog-ng and my perl script [solved]

## psy_ill

Previously, I used metalog to run a small script every time someone tried to guess a username/password pair for my ssh server.

After having experienced the not so funny side of metalog, the part where it due to some race condition locks up and effectively stops every attempt to log in, I decided to switch to syslog-ng.

I configured syslog-ng to run my script and I modified the script to stay reading from stdin no matter what happened.

The relevant parts of /etc/syslog-ng/syslog-ng.conf:

```

source src { unix-stream("/dev/log"); internal(); pipe("/proc/kmsg"); };

filter sshd_scan { program("sshd") and match("for invalid user"); };

destination messages { file("/var/log/messages"); };

destination blacklist { program("/usr/local/bin/sshd-blacklist.pl"); };

log { source(src); filter(sshd_scan); destination(messages); };

log { source(src); filter(sshd_scan); destination(blacklist); };

```

My little script:

```

#!/usr/bin/perl

# script to blacklist IP addresses as soon as they

# try to abuse our ssh daemon; called from syslog-ng

$iptables = "/sbin/iptables";

$blockchain = "blocked-addresses";

$blocktarget = "DROP";

open( OUTFILE, ">/var/log/test" );

while ( <> )

{

    print OUTFILE;

    if ( /from\ (\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3})/ )

    {

        print OUTFILE $1;

        #system( "$iptables -A $blockchain -s $1 -j $blocktarget" );

    }

}

```

Note that the real blocking has been commented out in the script for testing purposes.

The funny thing is this; when I run the following:

```

# echo "asdf from 127.0.0.1 port ads" | /usr/local/bin/sshd-blacklist.pl 

# cat /var/log/test 

asdf from 127.0.0.1 port ads

127.0.0.1

```

I get the expected behaviour, but when I try to log in with ssh to my own server with a faulty name, I get the expected output in my log file /var/log/messages, but nothing in /var/log/test, that is, nothing ever gets printed to my script from syslog-ng!

Am I missing something crucial here?Last edited by psy_ill on Wed Jan 04, 2006 2:34 pm; edited 1 time in total

----------

## magic919

Is your script actually running?  And if so, does it keep running?  You might want to watch that whilst you test, in order to debug.

----------

## psy_ill

The script is running, both before and after I tried to log in to sshd with a faulty name.

```

$ ps afx

 7359 ?        Ss     0:00 /usr/sbin/syslog-ng

 7360 ?        Ss     0:00  \_ /usr/bin/perl /usr/local/bin/sshd-blacklist.pl

```

and

```

$ ps afx

 7359 ?        Ss     0:00 /usr/sbin/syslog-ng

 7360 ?        Ss     0:00  \_ /usr/bin/perl /usr/local/bin/sshd-blacklist.pl

```

Since the PID stays the same, no new instance has been started.

----------

## magic919

Have you tested this with a blacklist log file to make sure this filter is matching?

----------

## psy_ill

Yes. See my first post for details.

----------

## magic919

I can't see that bit.

----------

## psy_ill

This part:

 *Quote:*   

> 
> 
> log { source(src); filter(sshd_scan); destination(messages); };
> 
> 

 

It filters the source through the filter and outputs the result to /var/log/messages.

That is the same filter as the one used to sort out blacklistings.

It works.

----------

## psy_ill

I did one more thing to my script to ensure it wasn't buffering the output:

```

#!/usr/bin/perl

# script to blacklist IP addresses as soon as they

# try to abuse our ssh daemon; called from syslog-ng

$iptables = "/sbin/iptables";

$blockchain = "blocked-addresses";

$blocktarget = "DROP";

# disable buffering

$| = 1;

open( OUTFILE, ">/var/log/test" );

while ( <> )

{

   print OUTFILE;

   

   if ( /from\ (\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3})/ )

   {

      print OUTFILE $1;

      #system( "$iptables -A $blockchain -s $1 -j $blocktarget" );

   }

}

```

Still nothing in /var/log/test.

----------

## psy_ill

Ok, the last script did not prevent buffering. This one does:

```

#!/usr/bin/perl

# script to blacklist IP addresses as soon as they

# try to abuse our ssh daemon; called from syslog-ng

$iptables = "/sbin/iptables";

$blockchain = "blocked-addresses";

$blocktarget = "DROP";

open( OUTFILE, ">/var/log/test" );

# disable buffering

$old_fh = select( OUTFILE );

$| = 1;

select( $old_fh );

while ( <> )

{

   print OUTFILE;

   

   if ( /from\ (\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3})/ )

   {

      print OUTFILE $1;

      #system( "$iptables -A $blockchain -s $1 -j $blocktarget" );

   }

}

```

And now I get the wanted response in /var/log/test:

```

# cat /var/log/test

<38>Jan  4 16:35:48 xxx sshd[9728]: Failed none for invalid user xxx from 127.0.0.1 port xxx

127.0.0.1<38>Jan  4 16:35:51 xxx sshd[9728]: Failed keyboard-interactive/pam for invalid user xxx from 127.0.0.1 port xxx

127.0.0.1<38>Jan  4 16:35:55 xxx sshd[9728]: Failed keyboard-interactive/pam for invalid user xxx from 127.0.0.1 port xxx

127.0.0.1

```

So the good thing is, my script works and will continue to serve my firewall needs well.

The bad thing is that I am still a Perl grasshopper...  :Razz: 

----------

## magic919

Glad you got it sorted.

You can stop trying to hack your own machine now  :Smile: 

T

----------

