Post

Overview Mail Server Hardening

Overview Mail Server Hardening

Overview

This is an overview on basic hardening and is not a complete guide.


1. Scope and Goals

  • Protect SSH, SMTP, SMTP AUTH, IMAP/POP3, and web authentication services
  • Enforce network-level blocking using nftables
  • Report high-confidence abuse to AbuseIPDB
  • Maintain performance and avoid false positives
  • Provide repeatable, documented configuration

2. System Overview

  • OS: Debian 13
  • Mail stack: Postfix, Dovecot, Rspamd
  • Web: Apache
  • Firewall: nftables,ufw
  • Log backend: systemd journal
  • Abuse reporting: AbuseIPDB

3. Fail2Ban Configuration Layout

Main files

1
2
/etc/fail2ban/jail.conf
/etc/fail2ban/jail.local

Per-jail directory

1
/etc/fail2ban/jail.d/

Enabled jails:

  • sshd (auto-enabled on Debian 13)
  • apache-auth
  • postfix
  • postfix-sasl
  • dovecot

4. Debian 13 SSH Behavior

On Debian 13, the sshd jail is enabled automatically and defined in:

1
/etc/fail2ban/jail.local

Recommended override:

1
2
3
[sshd]
maxretry = 3
bantime  = 12h

5. Apache Authentication Jail

1
2
3
4
5
6
7
8
9
10
11
12
[apache-auth]
enabled = true
backend = systemd

findtime = 3m
maxretry = 5
bantime  = 10m

journalmatch = _SYSTEMD_UNIT=apache2.service

action = %(action_mw)s
         %(action_abuseipdb)s[abuseipdb_category="18"]

6. Postfix (SMTP)

1
2
3
4
5
6
7
8
9
10
11
12
[postfix]
enabled = true
backend = systemd

findtime = 10m
maxretry = 3
bantime  = 1h

journalmatch = _SYSTEMD_UNIT=postfix.service

action = %(action_mw)s
         %(action_abuseipdb)s[abuseipdb_category="22"]

7. Postfix SASL

1
2
3
4
5
6
7
8
9
10
11
12
[postfix-sasl]
enabled = true
backend = systemd

findtime = 10m
maxretry = 3
bantime  = 4h

journalmatch = _SYSTEMD_UNIT=postfix.service

action = %(action_mw)s
         %(action_abuseipdb)s[abuseipdb_category="18"]

8. Dovecot

1
2
3
4
5
6
7
8
9
10
11
12
[dovecot]
enabled = true
backend = systemd

findtime = 10m
maxretry = 4
bantime  = 2h

journalmatch = _SYSTEMD_UNIT=dovecot.service

action = %(action_mw)s
         %(action_abuseipdb)s[abuseipdb_category="18"]

9. AbuseIPDB

Global config:

1
/etc/fail2ban/action.d/abuseipdb.conf
1
2
abuseipdb_apikey   = <REDACTED>
abuseipdb_category = 18

Verify:

1
fail2ban-client -d | grep abuseipdb

10. Rspamd Integration

Rspamd handles content scoring. Fail2Ban handles persistent abusive behavior.

Rspamd is the judge. Fail2Ban is the bouncer.


11. Logging

Fail2Ban:

1
/var/log/fail2ban.log

Rspamd:

1
/var/log/rspamd/rspamd.log

12. Cheat Sheet

Restart:

1
systemctl restart fail2ban

Status:

1
fail2ban-client status

Ban/unban:

1
2
fail2ban-client set sshd banip 1.2.3.4
fail2ban-client set sshd unbanip 1.2.3.4

13. Optional Hardening

Recidive

1
2
3
4
5
6
[recidive]
enabled = true
logpath = /var/log/fail2ban.log
findtime = 1d
maxretry = 5
bantime  = 7d

14. Philosophy

  • Fewer, higher-confidence bans
  • Avoid spam-only IP reporting
  • Tune by service risk
  • Document known-good states
This post is licensed under CC BY 4.0 by the author.