Add ban feature to fail2ban script (#2538)

This commit is contained in:
Casper 2022-04-19 10:44:51 +02:00 committed by GitHub
parent 9aaf15b38f
commit de61d42e68
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
9 changed files with 105 additions and 30 deletions

View file

@ -1,21 +1,37 @@
[DEFAULT] [DEFAULT]
# "bantime" is the number of seconds that a host is banned. # "bantime" is the number of seconds that a host is banned.
#bantime = 10m bantime = 3h
# A host is banned if it has generated "maxretry" during the last "findtime" # A host is banned if it has generated "maxretry" during the last "findtime"
# seconds. # seconds.
#findtime = 10m findtime = 10m
# "maxretry" is the number of failures before a host get banned. # "maxretry" is the number of failures before a host get banned.
#maxretry = 5 maxretry = 3
# "ignoreip" can be a list of IP addresses, CIDR masks or DNS hosts. Fail2ban # "ignoreip" can be a list of IP addresses, CIDR masks or DNS hosts. Fail2ban
# will not ban a host which matches an address in this list. Several addresses # will not ban a host which matches an address in this list. Several addresses
# can be defined using space (and/or comma) separator. # can be defined using space (and/or comma) separator.
#ignoreip = 127.0.0.1/8 ignoreip = 127.0.0.1/8
# Default ban action # default ban action
# nftables-multiport: block IP only on affected port # nftables-multiport: block IP only on affected port
# nftables-allports: block IP on all ports # nftables-allports: block IP on all ports
#banaction = nftables-allports banaction = nftables-allports
[dovecot]
enabled = true
[postfix]
enabled = true
[postfix-sasl]
enabled = true
# This jail is used for manual bans.
# To ban an IP address use: setup.sh fail2ban ban <IP>
[custom]
enabled = true
bantime = 180d
port = smtp,pop3,pop3s,imap,imaps,submission,submissions,sieve

View file

@ -97,7 +97,7 @@ You can also manage and list the banned IPs with the [`setup.sh`][docs-setupsh]
### List bans ### List bans
```sh ```sh
./setup.sh debug fail2ban ./setup.sh fail2ban
``` ```
### Un-ban ### Un-ban
@ -105,7 +105,7 @@ You can also manage and list the banned IPs with the [`setup.sh`][docs-setupsh]
Here `192.168.1.15` is our banned IP. Here `192.168.1.15` is our banned IP.
```sh ```sh
./setup.sh debug fail2ban unban 192.168.1.15 ./setup.sh fail2ban unban 192.168.1.15
``` ```
[docs-setupsh]: ../setup.sh.md [docs-setupsh]: ../setup.sh.md

View file

@ -73,8 +73,12 @@ DESCRIPTION
./setup.sh relay add-domain <DOMAIN> <HOST> [<PORT>] ./setup.sh relay add-domain <DOMAIN> <HOST> [<PORT>]
./setup.sh relay exclude-domain <DOMAIN> ./setup.sh relay exclude-domain <DOMAIN>
COMMAND fail2ban =
./setup.sh fail2ban
./setup.sh fail2ban ban <IP>
./setup.sh fail2ban unban <IP>
COMMAND debug := COMMAND debug :=
./setup.sh debug fail2ban [unban <IP>]
./setup.sh debug fetchmail ./setup.sh debug fetchmail
./setup.sh debug login <COMMANDS> ./setup.sh debug login <COMMANDS>
./setup.sh debug show-mail-logs ./setup.sh debug show-mail-logs

View file

@ -427,6 +427,17 @@ sed -i 's/rimap -r/rimap/' /etc/supervisor/conf.d/saslauth.conf
supervisorctl update supervisorctl update
``` ```
### How to ban custom IP addresses with Fail2ban
Use the following command:
```bash
./setup.sh fail2ban ban <IP>
```
The default bantime is 180 days. This value can be [customized][fail2ban-customize].
[fail2ban-customize]: ./config/security/fail2ban.md
[docs-maintenance]: ./config/advanced/maintenance/update-and-cleanup.md [docs-maintenance]: ./config/advanced/maintenance/update-and-cleanup.md
[docs-userpatches]: ./config/advanced/override-defaults/user-patches.md [docs-userpatches]: ./config/advanced/override-defaults/user-patches.md
[github-issue-95]: https://github.com/docker-mailserver/docker-mailserver/issues/95 [github-issue-95]: https://github.com/docker-mailserver/docker-mailserver/issues/95

View file

@ -3,7 +3,7 @@
# shellcheck source=../scripts/helpers/index.sh # shellcheck source=../scripts/helpers/index.sh
source /usr/local/bin/helpers/index.sh source /usr/local/bin/helpers/index.sh
function __usage { echo "Usage: ${0} [<unban> <ip-address>]" ; } function __usage { echo "Usage: ./setup.sh fail2ban [<ban|unban> <IP>]" ; }
unset JAILS unset JAILS
declare -a JAILS declare -a JAILS
@ -36,6 +36,26 @@ else
case "${1}" in case "${1}" in
( 'help' ) __usage ; exit ;;
( 'ban' )
shift
if [[ -n ${1} ]]
then
RESULT=$(fail2ban-client set custom banip "${@}")
if [[ ${RESULT} -gt 0 ]]
then
echo "Banned custom IP: ${RESULT}"
else
_log 'error' "Banning '${*}' failed. Already banned?"
fi
else
_log 'warn' "You need to specify an IP address: Run './setup.sh fail2ban ban <IP>'"
exit 0
fi
;;
( 'unban' ) ( 'unban' )
shift shift
if [[ -n ${1} ]] if [[ -n ${1} ]]
@ -43,13 +63,13 @@ else
for JAIL in "${JAILS[@]}" for JAIL in "${JAILS[@]}"
do do
RESULT="$(fail2ban-client set "${JAIL}" unbanip "${@}" 2>&1)" RESULT=$(fail2ban-client set "${JAIL}" unbanip "${@}" 2>&1)
[[ ${RESULT} != *"is not banned"* ]] && [[ ${RESULT} != *"NOK"* ]] && echo -e "Unbanned IP from ${JAIL}: ${RESULT}" [[ ${RESULT} != *"is not banned"* ]] && [[ ${RESULT} != *"NOK"* ]] && echo "Unbanned IP from ${JAIL}: ${RESULT}"
done done
else else
_log 'warn' "You need to specify an IP address: Run './setup.sh debug fail2ban' to get a list of banned IP addresses" _log 'warn' "You need to specify an IP address: Run './setup.sh fail2ban' to get a list of banned IP addresses"
exit 0 exit 0
fi fi
;; ;;

View file

@ -67,8 +67,12 @@ ${RED}[${ORANGE}SUB${RED}]${ORANGE}COMMANDS${RESET}
${0} relay ${CYAN}add-domain${RESET} <DOMAIN> <HOST> [<PORT>] ${0} relay ${CYAN}add-domain${RESET} <DOMAIN> <HOST> [<PORT>]
${0} relay ${CYAN}exclude-domain${RESET} <DOMAIN> ${0} relay ${CYAN}exclude-domain${RESET} <DOMAIN>
${LBLUE}COMMAND${RESET} fail2ban ${RED}:=${RESET}
${0} fail2ban ${RESET}
${0} fail2ban ${CYAN}ban${RESET} <IP>
${0} fail2ban ${CYAN}unban${RESET} <IP>
${LBLUE}COMMAND${RESET} debug ${RED}:=${RESET} ${LBLUE}COMMAND${RESET} debug ${RED}:=${RESET}
${0} debug ${CYAN}fail2ban${RESET} [unban <IP>]
${0} debug ${CYAN}fetchmail${RESET} ${0} debug ${CYAN}fetchmail${RESET}
${0} debug ${CYAN}login${RESET} <COMMANDS> ${0} debug ${CYAN}login${RESET} <COMMANDS>
${0} debug ${CYAN}show-mail-logs${RESET} ${0} debug ${CYAN}show-mail-logs${RESET}
@ -144,10 +148,11 @@ function _main
esac esac
;; ;;
( fail2ban ) shift 1 ; fail2ban "${@}" ;;
( debug ) ( debug )
case ${2:-} in case ${2:-} in
( fetchmail ) debug-fetchmail ;; ( fetchmail ) debug-fetchmail ;;
( fail2ban ) shift 2 ; fail2ban "${@}" ;;
( show-mail-logs ) cat /var/log/mail/mail.log ;; ( show-mail-logs ) cat /var/log/mail/mail.log ;;
( login ) ( login )
shift 2 shift 2

View file

@ -28,3 +28,10 @@ enabled = true
[postfix-sasl] [postfix-sasl]
enabled = true enabled = true
# This jail is used for manual bans.
# To ban an IP address use: setup.sh fail2ban ban <IP>
[custom]
enabled = true
bantime = 180d
port = smtp,pop3,pop3s,imap,imaps,submission,submissions,sieve

View file

@ -1149,10 +1149,13 @@ function _setup_user_patches
function _setup_fail2ban function _setup_fail2ban
{ {
_log 'debug' 'Setting up Fail2Ban' _log 'debug' 'Setting up Fail2Ban'
if [[ ${FAIL2BAN_BLOCKTYPE} != 'reject' ]] if [[ ${FAIL2BAN_BLOCKTYPE} != 'reject' ]]
then then
echo -e '[Init]\nblocktype = drop' >/etc/fail2ban/action.d/nftables-common.local echo -e '[Init]\nblocktype = drop' >/etc/fail2ban/action.d/nftables-common.local
fi fi
echo '[Definition]' >/etc/fail2ban/filter.d/custom.conf
} }
function _setup_dnsbl_disable function _setup_dnsbl_disable

View file

@ -116,32 +116,41 @@ function teardown_file() {
refute_output "${FAIL_AUTH_MAILER_IP}" refute_output "${FAIL_AUTH_MAILER_IP}"
} }
# @test "checking fail2ban ban" {
# debug run docker exec mail_fail2ban fail2ban ban 192.0.66.7
# assert_success
assert_output "Banned custom IP: 1"
@test "checking setup.sh: setup.sh debug fail2ban" { run docker exec mail_fail2ban fail2ban
assert_success
assert_output --regexp "Banned in custom:.*192\.0\.66\.7"
run docker exec mail_fail2ban fail2ban unban 192.0.66.7
assert_success
assert_output --partial "Unbanned IP from custom: 1"
}
@test "checking setup.sh: setup.sh fail2ban" {
run docker exec mail_fail2ban /bin/sh -c "fail2ban-client set dovecot banip 192.0.66.4" run docker exec mail_fail2ban /bin/sh -c "fail2ban-client set dovecot banip 192.0.66.4"
run docker exec mail_fail2ban /bin/sh -c "fail2ban-client set dovecot banip 192.0.66.5" run docker exec mail_fail2ban /bin/sh -c "fail2ban-client set dovecot banip 192.0.66.5"
sleep 10 sleep 10
run ./setup.sh -c mail_fail2ban debug fail2ban run ./setup.sh -c mail_fail2ban fail2ban
assert_output --partial 'Banned in dovecot:' assert_output --regexp '^Banned in dovecot:.*192\.0\.66\.4'
assert_output --partial '192.0.66.5' assert_output --regexp '^Banned in dovecot:.*192\.0\.66\.5'
assert_output --partial '192.0.66.4'
run ./setup.sh -c mail_fail2ban debug fail2ban unban 192.0.66.4 run ./setup.sh -c mail_fail2ban fail2ban unban 192.0.66.4
assert_output --partial "Unbanned IP from dovecot: 1" assert_output --partial "Unbanned IP from dovecot: 1"
run ./setup.sh -c mail_fail2ban debug fail2ban run ./setup.sh -c mail_fail2ban fail2ban
assert_output --regexp "^Banned in dovecot:.*192.0.66.5.*" assert_output --regexp "^Banned in dovecot:.*192\.0\.66\.5"
run ./setup.sh -c mail_fail2ban debug fail2ban unban 192.0.66.5 run ./setup.sh -c mail_fail2ban fail2ban unban 192.0.66.5
assert_output --partial "Unbanned IP from dovecot: 1" assert_output --partial "Unbanned IP from dovecot: 1"
run ./setup.sh -c mail_fail2ban debug fail2ban unban run ./setup.sh -c mail_fail2ban fail2ban unban
assert_output --partial "You need to specify an IP address: Run" assert_output --partial "You need to specify an IP address: Run"
} }