Write failed login attempts on the management interface to the syslog to allow fail2ban to ban repeat offenders
This commit is contained in:
parent
7d4d9915ec
commit
864bd988d8
|
@ -28,7 +28,7 @@ maxretry = 20
|
||||||
enabled = true
|
enabled = true
|
||||||
filter = miab-management-daemon
|
filter = miab-management-daemon
|
||||||
port = http,https
|
port = http,https
|
||||||
logpath = /var/log/mailinabox.log
|
logpath = /var/log/syslog
|
||||||
maxretry = 20
|
maxretry = 20
|
||||||
findtime = 30
|
findtime = 30
|
||||||
|
|
||||||
|
|
|
@ -8,5 +8,5 @@ before = common.conf
|
||||||
|
|
||||||
_daemon = mailinabox
|
_daemon = mailinabox
|
||||||
|
|
||||||
failregex = Failed login from ip <HOST>
|
failregex = MIAB: Failed login attempt from ip <HOST> - timestamp .*
|
||||||
ignoreregex =
|
ignoreregex =
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
#!/usr/bin/python3
|
#!/usr/bin/python3
|
||||||
|
|
||||||
import os, os.path, re, json, logging, logging.handlers
|
import os, os.path, re, json, time
|
||||||
|
|
||||||
from functools import wraps
|
from functools import wraps
|
||||||
|
|
||||||
|
@ -32,19 +32,6 @@ with open(os.path.join(os.path.dirname(me), "csr_country_codes.tsv")) as f:
|
||||||
|
|
||||||
app = Flask(__name__, template_folder=os.path.abspath(os.path.join(os.path.dirname(me), "templates")))
|
app = Flask(__name__, template_folder=os.path.abspath(os.path.join(os.path.dirname(me), "templates")))
|
||||||
|
|
||||||
# Initialize the logger
|
|
||||||
#
|
|
||||||
# The logger wil automatically rotate the log if it gets to big, it will keep 3 old log files
|
|
||||||
# The log will contain timestap-level-message
|
|
||||||
logger = logging.getLogger('mailinabox')
|
|
||||||
fh = logging.handlers.RotatingFileHandler("/var/log/mailinabox.log", maxBytes=10240, backupCount=3)
|
|
||||||
fh.setFormatter(logging.Formatter('%(asctime)s %(levelname)-8s %(message)s'))
|
|
||||||
logger.addHandler(fh)
|
|
||||||
logger.setLevel(logging.INFO)
|
|
||||||
|
|
||||||
# Log a line that the daemon was started
|
|
||||||
logger.info("Management daemon started")
|
|
||||||
|
|
||||||
# Decorator to protect views that require a user with 'admin' privileges.
|
# Decorator to protect views that require a user with 'admin' privileges.
|
||||||
def authorized_personnel_only(viewfunc):
|
def authorized_personnel_only(viewfunc):
|
||||||
@wraps(viewfunc)
|
@wraps(viewfunc)
|
||||||
|
@ -524,7 +511,19 @@ def munin(filename=""):
|
||||||
return send_from_directory("/var/cache/munin/www", filename)
|
return send_from_directory("/var/cache/munin/www", filename)
|
||||||
|
|
||||||
def log_failed_login(request):
|
def log_failed_login(request):
|
||||||
logger.warning("Failed login from ip %s" % (request.headers.getlist("X-Forwarded-For")[0]))
|
# We need to figure out the ip to list in the message, all our calls are routed
|
||||||
|
# through nginx who will put the original ip in X-Forwarded-For.
|
||||||
|
# During setup we call the management interface directly to determine the user
|
||||||
|
# status. So we can't always use X-Forwarded-For because during setup that header
|
||||||
|
# will not be present.
|
||||||
|
if request.headers.getlist("X-Forwarded-For"):
|
||||||
|
ip = request.headers.getlist("X-Forwarded-For")[0]
|
||||||
|
else:
|
||||||
|
ip = request.remote_addr
|
||||||
|
|
||||||
|
# We need to add a timestamp to the log message, otherwise /dev/log will eat the "duplicate"
|
||||||
|
# message.
|
||||||
|
app.logger.warning( "MIAB: Failed login attempt from ip %s - timestamp %s" % (ip, time.time()))
|
||||||
|
|
||||||
# APP
|
# APP
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue