diff --git a/ENVIRONMENT.md b/ENVIRONMENT.md index ba949513..a3db7087 100644 --- a/ENVIRONMENT.md +++ b/ENVIRONMENT.md @@ -63,6 +63,12 @@ cap_add: Otherwise, `iptables` won't be able to ban IPs. +##### FAIL2BAN_BLOCKTYPE + +- **drop** => drop packet (send NO reply) +- reject => reject packet (send ICMP unreachable) +FAIL2BAN_BLOCKTYPE=drop + ##### SMTP_ONLY - **empty** => all daemons start diff --git a/config/fail2ban-jail.cf b/config/fail2ban-jail.cf index 46b987f7..ce162dcf 100644 --- a/config/fail2ban-jail.cf +++ b/config/fail2ban-jail.cf @@ -9,3 +9,8 @@ # "maxretry" is the number of failures before a host get banned. #maxretry = 5 + +# Default ban action +# iptables-multiport: block IP only on affected port +# iptables-allports: block IP on all ports +#banaction = iptables-allports diff --git a/mailserver.env b/mailserver.env index c8103663..0d3c0423 100644 --- a/mailserver.env +++ b/mailserver.env @@ -75,6 +75,11 @@ ENABLE_AMAVIS=1 # Otherwise, `iptables` won't be able to ban IPs. ENABLE_FAIL2BAN=0 +# Fail2Ban blocktype +# drop => drop packet (send NO reply) +# reject => reject packet (send ICMP unreachable) +FAIL2BAN_BLOCKTYPE=drop + # 1 => Enables Managesieve on port 4190 # empty => disables Managesieve ENABLE_MANAGESIEVE= diff --git a/target/fail2ban/jail.local b/target/fail2ban/jail.local index 73fa7c43..496b7581 100644 --- a/target/fail2ban/jail.local +++ b/target/fail2ban/jail.local @@ -15,6 +15,11 @@ maxretry = 3 # can be defined using space (and/or comma) separator. ignoreip = 127.0.0.1/8 +# Default ban action +# iptables-multiport: block IP only on affected port +# iptables-allports: block IP on all ports +banaction = iptables-allports + [dovecot] enabled = true diff --git a/target/scripts/start-mailserver.sh b/target/scripts/start-mailserver.sh index a3b3d8f0..e23c0820 100755 --- a/target/scripts/start-mailserver.sh +++ b/target/scripts/start-mailserver.sh @@ -32,6 +32,7 @@ VARS[ENABLE_QUOTAS]="${ENABLE_QUOTAS:=1}" VARS[ENABLE_SASLAUTHD]="${ENABLE_SASLAUTHD:=0}" VARS[ENABLE_SPAMASSASSIN]="${ENABLE_SPAMASSASSIN:=0}" VARS[ENABLE_SRS]="${ENABLE_SRS:=0}" +VARS[FAIL2BAN_BLOCKTYPE]="${FAIL2BAN_BLOCKTYPE:=drop}" VARS[FETCHMAIL_POLL]="${FETCHMAIL_POLL:=300}" VARS[FETCHMAIL_PARALLEL]="${FETCHMAIL_PARALLEL:=0}" VARS[LDAP_START_TLS]="${LDAP_START_TLS:=no}" @@ -103,6 +104,7 @@ function register_functions [[ ${ENABLE_POSTGREY} -eq 1 ]] && _register_setup_function '_setup_postgrey' [[ ${ENABLE_SASLAUTHD} -eq 1 ]] && _register_setup_function '_setup_saslauthd' [[ ${POSTFIX_INET_PROTOCOLS} != 'all' ]] && _register_setup_function '_setup_inet_protocols' + [[ ${ENABLE_FAIL2BAN} -eq 1 ]] && _register_setup_function '_setup_fail2ban' _register_setup_function '_setup_dkim' _register_setup_function '_setup_ssl' diff --git a/target/scripts/startup/setup-stack.sh b/target/scripts/startup/setup-stack.sh index b48c5c34..28dbf454 100644 --- a/target/scripts/startup/setup-stack.sh +++ b/target/scripts/startup/setup-stack.sh @@ -1619,3 +1619,12 @@ function _setup_environment echo "VIRUSMAILS_DELETE_DELAY=${VIRUSMAILS_DELETE_DELAY}" >>/etc/environment fi } + +function _setup_fail2ban +{ + _notify 'task' 'Setting up fail2ban' + if [[ ${FAIL2BAN_BLOCKTYPE} != "reject" ]] + then + echo -e "[Init]\nblocktype = DROP" > /etc/fail2ban/action.d/iptables-common.local + fi +} diff --git a/test/config/fail2ban-jail.cf b/test/config/fail2ban-jail.cf index eee1f8ff..3ac4dd98 100644 --- a/test/config/fail2ban-jail.cf +++ b/test/config/fail2ban-jail.cf @@ -9,3 +9,8 @@ findtime = 321 # "maxretry" is the number of failures before a host get banned. maxretry = 2 + +# Default ban action +# iptables-multiport: block IP only on affected port +# iptables-allports: block IP on all ports +banaction = iptables-multiport diff --git a/test/mail_fail2ban.bats b/test/mail_fail2ban.bats index 1b29e36f..3a41b6be 100644 --- a/test/mail_fail2ban.bats +++ b/test/mail_fail2ban.bats @@ -75,6 +75,15 @@ function teardown_file() { run docker exec mail_fail2ban /bin/sh -c "fail2ban-client get ${FILTER} maxretry" assert_output 2 + + run docker exec mail_fail2ban /bin/sh -c "fail2ban-client -d | grep -F \"['set', 'dovecot', 'addaction', 'iptables-multiport']\"" + assert_output "['set', 'dovecot', 'addaction', 'iptables-multiport']" + + run docker exec mail_fail2ban /bin/sh -c "fail2ban-client -d | grep -F \"['set', 'postfix', 'addaction', 'iptables-multiport']\"" + assert_output "['set', 'postfix', 'addaction', 'iptables-multiport']" + + run docker exec mail_fail2ban /bin/sh -c "fail2ban-client -d | grep -F \"['set', 'postfix-sasl', 'addaction', 'iptables-multiport']\"" + assert_output "['set', 'postfix-sasl', 'addaction', 'iptables-multiport']" done } @@ -99,9 +108,9 @@ function teardown_file() { run docker exec mail_fail2ban /bin/sh -c "fail2ban-client status postfix-sasl | grep '${FAIL_AUTH_MAILER_IP}'" assert_success - # Checking that FAIL_AUTH_MAILER_IP is banned by iptables - run docker exec mail_fail2ban /bin/sh -c "iptables -L f2b-postfix-sasl -n | grep REJECT | grep '${FAIL_AUTH_MAILER_IP}'" - assert_success + # Checking that FAIL_AUTH_MAILER_IP is banned by iptables and blocktype set to DROP + run docker exec mail_fail2ban /bin/sh -c "iptables -n -L f2b-postfix-sasl" + assert_output --regexp "DROP.+all.+${FAIL_AUTH_MAILER_IP}" } @test "checking fail2ban: unban ip works" { @@ -135,6 +144,7 @@ function teardown_file() { run ./setup.sh -c mail_fail2ban debug fail2ban assert_output --regexp "^Banned in dovecot: 192.0.66.5.*" run ./setup.sh -c mail_fail2ban debug fail2ban unban 192.0.66.5 + assert_output --partial "Unbanned IP from dovecot: 192.0.66.5" run ./setup.sh -c mail_fail2ban debug fail2ban unban assert_output --partial "You need to specify an IP address. Run" }