Merge remote-tracking branch 'remotes/gh-upstream/0.10' into 0.11

pull/1913/head
sebres 2017-09-01 10:37:52 +02:00
commit 32058ed268
5 changed files with 96 additions and 18 deletions

View File

@ -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)

View File

@ -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

View File

@ -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]

View File

@ -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

View File

@ -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("")