- One step forward to 0.7.0

git-svn-id: https://fail2ban.svn.sourceforge.net/svnroot/fail2ban/trunk@250 a942ae1a-1317-0410-a47c-b1dcaea8d605
0.x
Cyril Jaquier 2006-07-08 16:51:14 +00:00
parent ea1948eff4
commit 12c222bd1c
21 changed files with 550 additions and 210 deletions

View File

@ -4,9 +4,20 @@
|_| \__,_|_|_/___|_.__/\__,_|_||_| |_| \__,_|_|_/___|_.__/\__,_|_||_|
============================================================= =============================================================
Fail2Ban (version 0.6.1) 2006/03/16 Fail2Ban (version 0.7.0) 2006/07/??
============================================================= =============================================================
ver. 0.7.0 (2006/07/??) - alpha
----------
- Almost a complete rewrite :) Fail2ban design is really
better (IMHO). There is a lot of new features
- Client/Server architecture
- Multithreading. Each jail has its own threads: one for the
log reading and another for the actions
- Execute several actions
- Split configuration files. They are more readable and easy
to use
ver. 0.6.1 (2006/03/16) - stable ver. 0.6.1 (2006/03/16) - stable
---------- ----------
- Added permanent banning. Set banTime to a negative value to - Added permanent banning. Set banTime to a negative value to

View File

@ -1,29 +1,52 @@
README README
CHANGELOG CHANGELOG
TODO TODO
setup.cfg fail2ban-client
fail2ban-server
fail2ban-testcases
client/__init__.py
client/actionreader.py
client/configreader.py
client/configurator.py
client/csocket.py
client/fail2banreader.py
client/filterreader.py
client/jailreader.py
client/jailsreader.py
server/__init__.py
server/action.py
server/actions.py
server/banmanager.py
server/banticket.py
server/faildata.py
server/failmanager.py
server/failticket.py
server/filter.py
server/jail.py
server/jailthread.py
server/server.py
server/ssocket.py
server/ticket.py
server/transmitter.py
setup.py setup.py
version.py testcases/__init__.py
fail2ban testcases/banmanagertestcase.py
fail2ban.py testcases/failmanagertestcase.py
firewall/__init__.py testcases/filtertestcase.py
firewall/firewall.py testcases/servertestcase.py
logreader/__init__.py
logreader/logreader.py
confreader/__init__.py
confreader/configreader.py
utils/__init__.py utils/__init__.py
utils/dns.py utils/dns.py
utils/process.py
utils/mail.py utils/mail.py
utils/strings.py
utils/pidlock.py utils/pidlock.py
config/fail2ban.conf.iptables utils/process.py
config/fail2ban.conf.shorewall utils/strings.py
config/fail2ban.conf.hostsdeny version.py
config/gentoo-initd config/fail2ban.conf
config/gentoo-confd config/fail2ban.local
config/redhat-initd config/jail.conf
config/debian-initd config/action.d/dummy.conf
config/action.d/iptables.conf
config/filter.d/apache-auth.conf
config/filter.d/sshd.conf
man/fail2ban.8 man/fail2ban.8
man/fail2ban.conf.5 man/fail2ban.conf.5

2
TODO
View File

@ -1,2 +1,2 @@
- Don't close socket after a send - Don't close socket after a send
- Multiple actions !!! - Refactoring in server.py, actions.py, filter.py

View File

