mirror of https://github.com/fail2ban/fail2ban
Merge pull request #1705 from sebres/0.10-tag-ip-host
New actions tag `<ip-host>` introduced: can be used in actions to retrieve the host name (dns) from the IP addresspull/1709/head
commit
e71f3d595f
|
@ -17,6 +17,8 @@ TODO: implementing of options resp. other tasks from PR #1346
|
||||||
- [grave] injection on user name to host fixed
|
- [grave] injection on user name to host fixed
|
||||||
* `action.d/complain.conf`
|
* `action.d/complain.conf`
|
||||||
- fixed using new tag `<ip-rev>` (sh/dash compliant now)
|
- fixed using new tag `<ip-rev>` (sh/dash compliant now)
|
||||||
|
* `action.d/sendmail-geoip-lines.conf`
|
||||||
|
- fixed using new tag `<ip-host>` (without external command execution)
|
||||||
|
|
||||||
### New Features
|
### New Features
|
||||||
* New Actions:
|
* New Actions:
|
||||||
|
@ -44,7 +46,11 @@ TODO: implementing of options resp. other tasks from PR #1346
|
||||||
to re.sub with callable)
|
to re.sub with callable)
|
||||||
* substituteRecursiveTags optimization + moved in helpers facilities (because currently used
|
* substituteRecursiveTags optimization + moved in helpers facilities (because currently used
|
||||||
commonly in server and in client)
|
commonly in server and in client)
|
||||||
* Provides new tag `<ip-rev>` for PTR reversed representation of IP address
|
* New tags (usable in actions):
|
||||||
|
- `<fid>` - failure identifier (if raw resp. failures without IP address)
|
||||||
|
- `<ip-rev>` - PTR reversed representation of IP address
|
||||||
|
- `<ip-host>` - host name of the IP address
|
||||||
|
- `<F-...>` - interpolates to the corresponding filter group capture `...`
|
||||||
|
|
||||||
|
|
||||||
ver. 0.10.0-alpha-1 (2016/07/14) - ipv6-support-etc
|
ver. 0.10.0-alpha-1 (2016/07/14) - ipv6-support-etc
|
||||||
|
|
|
@ -36,7 +36,7 @@ actionban = ( printf %%b "Subject: [Fail2Ban] <name>: banned <ip> from `uname -n
|
||||||
http://whois.domaintools.com/<ip>\n\n
|
http://whois.domaintools.com/<ip>\n\n
|
||||||
Country:`geoiplookup -f /usr/share/GeoIP/GeoIP.dat "<ip>" | cut -d':' -f2-`
|
Country:`geoiplookup -f /usr/share/GeoIP/GeoIP.dat "<ip>" | cut -d':' -f2-`
|
||||||
AS:`geoiplookup -f /usr/share/GeoIP/GeoIPASNum.dat "<ip>" | cut -d':' -f2-`
|
AS:`geoiplookup -f /usr/share/GeoIP/GeoIPASNum.dat "<ip>" | cut -d':' -f2-`
|
||||||
hostname: `host -t A <ip> 2>&1`\n\n
|
hostname: <ip-host>\n\n
|
||||||
Lines containing failures of <ip>\n";
|
Lines containing failures of <ip>\n";
|
||||||
%(_grep_logs)s;
|
%(_grep_logs)s;
|
||||||
printf %%b "\n
|
printf %%b "\n
|
||||||
|
|
|
@ -291,6 +291,7 @@ class Actions(JailThread, Mapping):
|
||||||
AI_DICT = {
|
AI_DICT = {
|
||||||
"ip": lambda self: self.__ticket.getIP(),
|
"ip": lambda self: self.__ticket.getIP(),
|
||||||
"ip-rev": lambda self: self['ip'].getPTR(''),
|
"ip-rev": lambda self: self['ip'].getPTR(''),
|
||||||
|
"ip-host": lambda self: self['ip'].getHost(),
|
||||||
"fid": lambda self: self.__ticket.getID(),
|
"fid": lambda self: self.__ticket.getID(),
|
||||||
"failures": lambda self: self.__ticket.getAttempt(),
|
"failures": lambda self: self.__ticket.getAttempt(),
|
||||||
"time": lambda self: self.__ticket.getTime(),
|
"time": lambda self: self.__ticket.getTime(),
|
||||||
|
|
|
@ -376,6 +376,11 @@ class IPAddr(object):
|
||||||
|
|
||||||
return "%s.%s" % (".".join(reversed(exploded_ip)), suffix)
|
return "%s.%s" % (".".join(reversed(exploded_ip)), suffix)
|
||||||
|
|
||||||
|
def getHost(self):
|
||||||
|
"""Return the host name (DNS) of the provided IP address object
|
||||||
|
"""
|
||||||
|
return DNSUtils.ipToName(self.ntoa)
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def isIPv4(self):
|
def isIPv4(self):
|
||||||
"""Either the IP object is of address family AF_INET
|
"""Either the IP object is of address family AF_INET
|
||||||
|
|
|
@ -38,7 +38,9 @@ from ..server.server import Server
|
||||||
from ..server.ipdns import IPAddr
|
from ..server.ipdns import IPAddr
|
||||||
from ..server.jail import Jail
|
from ..server.jail import Jail
|
||||||
from ..server.jailthread import JailThread
|
from ..server.jailthread import JailThread
|
||||||
|
from ..server.ticket import BanTicket
|
||||||
from ..server.utils import Utils
|
from ..server.utils import Utils
|
||||||
|
from .dummyjail import DummyJail
|
||||||
from .utils import LogCaptureTestCase
|
from .utils import LogCaptureTestCase
|
||||||
from ..helpers import getLogger, PREFER_ENC
|
from ..helpers import getLogger, PREFER_ENC
|
||||||
from .. import version
|
from .. import version
|
||||||
|
@ -1677,7 +1679,7 @@ class ServerConfigReaderTests(LogCaptureTestCase):
|
||||||
# complain --
|
# complain --
|
||||||
('j-complain-abuse',
|
('j-complain-abuse',
|
||||||
'complain['
|
'complain['
|
||||||
'name=%(__name__)s, grepopts="-m 1", grepmax=2, mailcmd="mail -s",' +
|
'name=%(__name__)s, grepopts="-m 1", grepmax=2, mailcmd="mail -s Hostname: <ip-host> - ",' +
|
||||||
# test reverse ip:
|
# test reverse ip:
|
||||||
'debug=1,' +
|
'debug=1,' +
|
||||||
# 2 logs to test grep from multiple logs:
|
# 2 logs to test grep from multiple logs:
|
||||||
|
@ -1692,14 +1694,14 @@ class ServerConfigReaderTests(LogCaptureTestCase):
|
||||||
'testcase01.log:Dec 31 11:59:59 [sshd] error: PAM: Authentication failure for kevin from 87.142.124.10',
|
'testcase01.log:Dec 31 11:59:59 [sshd] error: PAM: Authentication failure for kevin from 87.142.124.10',
|
||||||
'testcase01a.log:Dec 31 11:55:01 [sshd] error: PAM: Authentication failure for test from 87.142.124.10',
|
'testcase01a.log:Dec 31 11:55:01 [sshd] error: PAM: Authentication failure for test from 87.142.124.10',
|
||||||
# both abuse mails should be separated with space:
|
# both abuse mails should be separated with space:
|
||||||
'mail -s Abuse from 87.142.124.10 abuse-1@abuse-test-server abuse-2@abuse-test-server',
|
'mail -s Hostname: test-host - Abuse from 87.142.124.10 abuse-1@abuse-test-server abuse-2@abuse-test-server',
|
||||||
),
|
),
|
||||||
'ip6-ban': (
|
'ip6-ban': (
|
||||||
# test reverse ip:
|
# test reverse ip:
|
||||||
'try to resolve 1.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.8.b.d.0.1.0.0.2.abuse-contacts.abusix.org',
|
'try to resolve 1.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.8.b.d.0.1.0.0.2.abuse-contacts.abusix.org',
|
||||||
'Lines containing failures of 2001:db8::1 (max 2)',
|
'Lines containing failures of 2001:db8::1 (max 2)',
|
||||||
# both abuse mails should be separated with space:
|
# both abuse mails should be separated with space:
|
||||||
'mail -s Abuse from 2001:db8::1 abuse-1@abuse-test-server abuse-2@abuse-test-server',
|
'mail -s Hostname: test-host - Abuse from 2001:db8::1 abuse-1@abuse-test-server abuse-2@abuse-test-server',
|
||||||
),
|
),
|
||||||
}),
|
}),
|
||||||
)
|
)
|
||||||
|
@ -1723,6 +1725,7 @@ class ServerConfigReaderTests(LogCaptureTestCase):
|
||||||
|
|
||||||
ipv4 = IPAddr('87.142.124.10')
|
ipv4 = IPAddr('87.142.124.10')
|
||||||
ipv6 = IPAddr('2001:db8::1');
|
ipv6 = IPAddr('2001:db8::1');
|
||||||
|
dmyjail = DummyJail()
|
||||||
for jail, act, tests in testJailsActions:
|
for jail, act, tests in testJailsActions:
|
||||||
# print(jail, jails[jail])
|
# print(jail, jails[jail])
|
||||||
for a in jails[jail].actions:
|
for a in jails[jail].actions:
|
||||||
|
@ -1736,7 +1739,8 @@ class ServerConfigReaderTests(LogCaptureTestCase):
|
||||||
for (test, ip) in (('ip4-ban', ipv4), ('ip6-ban', ipv6)):
|
for (test, ip) in (('ip4-ban', ipv4), ('ip6-ban', ipv6)):
|
||||||
if not tests.get(test): continue
|
if not tests.get(test): continue
|
||||||
self.pruneLog('# === %s ===' % test)
|
self.pruneLog('# === %s ===' % test)
|
||||||
ticket = _actions.CallingMap({
|
ticket = BanTicket(ip)
|
||||||
'ip': ip, 'ip-rev': lambda self: self['ip'].getPTR(''), 'failures': 100,})
|
ticket.setAttempt(100)
|
||||||
|
ticket = _actions.Actions.ActionInfo(ticket, dmyjail)
|
||||||
action.ban(ticket)
|
action.ban(ticket)
|
||||||
self.assertLogged(*tests[test], all=True)
|
self.assertLogged(*tests[test], all=True)
|
||||||
|
|
|
@ -273,6 +273,9 @@ def initTests(opts):
|
||||||
c.set('192.0.2.%s' % i, None)
|
c.set('192.0.2.%s' % i, None)
|
||||||
c.set('198.51.100.%s' % i, None)
|
c.set('198.51.100.%s' % i, None)
|
||||||
c.set('203.0.113.%s' % i, None)
|
c.set('203.0.113.%s' % i, None)
|
||||||
|
c.set('2001:db8::%s' %i, 'test-host')
|
||||||
|
# some legal ips used in our test cases (prevent slow dns-resolving and failures if will be changed later):
|
||||||
|
c.set('87.142.124.10', 'test-host')
|
||||||
if unittest.F2B.no_network: # pragma: no cover
|
if unittest.F2B.no_network: # pragma: no cover
|
||||||
# precache all wrong dns to ip's used in test cases:
|
# precache all wrong dns to ip's used in test cases:
|
||||||
c = DNSUtils.CACHE_nameToIp
|
c = DNSUtils.CACHE_nameToIp
|
||||||
|
|
Loading…
Reference in New Issue