mirror of https://github.com/fail2ban/fail2ban
Merge branch 'fix-xarf-abuse-action' into 0.10 (closes gh-2372)
commit
6fe6ebe039
|
@ -41,7 +41,12 @@ actionstop =
|
||||||
|
|
||||||
actioncheck =
|
actioncheck =
|
||||||
|
|
||||||
actionban = oifs=${IFS}; IFS=.;SEP_IP=( <ip> ); set -- ${SEP_IP}; ADDRESSES=$(dig +short -t txt -q $4.$3.$2.$1.abuse-contacts.abusix.org); IFS=${oifs}
|
actionban = oifs=${IFS};
|
||||||
|
RESOLVER_ADDR="%(addr_resolver)s"
|
||||||
|
if [ "<debug>" -gt 0 ]; then echo "try to resolve $RESOLVER_ADDR"; fi
|
||||||
|
ADDRESSES=$(dig +short -t txt -q $RESOLVER_ADDR | tr -d '"')
|
||||||
|
IFS=,; ADDRESSES=$(echo $ADDRESSES)
|
||||||
|
IFS=${oifs}
|
||||||
IP=<ip>
|
IP=<ip>
|
||||||
FROM=<sender>
|
FROM=<sender>
|
||||||
SERVICE=<service>
|
SERVICE=<service>
|
||||||
|
@ -51,26 +56,37 @@ actionban = oifs=${IFS}; IFS=.;SEP_IP=( <ip> ); set -- ${SEP_IP}; ADDRESSES=$(di
|
||||||
PORT=<port>
|
PORT=<port>
|
||||||
DATE=`LC_ALL=C date --date=@<time> +"%%a, %%d %%h %%Y %%T %%z"`
|
DATE=`LC_ALL=C date --date=@<time> +"%%a, %%d %%h %%Y %%T %%z"`
|
||||||
if [ ! -z "$ADDRESSES" ]; then
|
if [ ! -z "$ADDRESSES" ]; then
|
||||||
|
oifs=${IFS}; IFS=,; ADDRESSES=$(echo $ADDRESSES)
|
||||||
|
IFS=${oifs}
|
||||||
(printf -- %%b "<header>\n<message>\n<report>\n\n";
|
(printf -- %%b "<header>\n<message>\n<report>\n\n";
|
||||||
date '+Note: Local timezone is %%z (%%Z)';
|
date '+Note: Local timezone is %%z (%%Z)';
|
||||||
printf -- %%b "\n<ipmatches>\n\n<footer>") | <mailcmd> <mailargs> ${ADDRESSES//,/\" \"}
|
printf -- %%b "\n<ipmatches>\n\n<footer>") | <mailcmd> <mailargs> $ADDRESSES
|
||||||
fi
|
fi
|
||||||
|
|
||||||
actionunban =
|
actionunban =
|
||||||
|
|
||||||
[Init]
|
# Server as resolver used in dig command
|
||||||
|
#
|
||||||
|
addr_resolver = <ip-rev>abuse-contacts.abusix.org
|
||||||
|
|
||||||
|
# Option: boundary
|
||||||
|
# Notes: This can be overwritten to be safe for possible predictions
|
||||||
|
boundary = bfbb0f920793ac03cb8634bde14d8a1e
|
||||||
|
|
||||||
|
_boundary = Abuse<time>-<boundary>
|
||||||
|
|
||||||
# Option: header
|
# Option: header
|
||||||
# Notes: This is really a fixed value
|
# Notes: This is really a fixed value
|
||||||
header = Subject: abuse report about $IP - $DATE\nAuto-Submitted: auto-generated\nX-XARF: PLAIN\nContent-Transfer-Encoding: 7bit\nContent-Type: multipart/mixed; charset=utf8;\n boundary=Abuse-bfbb0f920793ac03cb8634bde14d8a1e;\n\n--Abuse-bfbb0f920793ac03cb8634bde14d8a1e\nMIME-Version: 1.0\nContent-Transfer-Encoding: 7bit\nContent-Type: text/plain; charset=utf-8;\n
|
header = Subject: abuse report about $IP - $DATE\nAuto-Submitted: auto-generated\nX-XARF: PLAIN\nContent-Transfer-Encoding: 7bit\nContent-Type: multipart/mixed; charset=utf8;\n boundary=%(_boundary)s;\n\n--%(_boundary)s\nMIME-Version: 1.0\nContent-Transfer-Encoding: 7bit\nContent-Type: text/plain; charset=utf-8;\n
|
||||||
|
|
||||||
# Option: footer
|
# Option: footer
|
||||||
# Notes: This is really a fixed value and needs to match the report and header
|
# Notes: This is really a fixed value and needs to match the report and header
|
||||||
# mime delimiters
|
# mime delimiters
|
||||||
footer = \n\n--Abuse-bfbb0f920793ac03cb8634bde14d8a1e--
|
footer = \n\n--%(_boundary)s--
|
||||||
|
|
||||||
# Option: report
|
# Option: report
|
||||||
# Notes: Intended to be fixed
|
# Notes: Intended to be fixed
|
||||||
report = --Abuse-bfbb0f920793ac03cb8634bde14d8a1e\nMIME-Version: 1.0\nContent-Transfer-Encoding: 7bit\nContent-Type: text/plain; charset=utf-8; name=\"report.txt\";\n\n---\nReported-From: $FROM\nCategory: abuse\nReport-ID: $REPORTID\nReport-Type: login-attack\nService: $SERVICE\nVersion: 0.2\nUser-Agent: Fail2ban v0.9\nDate: $DATE\nSource-Type: ip-address\nSource: $IP\nPort: $PORT\nSchema-URL: http://www.x-arf.org/schema/abuse_login-attack_0.1.2.json\nAttachment: text/plain\nOccurances: $FAILURES\nTLP: $TLP\n\n\n--Abuse-bfbb0f920793ac03cb8634bde14d8a1e\nMIME-Version: 1.0\nContent-Transfer-Encoding: 7bit\nContent-Type: text/plain; charset=utf8; name=\"logfile.log\";
|
report = --%(_boundary)s\nMIME-Version: 1.0\nContent-Transfer-Encoding: 7bit\nContent-Type: text/plain; charset=utf-8; name=\"report.txt\";\n\n---\nReported-From: $FROM\nCategory: abuse\nReport-ID: $REPORTID\nReport-Type: login-attack\nService: $SERVICE\nVersion: 0.2\nUser-Agent: Fail2ban v0.9\nDate: $DATE\nSource-Type: ip-address\nSource: $IP\nPort: $PORT\nSchema-URL: http://www.x-arf.org/schema/abuse_login-attack_0.1.2.json\nAttachment: text/plain\nOccurances: $FAILURES\nTLP: $TLP\n\n\n--%(_boundary)s\nMIME-Version: 1.0\nContent-Transfer-Encoding: 7bit\nContent-Type: text/plain; charset=utf8; name=\"logfile.log\";
|
||||||
|
|
||||||
# Option: Message
|
# Option: Message
|
||||||
# Notes: This can be modified by the users
|
# Notes: This can be modified by the users
|
||||||
|
|
|
@ -1866,12 +1866,19 @@ class ServerConfigReaderTests(LogCaptureTestCase):
|
||||||
|
|
||||||
def _executeMailCmd(self, realCmd, timeout=60):
|
def _executeMailCmd(self, realCmd, timeout=60):
|
||||||
# replace pipe to mail with pipe to cat:
|
# replace pipe to mail with pipe to cat:
|
||||||
realCmd = re.sub(r'\)\s*\|\s*mail\b([^\n]*)',
|
cmd = realCmd
|
||||||
r') | cat; printf "\\n... | "; echo mail \1', realCmd)
|
if isinstance(realCmd, list):
|
||||||
|
cmd = realCmd[0]
|
||||||
|
cmd = re.sub(r'\)\s*\|\s*mail\b([^\n]*)',
|
||||||
|
r') | cat; printf "\\n... | "; echo mail \1', cmd)
|
||||||
# replace abuse retrieving (possible no-network), just replace first occurrence of 'dig...':
|
# replace abuse retrieving (possible no-network), just replace first occurrence of 'dig...':
|
||||||
realCmd = re.sub(r'\bADDRESSES=\$\(dig\s[^\n]+',
|
cmd = re.sub(r'\bADDRESSES=\$\(dig\s[^\n]+',
|
||||||
lambda m: 'ADDRESSES="abuse-1@abuse-test-server, abuse-2@abuse-test-server"',
|
lambda m: 'ADDRESSES="abuse-1@abuse-test-server, abuse-2@abuse-test-server"',
|
||||||
realCmd, 1)
|
cmd, 1)
|
||||||
|
if isinstance(realCmd, list):
|
||||||
|
realCmd[0] = cmd
|
||||||
|
else:
|
||||||
|
realCmd = cmd
|
||||||
# execute action:
|
# execute action:
|
||||||
return _actions.CommandAction.executeCmd(realCmd, timeout=timeout)
|
return _actions.CommandAction.executeCmd(realCmd, timeout=timeout)
|
||||||
|
|
||||||
|
@ -1926,6 +1933,31 @@ class ServerConfigReaderTests(LogCaptureTestCase):
|
||||||
'mail -s Hostname: test-host, family: inet6 - Abuse from 2001:db8::1 abuse-1@abuse-test-server abuse-2@abuse-test-server',
|
'mail -s Hostname: test-host, family: inet6 - Abuse from 2001:db8::1 abuse-1@abuse-test-server abuse-2@abuse-test-server',
|
||||||
),
|
),
|
||||||
}),
|
}),
|
||||||
|
# xarf-login-attack --
|
||||||
|
('j-xarf-abuse',
|
||||||
|
'xarf-login-attack['
|
||||||
|
'name=%(__name__)s, mailcmd="mail", mailargs="",' +
|
||||||
|
# test reverse ip:
|
||||||
|
'debug=1' +
|
||||||
|
']',
|
||||||
|
{
|
||||||
|
'ip4-ban': (
|
||||||
|
# test reverse ip:
|
||||||
|
'try to resolve 10.124.142.87.abuse-contacts.abusix.org',
|
||||||
|
'We have detected abuse from the IP address 87.142.124.10',
|
||||||
|
'Dec 31 11:59:59 [sshd] error: PAM: Authentication failure for kevin from 87.142.124.10',
|
||||||
|
'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:
|
||||||
|
'mail abuse-1@abuse-test-server abuse-2@abuse-test-server',
|
||||||
|
),
|
||||||
|
'ip6-ban': (
|
||||||
|
# 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',
|
||||||
|
'We have detected abuse from the IP address 2001:db8::1',
|
||||||
|
# both abuse mails should be separated with space:
|
||||||
|
'mail abuse-1@abuse-test-server abuse-2@abuse-test-server',
|
||||||
|
),
|
||||||
|
}),
|
||||||
)
|
)
|
||||||
server = TestServer()
|
server = TestServer()
|
||||||
transm = server._Server__transm
|
transm = server._Server__transm
|
||||||
|
@ -1963,6 +1995,10 @@ class ServerConfigReaderTests(LogCaptureTestCase):
|
||||||
self.pruneLog('# === %s ===' % test)
|
self.pruneLog('# === %s ===' % test)
|
||||||
ticket = BanTicket(ip)
|
ticket = BanTicket(ip)
|
||||||
ticket.setAttempt(100)
|
ticket.setAttempt(100)
|
||||||
|
ticket.setMatches([
|
||||||
|
'Dec 31 11:59:59 [sshd] error: PAM: Authentication failure for kevin from 87.142.124.10',
|
||||||
|
'Dec 31 11:55:01 [sshd] error: PAM: Authentication failure for test from 87.142.124.10'
|
||||||
|
])
|
||||||
ticket = _actions.Actions.ActionInfo(ticket, dmyjail)
|
ticket = _actions.Actions.ActionInfo(ticket, dmyjail)
|
||||||
action.ban(ticket)
|
action.ban(ticket)
|
||||||
self.assertLogged(*tests[test], all=True)
|
self.assertLogged(*tests[test], all=True)
|
||||||
|
|
Loading…
Reference in New Issue