Securing my server from spammers and bots
In the last few weeks I've been getting hammered by spam directed toward my private, self-hosted email address; typically every 30 minutes I would receive some... well, strange emails, often trying to sell me a product or were just plain strange. Unfortunately this address was part of a LinkedIn data leak spammers had managed to get a hold of.
After observing my mail logs, I noticed the spammer(s) sending me these emails wasn't the only one trying to cause trouble: there were quite a few bots using SASL attacks to attempt to login. ssh logs were much, much worse. Finally, I decided I was going to go to war against bots trying to gain unauthorized access to my Ubuntu server.
Installing ipset
iptables is most likely suitable for small servers trying to IP ban spammer and bots. While this is optional, ipset is a more appropriate option when performance is important. Install it:
1 sudo
apt-get
install
ipset
As an additional optional task, you can make ipset entries persist across reboots using ipset-persistent
.
Installing fail2ban
fail2ban (f2b) is a piece of software that monitors log files and looks for suspicious activity. f2b has what are called filters and actions: filters are regular expressions that get evaluated for each log line and are used to match on suspicious activity (e.g. you might want to match for failed password attempts if you're monitoring ssh logs); and actions are what f2b should do when a ban is to happen. A jail in f2b is a combination of a filter and one or several actions. You can configure a jail for any app on your server. Many default jails are provided in jail.conf, but you can override their behavior in a local jail config.
To install fail2ban:
1 sudo
apt-get
install
fail2ban
f2b comes with presets for popular apps such as ssh. Adding a jail for it to /etc/fail2ban/jail.local:
12345678910 [sshd]
enabled = true
mode = aggressive
filter = sshd
logpath = /var/log/auth.log
maxretry = 5
findtime = 300
bantime = 1h
banaction = iptables-ipset-proto6
ignoreip = 127.0.0.1
A few things to point out:
- We enable the sshd jail with
enabled = true
- While optional in this case (the sshd jail already sets the filter name in jail.conf), you can specify which filter should be applied by specifying the filter name. For example, if sshd is the filter name, there should be a matching config file in /etc/fail2ban/filter.d/sshd.conf.
logpath
is a path to the log file to monitor.maxretry
is the number of matches (e.g. a failed password attempt) to allow before deciding to ban.findtime
is a time unit which specifies how many retries within the time given to allow. In this case, if there are more than 5 retries in a 5 minute span (300 seconds = 5 minutes), then f2b executes a ban.bantime
is a time unit specifying how long the ban should be in effect for.banaction
is what should happen when a ban is executed.iptables-ipset-proto6
is the name of an action (which should exist at /etc/fail2ban/action.d/iptables-ipset-proto6.conf), and comes with a default installation of f2b. This ban action adds the IP of the offending machine to an ipset and if not already done so, adds a line to iptables which creates a REJECT rule for any IPs which match in the ipset.
Here's an example of a log line that would match f2b's fail regex:
1 Sep 25 20:48:16 anthony-calandra sshd[3527]: Failed password for invalid user foo from 203.121.116.9 port 55036 ssh2
Here's an example of a SASL attack that f2b would match (line 2, specifically):
1234 Sep 25 20:21:24 anthony-calandra postfix/smtps/smtpd[2317]: connect from unknown[194.61.24.152]
Sep 25 20:21:31 anthony-calandra postfix/smtps/smtpd[2317]: warning: unknown[194.61.24.152]: SASL PLAIN authentication failed:
Sep 25 20:21:31 anthony-calandra postfix/smtps/smtpd[2317]: lost connection after AUTH from unknown[194.61.24.152]
Sep 25 20:21:31 anthony-calandra postfix/smtps/smtpd[2317]: disconnect from unknown[194.61.24.152] ehlo=1 auth=0/1 commands=1/2
I also have jails for long-term attacks: bots which don't ever leave my server alone.
Adjusting my mail server to more aggressively reject suspicious email
I found that the default postfix configuration wasn't very aggressive against rejecting suspicious mail. So after looking around on the internet for some settings to enable, I settled on the following.
/etc/postfix/main.cf
1234567891011121314151617181920212223242526272829 smtpd_delay_reject = yes
strict_rfc821_envelopes = yes
disable_vrfy_command = yes
smtpd_helo_required = yes
smtpd_relay_restrictions =
permit_mynetworks
permit_sasl_authenticated
defer_unauth_destination
smtpd_sender_restrictions =
permit_mynetworks
permit_sasl_authenticated
reject_unknown_sender_domain
reject_non_fqdn_sender
smtpd_recipient_restrictions =
permit_mynetworks
permit_sasl_authenticated
reject_unauth_destination
reject_invalid_helo_hostname
warn_if_reject reject_non_fqdn_helo_hostname
warn_if_reject reject_unknown_helo_hostname
warn_if_reject reject_unknown_reverse_client_hostname
warn_if_reject reject_unknown_client_hostname
reject_non_fqdn_sender
reject_non_fqdn_recipient
reject_unknown_sender_domain
reject_unknown_recipient_domain
Once this configuration is saved, reload postfix:
1 sudo
systemctl reload postfix
These simple changes rejecting about 80% of the spam I was receiving daily.
Installing spamassassin
This is still a work in progress, as I've been noticing the default rules are not effective at all against the spam I've been receiving.
TODO
Tags: bot, spam, email, postfix, dovecot, iptables, ipset, fail2ban, spamassassin, ubuntu, linux