Re: RFC: Fam/Python based script for bruteforce blocking

2009-12-26 Thread Brandon Low
On 2009-12-19 (Sat) at 03:38:26 -0900, Mel Flynn wrote:
 Well, my first problem with it is obviously that I now need python, where I 
 don't want python. In fact, my firewalls/gateways only have /bin/sh and 
 /bin/csh as scripting languages. It's one reason I switched from custom 
 sysutils/grok rules to using security/sshguard - it got me rid of perl.

That makes sense -- I'm using it on a general purpose server as opposed
to a dedicated firewall box.

 Secondly, you have matching rules coded in the script. If there would be one 
 reason to prefer this script over sshguard, it would be that I can add attack 
 patterns more easily, in config file with a syntax that's not too obscure.

Interesting thought, I will definitely make the matching rules
configurable and potentially make possible to monitor multiple logfiles
for attack patterns (potentially configurable per-logfile).

 Last but not least, you assume that once an IP is at fault, I want that IP 
 blocked permanently. In practice you end up with an extremely large table 
 that 
 might eventually be too big for a default PF table and recurring scans from 
 the same IP are not that common (you see the IP in a 12-24 hour window, then 
 not again).

You've misread the script.  IPs are expired after a configurable number
of seconds.
 
 Hope this helps.

Thanks kindly for the feedback!

--Brandon
___
freebsd-questions@freebsd.org mailing list
http://lists.freebsd.org/mailman/listinfo/freebsd-questions
To unsubscribe, send any mail to freebsd-questions-unsubscr...@freebsd.org


Re: RFC: Fam/Python based script for bruteforce blocking

2009-12-19 Thread Mel Flynn
On Thursday 17 December 2009 16:34:22 Brandon Low wrote:

 I'd love to hear other people's feedback on this approach of using FAM +
 auth.log to implement this and/or to hear of other superior approaches
 to achieving this result.

Well, my first problem with it is obviously that I now need python, where I 
don't want python. In fact, my firewalls/gateways only have /bin/sh and 
/bin/csh as scripting languages. It's one reason I switched from custom 
sysutils/grok rules to using security/sshguard - it got me rid of perl.
Secondly, you have matching rules coded in the script. If there would be one 
reason to prefer this script over sshguard, it would be that I can add attack 
patterns more easily, in config file with a syntax that's not too obscure.
Last but not least, you assume that once an IP is at fault, I want that IP 
blocked permanently. In practice you end up with an extremely large table that 
might eventually be too big for a default PF table and recurring scans from 
the same IP are not that common (you see the IP in a 12-24 hour window, then 
not again).

Hope this helps.
-- 
Mel
___
freebsd-questions@freebsd.org mailing list
http://lists.freebsd.org/mailman/listinfo/freebsd-questions
To unsubscribe, send any mail to freebsd-questions-unsubscr...@freebsd.org


Re: RFC: Fam/Python based script for bruteforce blocking

2009-12-18 Thread Matthew Seaman

Robert Huff wrote:

Brandon Low writes:


 Not sure why this didn't attach the first time.


The FreeBSD mailing list software is set to scrub all
attachments as a security measure.  To makew material available,
post it in-line, or post a URL.


The attachment eater doesn't actually eat *all* attachments.  Just the
ones with MIME types it thinks are tasty.  You can generally get stuff
through if it's marked as something innocuous like text/plain   


Cheers,

Matthew

--
Dr Matthew J Seaman MA, D.Phil.   7 Priory Courtyard
 Flat 3
PGP: http://www.infracaninophile.co.uk/pgpkey Ramsgate
 Kent, CT11 9PW



signature.asc
Description: OpenPGP digital signature


Re: RFC: Fam/Python based script for bruteforce blocking

2009-12-18 Thread Robert Huff

Matthew Seaman writes:

  The FreeBSD mailing list software is set to scrub all
   attachments as a security measure.  To makew material available,
   post it in-line, or post a URL.
  
  The attachment eater doesn't actually eat *all* attachments.
  Just the ones with MIME types it thinks are tasty.  You can
  generally get stuff through if it's marked as something innocuous
  like text/plain

Point taken.


Robert Huff

___
freebsd-questions@freebsd.org mailing list
http://lists.freebsd.org/mailman/listinfo/freebsd-questions
To unsubscribe, send any mail to freebsd-questions-unsubscr...@freebsd.org


RFC: Fam/Python based script for bruteforce blocking

2009-12-17 Thread Brandon Low
Hi,

I'm pretty new to FreeBSD, but when I saw how neatly it supported
file-backed tables for IP blocking I knew I'd finally want to build a
bruteforce blocking script that I'd long wanted to create on Linux.

This script is loosely based on the perl script for the same purpose
from http://home.earthlink.net/~valiantsoul/pf.html .

My script, in contrast to the above, runs as a daemon and is completely
self contained other than the blacklist file.  Of course it's up to the
user to create the bruteforce table in pf and to do something useful
with it, but once that's done just running the bruteforce.py daemon will
take care of the rest.  I've attached the script and my pf.conf.  The
only other requirements other than python are py-fam and (of course)
a configured fam.

I'd love to hear other people's feedback on this approach of using FAM +
auth.log to implement this and/or to hear of other superior approaches
to achieving this result.

Thanks for reading,

