mirror of https://github.com/fail2ban/fail2ban
Merge remote-tracking branch 'remotes/gh-upstream/0.10' into 0.11
commit
32058ed268
|
@ -8,14 +8,27 @@ before = common.conf
|
||||||
[Definition]
|
[Definition]
|
||||||
|
|
||||||
_auth_worker = (?:dovecot: )?auth(?:-worker)?
|
_auth_worker = (?:dovecot: )?auth(?:-worker)?
|
||||||
_daemon = (dovecot(-auth)?|auth)
|
_daemon = (?:dovecot(?:-auth)?|auth)
|
||||||
|
|
||||||
prefregex = ^%(__prefix_line)s(%(_auth_worker)s(?:\([^\)]+\))?: )?(?:%(__pam_auth)s(?:\(dovecot:auth\))?: |(?:pop3|imap)-login: )?(?:Info: )?<F-CONTENT>.+</F-CONTENT>$
|
prefregex = ^%(__prefix_line)s(?:%(_auth_worker)s(?:\([^\)]+\))?: )?(?:%(__pam_auth)s(?:\(dovecot:auth\))?: |(?:pop3|imap)-login: )?(?:Info: )?<F-CONTENT>.+</F-CONTENT>$
|
||||||
|
|
||||||
failregex = ^authentication failure; logname=\S* uid=\S* euid=\S* tty=dovecot ruser=\S* rhost=<HOST>(?:\s+user=\S*)?\s*$
|
failregex = ^authentication failure; logname=\S* uid=\S* euid=\S* tty=dovecot ruser=\S* rhost=<HOST>(?:\s+user=\S*)?\s*$
|
||||||
^(?:Aborted login|Disconnected)(?::(?: [^ \(]+)+)? \((?:auth failed, \d+ attempts( in \d+ secs)?|tried to use (disabled|disallowed) \S+ auth)\):( user=<[^>]*>,)?( method=\S+,)? rip=<HOST>(?:, lip=\S+)?(?:, TLS(?: handshaking(?:: SSL_accept\(\) failed: error:[\dA-F]+:SSL routines:[TLS\d]+_GET_CLIENT_HELLO:unknown protocol)?)?(: Disconnected)?)?(, session=<\S+>)?\s*$
|
^(?:Aborted login|Disconnected)(?::(?: [^ \(]+)+)? \((?:auth failed, \d+ attempts(?: in \d+ secs)?|tried to use (?:disabled|disallowed) \S+ auth)\):(?: user=<[^>]*>,)?(?: method=\S+,)? rip=<HOST>(?:[^>]*(?:, session=<\S+>)?)\s*$
|
||||||
^pam\(\S+,<HOST>\): pam_authenticate\(\) failed: (User not known to the underlying authentication module: \d+ Time\(s\)|Authentication failure \(password mismatch\?\))\s*$
|
^pam\(\S+,<HOST>\): pam_authenticate\(\) failed: (?:User not known to the underlying authentication module: \d+ Time\(s\)|Authentication failure \(password mismatch\?\))\s*$
|
||||||
^[a-z\-]{3,15}\(\S*,<HOST>(?:,\S*)?\): (?:unknown user|invalid credentials)\s*$
|
^[a-z\-]{3,15}\(\S*,<HOST>(?:,\S*)?\): (?:unknown user|invalid credentials)\s*$
|
||||||
|
<mdre-<mode>>
|
||||||
|
|
||||||
|
mdre-aggressive = ^(?:Aborted login|Disconnected)(?::(?: [^ \(]+)+)? \((?:no auth attempts|disconnected before auth was ready,|client didn't finish \S+ auth,)(?: (?:in|waited) \d+ secs)?\):(?: user=<[^>]*>,)?(?: method=\S+,)? rip=<HOST>(?:[^>]*(?:, session=<\S+>)?)\s*$
|
||||||
|
|
||||||
|
mdre-normal =
|
||||||
|
|
||||||
|
# Parameter `mode` - `normal` or `aggressive`.
|
||||||
|
# Aggressive mode can be used to match log-entries like:
|
||||||
|
# 'no auth attempts', 'disconnected before auth was ready', 'client didn't finish SASL auth'.
|
||||||
|
# Note it may produce lots of false positives on misconfigured MTAs.
|
||||||
|
# Ex.:
|
||||||
|
# filter = dovecot[mode=aggressive]
|
||||||
|
mode = normal
|
||||||
|
|
||||||
ignoreregex =
|
ignoreregex =
|
||||||
|
|
||||||
|
@ -27,8 +40,6 @@ datepattern = {^LN-BEG}TAI64N
|
||||||
# DEV Notes:
|
# DEV Notes:
|
||||||
# * the first regex is essentially a copy of pam-generic.conf
|
# * the first regex is essentially a copy of pam-generic.conf
|
||||||
# * Probably doesn't do dovecot sql/ldap backends properly (resolved in edit 21/03/2016)
|
# * Probably doesn't do dovecot sql/ldap backends properly (resolved in edit 21/03/2016)
|
||||||
# * Removed the 'no auth attempts' log lines from the matches because produces
|
|
||||||
# lots of false positives on misconfigured MTAs making regexp unusable
|
|
||||||
#
|
#
|
||||||
# Author: Martin Waschbuesch
|
# Author: Martin Waschbuesch
|
||||||
# Daniel Black (rewrote with begin and end anchors)
|
# Daniel Black (rewrote with begin and end anchors)
|
||||||
|
|
|
@ -81,3 +81,19 @@ Mar 23 06:10:52 auth: Info: ldap(dog,52.37.139.121,): invalid credentials
|
||||||
Jul 26 11:11:21 hostname dovecot: imap-login: Disconnected: Too many invalid commands (tried to use disallowed plaintext auth): user=<test>, rip=192.0.2.1, lip=192.168.1.1, session=<S5dIdTFCDKUWWMbU>
|
Jul 26 11:11:21 hostname dovecot: imap-login: Disconnected: Too many invalid commands (tried to use disallowed plaintext auth): user=<test>, rip=192.0.2.1, lip=192.168.1.1, session=<S5dIdTFCDKUWWMbU>
|
||||||
# failJSON: { "time": "2005-07-26T11:12:19", "match": true , "host": "192.0.2.2" }
|
# failJSON: { "time": "2005-07-26T11:12:19", "match": true , "host": "192.0.2.2" }
|
||||||
Jul 26 11:12:19 hostname dovecot: imap-login: Disconnected: Too many invalid commands (auth failed, 1 attempts in 17 secs): user=<test>, method=PLAIN, rip=192.0.2.2, lip=192.168.1.1, TLS, session=<g3ZKeDECFqlWWMbU>
|
Jul 26 11:12:19 hostname dovecot: imap-login: Disconnected: Too many invalid commands (auth failed, 1 attempts in 17 secs): user=<test>, method=PLAIN, rip=192.0.2.2, lip=192.168.1.1, TLS, session=<g3ZKeDECFqlWWMbU>
|
||||||
|
|
||||||
|
# failJSON: { "time": "2004-08-28T06:38:51", "match": true , "host": "192.0.2.3" }
|
||||||
|
Aug 28 06:38:51 s166-62-100-187 dovecot: imap-login: Disconnected (auth failed, 1 attempts in 9 secs): user=<administrator@example.com>, method=PLAIN, rip=192.0.2.3, lip=192.168.1.2, TLS: Disconnected, TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)
|
||||||
|
|
||||||
|
# ---------------------------------------
|
||||||
|
# Test-cases of aggressive mode:
|
||||||
|
# ---------------------------------------
|
||||||
|
|
||||||
|
# filterOptions: [{"mode": "aggressive"}]
|
||||||
|
|
||||||
|
# failJSON: { "time": "2004-08-29T16:06:58", "match": true , "host": "192.0.2.5" }
|
||||||
|
Aug 29 16:06:58 s166-62-100-187 dovecot: imap-login: Disconnected (disconnected before auth was ready, waited 0 secs): user=<>, rip=192.0.2.5, lip=192.168.1.2, TLS handshaking: SSL_accept() syscall failed: Connection reset by peer
|
||||||
|
# failJSON: { "time": "2004-08-31T16:15:10", "match": true , "host": "192.0.2.6" }
|
||||||
|
Aug 31 16:15:10 s166-62-100-187 dovecot: imap-login: Disconnected (client didn't finish SASL auth, waited 2 secs): user=<>, method=PLAIN, rip=192.0.2.6, lip=192.168.1.2, TLS: SSL_read() syscall failed: Connection reset by peer, TLSv1.2 with cipher DHE-RSA-AES256-GCM-SHA384 (256/256 bits)
|
||||||
|
# failJSON: { "time": "2004-08-31T16:21:53", "match": true , "host": "192.0.2.7" }
|
||||||
|
Aug 31 16:21:53 s166-62-100-187 dovecot: imap-login: Disconnected (no auth attempts in 4 secs): user=<>, rip=192.0.2.7, lip=192.168.1.2, TLS handshaking: SSL_accept() syscall failed: Connection reset by peer
|
||||||
|
|
|
@ -101,6 +101,22 @@ class SetupTest(unittest.TestCase):
|
||||||
"Seems to be running with python distribution %s"
|
"Seems to be running with python distribution %s"
|
||||||
" -- install can be tested only with system distribution %s" % (str(tuple(sys.version_info)), sysVer))
|
" -- install can be tested only with system distribution %s" % (str(tuple(sys.version_info)), sysVer))
|
||||||
|
|
||||||
|
def testSetupInstallDryRun(self):
|
||||||
|
if not self.setup:
|
||||||
|
return # if verbose skip didn't work out
|
||||||
|
tmp = tempfile.mkdtemp()
|
||||||
|
# suppress stdout (and stderr) if not heavydebug
|
||||||
|
supdbgout = ' >/dev/null 2>&1' if unittest.F2B.log_level >= logging.DEBUG else '' # HEAVYDEBUG
|
||||||
|
try:
|
||||||
|
# try dry-run:
|
||||||
|
os.system("%s %s --dry-run install --disable-2to3 --root=%s%s"
|
||||||
|
% (sys.executable, self.setup , tmp, supdbgout))
|
||||||
|
# check nothing was created:
|
||||||
|
self.assertTrue(not os.listdir(tmp))
|
||||||
|
finally:
|
||||||
|
# clean up
|
||||||
|
shutil.rmtree(tmp)
|
||||||
|
|
||||||
def testSetupInstallRoot(self):
|
def testSetupInstallRoot(self):
|
||||||
if not self.setup:
|
if not self.setup:
|
||||||
return # if verbose skip didn't work out
|
return # if verbose skip didn't work out
|
||||||
|
@ -108,8 +124,8 @@ class SetupTest(unittest.TestCase):
|
||||||
# suppress stdout (and stderr) if not heavydebug
|
# suppress stdout (and stderr) if not heavydebug
|
||||||
supdbgout = ' >/dev/null' if unittest.F2B.log_level >= logging.DEBUG else '' # HEAVYDEBUG
|
supdbgout = ' >/dev/null' if unittest.F2B.log_level >= logging.DEBUG else '' # HEAVYDEBUG
|
||||||
try:
|
try:
|
||||||
os.system("%s %s install --disable-2to3 --dry-run --root=%s%s"
|
self.assertEqual(os.system("%s %s install --disable-2to3 --root=%s%s"
|
||||||
% (sys.executable, self.setup, tmp, supdbgout))
|
% (sys.executable, self.setup, tmp, supdbgout)), 0)
|
||||||
|
|
||||||
def strippath(l):
|
def strippath(l):
|
||||||
return [x[len(tmp)+1:] for x in l]
|
return [x[len(tmp)+1:] for x in l]
|
||||||
|
|
|
@ -7,11 +7,11 @@ PartOf=iptables.service firewalld.service
|
||||||
[Service]
|
[Service]
|
||||||
Type=simple
|
Type=simple
|
||||||
ExecStartPre=/bin/mkdir -p /var/run/fail2ban
|
ExecStartPre=/bin/mkdir -p /var/run/fail2ban
|
||||||
ExecStart=/usr/bin/fail2ban-server -xf start
|
ExecStart=@BINDIR@/fail2ban-server -xf start
|
||||||
# if should be logged in systemd journal, use following line or set logtarget to stdout in fail2ban.local
|
# if should be logged in systemd journal, use following line or set logtarget to stdout in fail2ban.local
|
||||||
# ExecStart=/usr/bin/fail2ban-server -xf --logtarget=stdout start
|
# ExecStart=@BINDIR@/fail2ban-server -xf --logtarget=stdout start
|
||||||
ExecStop=/usr/bin/fail2ban-client stop
|
ExecStop=@BINDIR@/fail2ban-client stop
|
||||||
ExecReload=/usr/bin/fail2ban-client reload
|
ExecReload=@BINDIR@/fail2ban-client reload
|
||||||
PIDFile=/var/run/fail2ban/fail2ban.pid
|
PIDFile=/var/run/fail2ban/fail2ban.pid
|
||||||
Restart=on-failure
|
Restart=on-failure
|
||||||
RestartPreventExitStatus=0 255
|
RestartPreventExitStatus=0 255
|
47
setup.py
47
setup.py
|
@ -50,6 +50,7 @@ except ImportError:
|
||||||
|
|
||||||
import os
|
import os
|
||||||
from os.path import isfile, join, isdir, realpath
|
from os.path import isfile, join, isdir, realpath
|
||||||
|
import re
|
||||||
import sys
|
import sys
|
||||||
import warnings
|
import warnings
|
||||||
from glob import glob
|
from glob import glob
|
||||||
|
@ -57,11 +58,25 @@ from glob import glob
|
||||||
from fail2ban.setup import updatePyExec
|
from fail2ban.setup import updatePyExec
|
||||||
|
|
||||||
|
|
||||||
|
source_dir = os.path.realpath(os.path.dirname(
|
||||||
|
# __file__ seems to be overwritten sometimes on some python versions (e.g. bug of 2.6 by running under cProfile, etc.):
|
||||||
|
sys.argv[0] if os.path.basename(sys.argv[0]) == 'setup.py' else __file__
|
||||||
|
))
|
||||||
|
|
||||||
# Wrapper to install python binding (to current python version):
|
# Wrapper to install python binding (to current python version):
|
||||||
class install_scripts_f2b(install_scripts):
|
class install_scripts_f2b(install_scripts):
|
||||||
|
|
||||||
def get_outputs(self):
|
def get_outputs(self):
|
||||||
outputs = install_scripts.get_outputs(self)
|
outputs = install_scripts.get_outputs(self)
|
||||||
|
# setup.py --dry-run install:
|
||||||
|
dry_run = not outputs
|
||||||
|
self.update_scripts(dry_run)
|
||||||
|
if dry_run:
|
||||||
|
#bindir = self.install_dir
|
||||||
|
bindir = self.build_dir
|
||||||
|
print('creating fail2ban-python binding -> %s (dry-run, real path can be different)' % (bindir,))
|
||||||
|
print('Copying content of %s to %s' % (self.build_dir, self.install_dir));
|
||||||
|
return outputs
|
||||||
fn = None
|
fn = None
|
||||||
for fn in outputs:
|
for fn in outputs:
|
||||||
if os.path.basename(fn) == 'fail2ban-server':
|
if os.path.basename(fn) == 'fail2ban-server':
|
||||||
|
@ -71,6 +86,27 @@ class install_scripts_f2b(install_scripts):
|
||||||
updatePyExec(bindir)
|
updatePyExec(bindir)
|
||||||
return outputs
|
return outputs
|
||||||
|
|
||||||
|
def update_scripts(self, dry_run=False):
|
||||||
|
buildroot = os.path.dirname(self.build_dir)
|
||||||
|
print('Creating %s/fail2ban.service (from fail2ban.service.in): @BINDIR@ -> %s' % (buildroot, self.install_dir))
|
||||||
|
with open(os.path.join(source_dir, 'files/fail2ban.service.in'), 'r') as fn:
|
||||||
|
lines = fn.readlines()
|
||||||
|
fn = None
|
||||||
|
if not dry_run:
|
||||||
|
fn = open(os.path.join(buildroot, 'fail2ban.service'), 'w')
|
||||||
|
try:
|
||||||
|
for ln in lines:
|
||||||
|
ln = re.sub(r'@BINDIR@', lambda v: self.install_dir, ln)
|
||||||
|
if dry_run:
|
||||||
|
sys.stdout.write(' | ' + ln)
|
||||||
|
continue
|
||||||
|
fn.write(ln)
|
||||||
|
finally:
|
||||||
|
if fn: fn.close()
|
||||||
|
if dry_run:
|
||||||
|
print(' `')
|
||||||
|
|
||||||
|
|
||||||
# Wrapper to specify fail2ban own options:
|
# Wrapper to specify fail2ban own options:
|
||||||
class install_command_f2b(install):
|
class install_command_f2b(install):
|
||||||
user_options = install.user_options + [
|
user_options = install.user_options + [
|
||||||
|
@ -94,11 +130,7 @@ class install_command_f2b(install):
|
||||||
|
|
||||||
|
|
||||||
# Update fail2ban-python env to current python version (where f2b-modules located/installed)
|
# Update fail2ban-python env to current python version (where f2b-modules located/installed)
|
||||||
rootdir = os.path.realpath(os.path.dirname(
|
updatePyExec(os.path.join(source_dir, 'bin'))
|
||||||
# __file__ seems to be overwritten sometimes on some python versions (e.g. bug of 2.6 by running under cProfile, etc.):
|
|
||||||
sys.argv[0] if os.path.basename(sys.argv[0]) == 'setup.py' else __file__
|
|
||||||
))
|
|
||||||
updatePyExec(os.path.join(rootdir, 'bin'))
|
|
||||||
|
|
||||||
if setuptools and "test" in sys.argv:
|
if setuptools and "test" in sys.argv:
|
||||||
import logging
|
import logging
|
||||||
|
@ -270,5 +302,8 @@ if isdir("/usr/lib/fail2ban"):
|
||||||
if sys.argv[1] == "install":
|
if sys.argv[1] == "install":
|
||||||
print("")
|
print("")
|
||||||
print("Please do not forget to update your configuration files.")
|
print("Please do not forget to update your configuration files.")
|
||||||
print("They are in /etc/fail2ban/.")
|
print("They are in \"/etc/fail2ban/\".")
|
||||||
|
print("")
|
||||||
|
print("You can also install systemd service-unit file from \"build/fail2ban.service\"")
|
||||||
|
print("resp. corresponding init script from \"files/*-initd\".")
|
||||||
print("")
|
print("")
|
||||||
|
|
Loading…
Reference in New Issue