@ -53,8 +53,7 @@ class ActionReader(ConfigReader):
ConfigReader.read(self, "action.d/" + self.file) ConfigReader.read(self, "action.d/" + self.file)
def getOptions(self, pOpts): def getOptions(self, pOpts):
opts = [["string", "bantime", "600"], opts = [["string", "actionstart", ""],
["string", "actionstart", ""],
["string", "actionstop", ""], ["string", "actionstop", ""],
["string", "actioncheck", ""], ["string", "actioncheck", ""],
["string", "actionban", ""], ["string", "actionban", ""],
@ -62,19 +61,19 @@ class ActionReader(ConfigReader):
self.opts = ConfigReader.getOptions(self, "DEFAULT", opts, pOpts) self.opts = ConfigReader.getOptions(self, "DEFAULT", opts, pOpts)
def convert(self): def convert(self):
head = ["set", self.name]
stream = list() stream = list()
stream.append(head + ["addaction", self.file])
for opt in self.opts: for opt in self.opts:
if opt == "bantime": if opt == "actionstart":
stream.append(["set", self.name, "bantime", self.opts[opt]]) stream.append(head + ["actionstart", self.file, self.opts[opt]])
elif opt == "actionstart":
stream.append(["set", self.name, "actionstart", self.opts[opt]])
elif opt == "actionstop": elif opt == "actionstop":
stream.append(["set", self.name, "actionstop", self.opts[opt]]) stream.append(head + ["actionstop", self.file, self.opts[opt]])
elif opt == "actioncheck": elif opt == "actioncheck":
stream.append(["set", self.name, "actioncheck", self.opts[opt]]) stream.append(head + ["actioncheck", self.file, self.opts[opt]])
elif opt == "actionban": elif opt == "actionban":
stream.append(["set", self.name, "actionban", self.opts[opt]]) stream.append(head + ["actionban", self.file, self.opts[opt]])
elif opt == "actionunban": elif opt == "actionunban":
stream.append(["set", self.name, "actionunban", self.opts[opt]]) stream.append(head + ["actionunban", self.file, self.opts[opt]])
return stream return stream

View File

@ -38,7 +38,7 @@ class JailReader(ConfigReader):
ConfigReader.__init__(self) ConfigReader.__init__(self)
self.name = name self.name = name
self.filter = None self.filter = None
self.action = None self.actions = list()
def setName(self, value): def setName(self, value):
self.name = value self.name = value
@ -55,7 +55,7 @@ class JailReader(ConfigReader):
def getOptions(self): def getOptions(self):
opts = [["bool", "enabled", "false"], opts = [["bool", "enabled", "false"],
["int", "maxretry", None], ["int", "maxretry", None],
["int", "bantime", None], ["int", "bantime", 600],
["string", "filter", ""], ["string", "filter", ""],
["string", "action", ""]] ["string", "action", ""]]
self.opts = ConfigReader.getOptions(self, self.name, opts) self.opts = ConfigReader.getOptions(self, self.name, opts)
@ -67,9 +67,11 @@ class JailReader(ConfigReader):
self.filter.getOptions(self.opts) self.filter.getOptions(self.opts)
# Read action # Read action
self.action = ActionReader(self.opts["action"], self.name) for act in self.opts["action"].split():
self.action.read() action = ActionReader(act, self.name)
self.action.getOptions(self.opts) action.read()
action.getOptions(self.opts)
self.actions.append(action)
def convert(self): def convert(self):
stream = [["add", self.name]] stream = [["add", self.name]]
@ -79,6 +81,7 @@ class JailReader(ConfigReader):
elif opt == "bantime": elif opt == "bantime":
stream.append(["set", self.name, "bantime", self.opts[opt]]) stream.append(["set", self.name, "bantime", self.opts[opt]])
stream.extend(self.filter.convert()) stream.extend(self.filter.convert())
stream.extend(self.action.convert()) for action in self.actions:
stream.extend(action.convert())
return stream return stream

View File

@ -1,7 +1,5 @@
[DEFAULT] [DEFAULT]
bantime = 1234
name = temporary name = temporary
# Option: protocol # Option: protocol

50
config/action.d/foo.conf Normal file
View File

@ -0,0 +1,50 @@
[DEFAULT]
name = temporary
# Option: protocol
# Notes.: internally used by config reader for interpolations.
# Values: [ tcp | udp | icmp | all ] Default: tcp
#
protocol = tcp
# Option: fwstart
# Notes.: command executed once at the start of Fail2Ban.
# Values: CMD Default:
#
actionstart = touch /tmp/fail2ban.foo
# Option: fwend
# Notes.: command executed once at the end of Fail2Ban
# Values: CMD Default:
#
actionstop = rm /tmp/fail2ban.foo
# Option: fwcheck
# Notes.: command executed once before each fwban command
# Values: CMD Default:
#
actioncheck =
# Option: fwban
# Notes.: command executed when banning an IP. Take care that the
# command is executed with Fail2Ban user rights.
# Tags: <ip> IP address
# <failures> number of failures
# <failtime> unix timestamp of the last failure
# <bantime> unix timestamp of the ban time
# Values: CMD
# Default: iptables -I INPUT 1 -s <ip> -j DROP
#
actionban = echo "+<ip>" >> /tmp/fail2ban.foo
# Option: fwunban
# Notes.: command executed when unbanning an IP. Take care that the
# command is executed with Fail2Ban user rights.
# Tags: <ip> IP address
# <bantime> unix timestamp of the ban time
# <unbantime> unix timestamp of the unban time
# Values: CMD
# Default: iptables -D INPUT -s <ip> -j DROP
#
actionunban = echo "-<ip>" >> /tmp/fail2ban.foo

View File

@ -1,4 +1,4 @@
[DEFAULT] [DEFAULT]
loglevel = 4 loglevel = 3

View File

@ -1,4 +1 @@
[DEFAULT] [DEFAULT]
test = 4567
prout = fuck you

View File

@ -2,9 +2,9 @@
enabled = true enabled = true
filter = sshd filter = sshd
action = dummy action = dummy foo
maxretry = 2 maxretry = 2
#bantime = 10 bantime = 5
[SSH] [SSH]

View File

@ -32,6 +32,7 @@ import sys, string, os, pickle, re, logging, getopt, time
sys.path.insert(1, "/usr/lib/fail2ban") sys.path.insert(1, "/usr/lib/fail2ban")
# Now we can import our modules # Now we can import our modules
from version import version
from client.csocket import CSocket from client.csocket import CSocket
from client.configurator import Configurator from client.configurator import Configurator
@ -57,7 +58,7 @@ class Fail2banClient:
""" """
print "Usage: "+self.argv[0]+" [OPTIONS] <COMMAND>" print "Usage: "+self.argv[0]+" [OPTIONS] <COMMAND>"
print print
print "Fail2Ban v0.7 reads log file that contains password failure report" print "Fail2Ban v" + version + " reads log file that contains password failure report"
print "and bans the corresponding IP addresses using firewall rules." print "and bans the corresponding IP addresses using firewall rules."
print print
print " -b start in background" print " -b start in background"
@ -126,6 +127,10 @@ class Fail2banClient:
self.startServer(self.conf["background"]) self.startServer(self.conf["background"])
# Configure the server # Configure the server
self.processCmd(self.stream) self.processCmd(self.stream)
elif cmd[0] == "loadconf" and len(cmd) == 1:
self.readConfig()
# Configure the server
self.processCmd(self.stream)
else: else:
try: try:
client = CSocket() client = CSocket()

View File

@ -25,9 +25,15 @@ __date__ = "$Date: 2004/10/10 13:33:40 $"
__copyright__ = "Copyright (c) 2004 Cyril Jaquier" __copyright__ = "Copyright (c) 2004 Cyril Jaquier"
__license__ = "GPL" __license__ = "GPL"
import locale, getopt, logging, sys
# Inserts our own modules path first in the list
# fix for bug #343821
sys.path.insert(1, "/usr/lib/fail2ban")
from version import version
from server.server import Server from server.server import Server
from utils.process import * from utils.process import *
import locale, getopt, logging, sys
# Gets the instance of the logger. # Gets the instance of the logger.
logSys = logging.getLogger("fail2ban") logSys = logging.getLogger("fail2ban")
@ -53,7 +59,7 @@ class Fail2banServer:
""" """
print "Usage: "+self.argv[0]+" [OPTIONS]" print "Usage: "+self.argv[0]+" [OPTIONS]"
print print
print "Fail2Ban v0.7 reads log file that contains password failure report" print "Fail2Ban v" + version + " reads log file that contains password failure report"
print "and bans the corresponding IP addresses using firewall rules." print "and bans the corresponding IP addresses using firewall rules."
print print
print " -b start in background" print " -b start in background"

View File

@ -28,6 +28,11 @@ __license__ = "GPL"
import unittest, logging, sys import unittest, logging, sys
# Inserts our own modules path first in the list
# fix for bug #343821
sys.path.insert(1, "/usr/lib/fail2ban")
from version import version
from testcases import filtertestcase from testcases import filtertestcase
from testcases import servertestcase from testcases import servertestcase
from testcases import failmanagertestcase from testcases import failmanagertestcase
@ -40,7 +45,7 @@ stdout = logging.StreamHandler(sys.stdout)
logSys.addHandler(stdout) logSys.addHandler(stdout)
logSys.setLevel(logging.FATAL) logSys.setLevel(logging.FATAL)
print "Fail2ban test suite. Please wait..." print "Fail2ban " + version + " test suite. Please wait..."
tests = unittest.TestSuite() tests = unittest.TestSuite()

View File

@ -24,13 +24,10 @@ __date__ = "$Date: 2004/10/10 13:33:40 $"
__copyright__ = "Copyright (c) 2004 Cyril Jaquier" __copyright__ = "Copyright (c) 2004 Cyril Jaquier"
__license__ = "GPL" __license__ = "GPL"
from banmanager import BanManager
from failmanager import FailManager, FailManagerEmpty
from jailthread import JailThread
import time, logging, os import time, logging, os
# Gets the instance of the logger. # Gets the instance of the logger.
logSys = logging.getLogger("fail2ban.action") logSys = logging.getLogger("fail2ban.actions.action")
## ##
# Execute commands. # Execute commands.
@ -39,20 +36,10 @@ logSys = logging.getLogger("fail2ban.action")
# action has to be taken. A BanManager take care of the banned IP # action has to be taken. A BanManager take care of the banned IP
# addresses. # addresses.
class Action(JailThread): class Action:
## def __init__(self, name):
# Constructor. self.name = name
#
# Initialize the filter object with default values.
# @param jail the jail object
def __init__(self, jail):
JailThread.__init__(self, jail)
## The jail which contains this action.
self.jail = jail
## The ban manager.
self.banManager = BanManager()
## Command executed in order to initialize the system. ## Command executed in order to initialize the system.
self.actionStart = '' self.actionStart = ''
## Command executed when an IP address gets banned. ## Command executed when an IP address gets banned.
@ -64,7 +51,13 @@ class Action(JailThread):
## Command executed in order to stop the system. ## Command executed in order to stop the system.
self.actionStop = '' self.actionStop = ''
logSys.debug("Created Action") logSys.debug("Created Action")
def setName(self, name):
self.name = name
def getName(self):
return self.name
## ##
# Set the "start" command. # Set the "start" command.
# #
@ -82,6 +75,9 @@ class Action(JailThread):
def getActionStart(self): def getActionStart(self):
return self.actionStart return self.actionStart
def execActionStart(self, aInfo):
return self.executeCmd(self.actionStart, aInfo);
## ##
# Set the "ban" command. # Set the "ban" command.
# #
@ -99,6 +95,9 @@ class Action(JailThread):
def getActionBan(self): def getActionBan(self):
return self.actionBan return self.actionBan
def execActionBan(self, aInfo):
return self.executeCmd(self.actionBan, aInfo);
## ##
# Set the "unban" command. # Set the "unban" command.
# #
@ -116,6 +115,9 @@ class Action(JailThread):
def getActionUnban(self): def getActionUnban(self):
return self.actionUnban return self.actionUnban
def execActionUnban(self, aInfo):
return self.executeCmd(self.actionUnban, aInfo);
## ##
# Set the "check" command. # Set the "check" command.
# #
@ -133,6 +135,9 @@ class Action(JailThread):
def getActionCheck(self): def getActionCheck(self):
return self.actionCheck return self.actionCheck
def execActionCheck(self, aInfo):
return self.executeCmd(self.actionCheck, aInfo);
## ##
# Set the "stop" command. # Set the "stop" command.
# #
@ -150,104 +155,8 @@ class Action(JailThread):
def getActionStop(self): def getActionStop(self):
return self.actionStop return self.actionStop
## def execActionStop(self, aInfo):
# Set the ban time. return self.executeCmd(self.actionStop, aInfo);
#
# @param value the time
def setBanTime(self, value):
self.banManager.setBanTime(value)
logSys.info("Set banTime = %s" % value)
##
# Get the ban time.
#
# @return the time
def getBanTime(self):
return self.banManager.getBanTime()
##
# Main loop.
#
# This function is the main loop of the thread. It checks the Jail
# queue and executes commands when an IP address is banned.
# @return True when the thread exits nicely
def run(self):
self.executeCmd(self.actionStart)
self.setActive(True)
while self.isActive():
if not self.isIdle:
#logSys.debug(self.jail.getName() + ": action")
ret = self.checkBan()
if not ret:
self.checkUnBan()
time.sleep(self.sleepTime)
else:
time.sleep(self.sleepTime)
self.flushBan()
self.executeCmd(self.actionStop)
logSys.debug(self.jail.getName() + ": action terminated")
return True
##
# Check for IP address to ban.
#
# Look in the Jail queue for FailTicket. If a ticket is available,
# it executes the "ban" command and add a ticket to the BanManager.
# @return True if an IP address get banned
def checkBan(self):
logSys.debug("Check for IP address to ban")
ticket = self.jail.getFailTicket()
if ticket != False:
aInfo = dict()
bTicket = BanManager.createBanTicket(ticket)
aInfo["ip"] = bTicket.getIP()
logSys.info("Ban %s" % aInfo["ip"])
self.executeCmd(self.replaceTag(self.actionBan, aInfo))
self.banManager.addBanTicket(bTicket)
return True
return False
##
# Check for IP address to unban.
#
# Unban IP address which are outdated.
def checkUnBan(self):
logSys.debug("Check for IP address to unban")
for ticket in self.banManager.unBanList(time.time()):
aInfo = dict()
aInfo["ip"] = ticket.getIP()
logSys.info("Unban %s" % aInfo["ip"])
self.executeCmd(self.replaceTag(self.actionUnban, aInfo))
##
# Flush the ban list.
#
# Unban all IP address which are still in the banning list.
def flushBan(self):
logSys.debug("Flush ban list")
for ticket in self.banManager.flushBanList():
aInfo = dict()
aInfo["ip"] = ticket.getIP()
logSys.info("Unban %s" % aInfo["ip"])
self.executeCmd(self.replaceTag(self.actionUnban, aInfo))
##
# Get the status of the filter.
#
# Get some informations about the filter state such as the total
# number of failures.
# @return a list with tuple
def status(self):
ret = [("Currently banned", self.banManager.size()),
("Total banned", self.banManager.getBanTotal())]
return ret
@staticmethod @staticmethod
def replaceTag(query, aInfo): def replaceTag(query, aInfo):
@ -261,21 +170,26 @@ class Action(JailThread):
return string return string
@staticmethod @staticmethod
def executeCmd(cmd): def executeCmd(cmd, aInfo = None):
""" Executes an OS command. """ Executes an OS command.
""" """
if cmd == "": if cmd == "":
logSys.debug("Nothing to do") logSys.debug("Nothing to do")
return True return True
logSys.debug(cmd) # Replace tags
retval = os.system(cmd) if not aInfo == None:
realCmd = Action.replaceTag(cmd, aInfo)
else:
realCmd = cmd
logSys.debug(realCmd)
retval = os.system(realCmd)
#if not retval == 0: #if not retval == 0:
# logSys.error("'" + cmd + "' returned " + `retval`) # logSys.error("'" + cmd + "' returned " + `retval`)
# raise Exception("Execution of command '%s' failed" % cmd) # raise Exception("Execution of command '%s' failed" % cmd)
if retval == 0: if retval == 0:
return True return True
else: else:
logSys.error("%s returned %x" % (cmd, retval)) logSys.error("%s returned %x" % (realCmd, retval))
return False return False

183
server/actions.py Normal file
View File

@ -0,0 +1,183 @@
# This file is part of Fail2Ban.
#
# Fail2Ban is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# Fail2Ban is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with Fail2Ban; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
# Author: Cyril Jaquier
#
# $Revision: 1.1 $
__author__ = "Cyril Jaquier"
__version__ = "$Revision: 1.1 $"
__date__ = "$Date: 2004/10/10 13:33:40 $"
__copyright__ = "Copyright (c) 2004 Cyril Jaquier"
__license__ = "GPL"
from banmanager import BanManager
from failmanager import FailManager, FailManagerEmpty
from jailthread import JailThread
from action import Action
import time, logging, os
# Gets the instance of the logger.
logSys = logging.getLogger("fail2ban.actions")
##
# Execute commands.
#
# This class reads the failures from the Jail queue and decide if an
# action has to be taken. A BanManager take care of the banned IP
# addresses.
class Actions(JailThread):
##
# Constructor.
#
# Initialize the filter object with default values.
# @param jail the jail object
def __init__(self, jail):
JailThread.__init__(self, jail)
## The jail which contains this action.
self.jail = jail
self.actions = list()
## The ban manager.
self.banManager = BanManager()
def addAction(self, name):
action = Action(name)
self.actions.append(action)
def delAction(self, name):
for action in self.actions:
if action.getName() == name:
self.actions.remove(action)
break
def getAction(self, name):
for action in self.actions:
if action.getName() == name:
return action
raise KeyError
def getLastAction(self):
action = self.actions.pop()
self.actions.append(action)
return action
##
# Set the ban time.
#
# @param value the time
def setBanTime(self, value):
self.banManager.setBanTime(value)
logSys.info("Set banTime = %s" % value)
##
# Get the ban time.
#
# @return the time
def getBanTime(self):
return self.banManager.getBanTime()
##
# Main loop.
#
# This function is the main loop of the thread. It checks the Jail
# queue and executes commands when an IP address is banned.
# @return True when the thread exits nicely
def run(self):
for action in self.actions:
action.execActionStart(None)
self.setActive(True)
while self.isActive():
if not self.isIdle:
#logSys.debug(self.jail.getName() + ": action")
ret = self.checkBan()
if not ret:
self.checkUnBan()
time.sleep(self.sleepTime)
else:
time.sleep(self.sleepTime)
self.flushBan()
for action in self.actions:
action.execActionStop(None)
logSys.debug(self.jail.getName() + ": action terminated")
return True
##
# Check for IP address to ban.
#
# Look in the Jail queue for FailTicket. If a ticket is available,
# it executes the "ban" command and add a ticket to the BanManager.
# @return True if an IP address get banned
def checkBan(self):
logSys.debug("Check for IP address to ban")
ticket = self.jail.getFailTicket()
if ticket != False:
aInfo = dict()
bTicket = BanManager.createBanTicket(ticket)
aInfo["ip"] = bTicket.getIP()
logSys.info("Ban %s" % aInfo["ip"])
for action in self.actions:
action.execActionBan(aInfo)
self.banManager.addBanTicket(bTicket)
return True
return False
##
# Check for IP address to unban.
#
# Unban IP address which are outdated.
def checkUnBan(self):
logSys.debug("Check for IP address to unban")
for ticket in self.banManager.unBanList(time.time()):
aInfo = dict()
aInfo["ip"] = ticket.getIP()
logSys.info("Unban %s" % aInfo["ip"])
for action in self.actions:
action.execActionUnban(aInfo)
##
# Flush the ban list.
#
# Unban all IP address which are still in the banning list.
def flushBan(self):
logSys.debug("Flush ban list")
for ticket in self.banManager.flushBanList():
aInfo = dict()
aInfo["ip"] = ticket.getIP()
logSys.info("Unban %s" % aInfo["ip"])
for action in self.actions:
action.execActionUnban(aInfo)
##
# Get the status of the filter.
#
# Get some informations about the filter state such as the total
# number of failures.
# @return a list with tuple
def status(self):
ret = [("Currently banned", self.banManager.size()),
("Total banned", self.banManager.getBanTotal())]
return ret

View File

@ -24,7 +24,7 @@ __date__ = "$Date: 2004/10/10 13:33:40 $"
__copyright__ = "Copyright (c) 2004 Cyril Jaquier" __copyright__ = "Copyright (c) 2004 Cyril Jaquier"
__license__ = "GPL" __license__ = "GPL"
from action import Action from actions import Actions
from filter import Filter from filter import Filter
import Queue import Queue
@ -35,7 +35,7 @@ class Jail:
self.name = name self.name = name
self.queue = Queue.Queue() self.queue = Queue.Queue()
self.filter = Filter(self) self.filter = Filter(self)
self.action = Action(self) self.action = Actions(self)
def setName(self, name): def setName(self, name):
self.name = name self.name = name

View File

@ -162,7 +162,25 @@ class Server:
else: else:
raise ServerUnknownJail(name) raise ServerUnknownJail(name)
# Action # Action
def addAction(self, name, value):
if self.jails.has_key(name):
self.jails[name].getAction().addAction(value)
else:
raise ServerUnknownJail(name)
def getLastAction(self, name):
if self.jails.has_key(name):
return self.jails[name].getAction().getLastAction()
else:
raise ServerUnknownJail(name)
def delAction(self, name, value):
if self.jails.has_key(name):
self.jails[name].getAction().delAction(value)
else:
raise ServerUnknownJail(name)
def setBanTime(self, name, value): def setBanTime(self, name, value):
if self.jails.has_key(name): if self.jails.has_key(name):
self.jails[name].getAction().setBanTime(value) self.jails[name].getAction().setBanTime(value)
@ -175,63 +193,63 @@ class Server:
else: else:
raise ServerUnknownJail(name) raise ServerUnknownJail(name)
def setActionStart(self, name, value): def setActionStart(self, name, action, value):
if self.jails.has_key(name): if self.jails.has_key(name):
self.jails[name].getAction().setActionStart(value) self.jails[name].getAction().getAction(action).setActionStart(value)
else: else:
raise ServerUnknownJail(name) raise ServerUnknownJail(name)
def getActionStart(self, name): def getActionStart(self, name, action):
if self.jails.has_key(name): if self.jails.has_key(name):
return self.jails[name].getAction().getActionStart() return self.jails[name].getAction().getAction(action).getActionStart()
else: else:
raise ServerUnknownJail(name) raise ServerUnknownJail(name)
def setActionStop(self, name, value): def setActionStop(self, name, action, value):
if self.jails.has_key(name): if self.jails.has_key(name):
self.jails[name].getAction().setActionStop(value) self.jails[name].getAction().getAction(action).setActionStop(value)
else: else:
raise ServerUnknownJail(name) raise ServerUnknownJail(name)
def getActionStop(self, name): def getActionStop(self, name, action):
if self.jails.has_key(name): if self.jails.has_key(name):
return self.jails[name].getAction().getActionStop() return self.jails[name].getAction().getAction(action).getActionStop()
else: else:
raise ServerUnknownJail(name) raise ServerUnknownJail(name)
def setActionCheck(self, name, value): def setActionCheck(self, name, action, value):
if self.jails.has_key(name): if self.jails.has_key(name):
self.jails[name].getAction().setActionCheck(value) self.jails[name].getAction().getAction(action).setActionCheck(value)
else: else:
raise ServerUnknownJail(name) raise ServerUnknownJail(name)
def getActionCheck(self, name): def getActionCheck(self, name, action):
if self.jails.has_key(name): if self.jails.has_key(name):
return self.jails[name].getAction().getActionCheck() return self.jails[name].getAction().getAction(action).getActionCheck()
else: else:
raise ServerUnknownJail(name) raise ServerUnknownJail(name)
def setActionBan(self, name, value): def setActionBan(self, name, action, value):
if self.jails.has_key(name): if self.jails.has_key(name):
self.jails[name].getAction().setActionBan(value) self.jails[name].getAction().getAction(action).setActionBan(value)
else: else:
raise ServerUnknownJail(name) raise ServerUnknownJail(name)
def getActionBan(self, name): def getActionBan(self, name, action):
if self.jails.has_key(name): if self.jails.has_key(name):
return self.jails[name].getAction().getActionBan() return self.jails[name].getAction().getAction(action).getActionBan()
else: else:
raise ServerUnknownJail(name) raise ServerUnknownJail(name)
def setActionUnban(self, name, value): def setActionUnban(self, name, action, value):
if self.jails.has_key(name): if self.jails.has_key(name):
self.jails[name].getAction().setActionUnban(value) self.jails[name].getAction().getAction(action).setActionUnban(value)
else: else:
raise ServerUnknownJail(name) raise ServerUnknownJail(name)
def getActionUnban(self, name): def getActionUnban(self, name, action):
if self.jails.has_key(name): if self.jails.has_key(name):
return self.jails[name].getAction().getActionUnban() return self.jails[name].getAction().getAction(action).getActionUnban()
else: else:
raise ServerUnknownJail(name) raise ServerUnknownJail(name)

View File

@ -104,7 +104,7 @@ class Transmitter:
self.server.setLogLevel(value) self.server.setLogLevel(value)
return self.server.getLogLevel() return self.server.getLogLevel()
# Jail # Jail
if action[1] == "idle": elif action[1] == "idle":
if action[2] == "on": if action[2] == "on":
self.server.setIdleJail(name, True) self.server.setIdleJail(name, True)
elif action[2] == "off": elif action[2] == "off":
@ -140,26 +140,38 @@ class Transmitter:
value = action[2] value = action[2]
self.server.setBanTime(name, int(value)) self.server.setBanTime(name, int(value))
return self.server.getBanTime(name) return self.server.getBanTime(name)
elif action[1] == "addaction":
value = action[2]
self.server.addAction(name, value)
return self.server.getLastAction(name).getName()
elif action[1] == "delaction":
self.server.delAction(name, value)
return None
elif action[1] == "actionstart": elif action[1] == "actionstart":
value = action[2] act = action[2]
self.server.setActionStart(name, value) value = action[3]
return self.server.getActionStart(name) self.server.setActionStart(name, act, value)
return self.server.getActionStart(name, act)
elif action[1] == "actionstop": elif action[1] == "actionstop":
value = action[2] act = action[2]
self.server.setActionStop(name, value) value = action[3]
return self.server.getActionStop(name) self.server.setActionStop(name, act, value)
return self.server.getActionStop(name, act)
elif action[1] == "actioncheck": elif action[1] == "actioncheck":
value = action[2] act = action[2]
self.server.setActionCheck(name, value) value = action[3]
return self.server.getActionCheck(name) self.server.setActionCheck(name, act, value)
return self.server.getActionCheck(name, act)
elif action[1] == "actionban": elif action[1] == "actionban":
value = action[2] act = action[2]
self.server.setActionBan(name, value) value = action[3]
return self.server.getActionBan(name) self.server.setActionBan(name, act, value)
return self.server.getActionBan(name, act)
elif action[1] == "actionunban": elif action[1] == "actionunban":
value = action[2] act = action[2]
self.server.setActionUnban(name, value) value = action[3]
return self.server.getActionUnban(name) self.server.setActionUnban(name, act, value)
return self.server.getActionUnban(name, act)
raise Exception("Invalid command (no set action)") raise Exception("Invalid command (no set action)")
def actionGet(self, action): def actionGet(self, action):

5
setup.cfg Normal file
View File

@ -0,0 +1,5 @@
[install]
install-purelib=/usr/lib/fail2ban
[sdist]
formats=bztar

84
setup.py Executable file
View File

@ -0,0 +1,84 @@
#!/usr/bin/env python
# This file is part of Fail2Ban.
#
# Fail2Ban is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# Fail2Ban is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with Fail2Ban; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
# Author: Cyril Jaquier
#
# $Revision: 1.6 $
__author__ = "Cyril Jaquier"
__version__ = "$Revision: 1.6 $"
__date__ = "$Date: 2006/01/22 11:08:42 $"
__copyright__ = "Copyright (c) 2004 Cyril Jaquier"
__license__ = "GPL"
from distutils.core import setup
from version import version
from os.path import isfile, join
from sys import exit, argv
longdesc = '''
Fail2Ban scans log files like /var/log/pwdfail or
/var/log/apache/error_log and bans IP that makes
too many password failures. It updates firewall rules
to reject the IP address or executes user defined
commands.'''
setup(
name = "fail2ban",
version = version,
description = "Ban IPs that make too many password failure",
long_description = longdesc,
author = "Cyril Jaquier",
author_email = "lostcontrol@users.sourceforge.net",
url = "http://fail2ban.sourceforge.net",
license = "GPL",
platforms = "Posix",
scripts = ['fail2ban-client', 'fail2ban-server',
'fail2ban-testcases'],
py_modules = ['version'],
packages = ['client', 'server', 'testcases', 'utils']
)
# Do some checks after installation
# Search for obsolete files.
obsoleteFiles = []
elements = {"/etc/": ["fail2ban.conf"],
"/usr/bin/": ["fail2ban.py"],
"/usr/lib/fail2ban/firewall/": ["iptables.py", "ipfwadm.py",
"ipfw.py"]}
for dir in elements:
for f in elements[dir]:
path = join(dir, f)
if isfile(path):
obsoleteFiles.append(path)
if obsoleteFiles:
print
print "Obsolete files from previous Fail2Ban versions were found on " \
"your system."
print "Please delete them:"
print
for f in obsoleteFiles:
print "\t" + f
print
# Update config file
if argv[1] == "install":
print
print "Please do not forget to update your configuration files."
print "Use config/ as an example."
print

27
version.py Normal file
View File

@ -0,0 +1,27 @@
# This file is part of Fail2Ban.
#
# Fail2Ban is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# Fail2Ban is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with Fail2Ban; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
# Author: Cyril Jaquier
#
# $Revision: 1.15.2.1 $
__author__ = "Cyril Jaquier"
__version__ = "$Revision: 1.15.2.1 $"
__date__ = "$Date: 2006/03/19 18:35:21 $"
__copyright__ = "Copyright (c) 2004 Cyril Jaquier"
__license__ = "GPL"
version = "0.7.0-SVN"