--Brandon
table bruteforce persist file /var/db/blacklist
table safe persist file /var/db/friendlist
block in all
pass in on nfe0 proto tcp from any to any port 22 keep state
pass in on nfe0 proto tcp from any to any port 80 keep state
pass in on nfe0 proto tcp from any to any port 443 keep state
pass in on nfe0 proto tcp from any to any port 25 keep state
pass in on nfe0 proto tcp from any to any port 465 keep state
pass in on nfe0 proto tcp from any to any port 993 keep state
pass in on nfe0 proto udp from any to any port 53
pass in on nfe0 proto tcp from any to any port 53 keep state
pass in on nfe0 proto udp from any to any port 123
pass in on nfe0 proto icmp
block from bruteforce
pass from safe
pass on lo0
pass out all keep state
___
freebsd-questions@freebsd.org mailing list
http://lists.freebsd.org/mailman/listinfo/freebsd-questions
To unsubscribe, send any mail to freebsd-questions-unsubscr...@freebsd.org

Re: RFC: Fam/Python based script for bruteforce blocking

2009-12-17 Thread Brandon Low
Not sure why this didn't attach the first time.

#!/usr/bin/env python
import errno
import logging
import optparse
import os
import re
import select
import signal
import subprocess
import sys
import time
import datetime

import _fam

def getUpdateBlocks(pfctl, expire_seconds, blacklist_filename, table, limit_n):
expire=str(expire_seconds)
blacklist=blacklist_filename
limit=limit_n

baseArgs=(pfctl, '-t', table, '-T')
def callAndLog(*args, **kwargs):
c=subprocess.Popen(baseArgs + args, stderr=subprocess.PIPE,
stdout=kwargs.get('stdout',subprocess.PIPE))
stdout,stderr=c.communicate()
if stdout: logging.info(stdout)
for line in (stderr if stderr else '').split('\n'):
if not line: continue
getattr(logging,'info' if line.find('ALTQ')  0 else 'debug')(line)

reParts=('(.*) erudite sshd\[[0-9]+\]: ',
'(?:', '|'.join(('Invalid user .* from',
'Did not receive identification string from',
'error: PAM: authentication error for root from')), ') ',
'(', '(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}',
'(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)', ')\n?')
r=re.compile(''.join(reParts))
df='%b %d %H:%M:%S'
oneDay=datetime.timedelta(days=1)
def processFile(now, ips, filename):
with open(filename, 'r') as f:
for line in f:
m=r.match(line)
if not m: continue
d=datetime.datetime.strptime(m.group(1),df).replace(now.year)
if d  now: d=d.replace(now.year-1)
if now-d  oneDay: ips[m.group(2)]=ips.get(m.group(2),0) + 1

def updateBlocks(filename):
logging.info(Updating blacklist...)
ips={}
now=datetime.datetime.now()
processFile(now, ips, filename)
logging.debug(Found %s IPs, len(ips))
logging.debug(Adding ips to pf table)
callAndLog('add', *tuple(k for k,v in ips.iteritems() if v = limit))
logging.debug(Expiring ips from pf table)
callAndLog('expire', expire)
logging.debug(Saving table state to file)
with open(blacklist,'w') as blacklistFile:
callAndLog('show', stdout=blacklistFile)
logging.debug(Done)
return updateBlocks

def main():
parser=optparse.OptionParser()
parser.add_option(-d, --debug,
action=store_true, help=Enable debug logging)
parser.add_option(-a, --auth_log,
default=/var/log/auth.log, help=Authentication log filename)
parser.add_option(-b, --blacklist,
default=/var/db/blacklist, help=Blacklist filename)
parser.add_option(-l, --log_file,
default=/var/log/bruteforce.log, help=Log filename)
parser.add_option(-p, --pfctl,
default=/sbin/pfctl, help=pfctl binary)
parser.add_option(-e, --expire, type=int,
default=604800, help=Seconds to hold a grudge)
parser.add_option(-t, --table,
default=bruteforce, help=Name of pf table to work on)
parser.add_option(-i, --limit, type=int,
default=2, help=Number of invalid logins to get blacklisted)

(opts, args)=parser.parse_args()

if args: optparse.error(No non-option arguments expected)

logging.basicConfig(filename=opts.log_file,
level=logging.DEBUG if opts.debug else logging.INFO)

fc=_fam.open()
p=select.poll()
p.register(fc, select.POLLIN|select.POLLPRI)

fr=fc.monitorFile(opts.auth_log, None)

updateBlocks=getUpdateBlocks(
opts.pfctl, opts.expire, opts.blacklist, opts.table, opts.limit)

while True:
p.poll(60)
update=False
while fc.pending():
fe=fc.nextEvent()
if fe.code in (_fam.Exists,_fam.Changed,_fam.Created): update=True
if not fe.filename==opts.auth_log: raise FAM event: wrong file
if update: updateBlocks(fe.filename)

if __name__ == __main__: main()

___
freebsd-questions@freebsd.org mailing list
http://lists.freebsd.org/mailman/listinfo/freebsd-questions
To unsubscribe, send any mail to freebsd-questions-unsubscr...@freebsd.org


Re: RFC: Fam/Python based script for bruteforce blocking

2009-12-17 Thread Robert Huff

Brandon Low writes:

  Not sure why this didn't attach the first time.

The FreeBSD mailing list software is set to scrub all
attachments as a security measure.  To makew material available,
post it in-line, or post a URL.


Robert Huff

___
freebsd-questions@freebsd.org mailing list
http://lists.freebsd.org/mailman/listinfo/freebsd-questions
To unsubscribe, send any mail to freebsd-questions-unsubscr...@freebsd.org