Best Practice Decreasing the Number of Random Hosts Attacking your Public-facing Servers [duplicate]

I just checked my server's /var/log/auth.log and found that I'm getting over 500 failed password/break-in attempt notifications per day! My site is small, and its URL is obscure. Is this normal? Should I be taking any measures?


In today's internet this is quite normal sadly. There are hordes of botnets trying to login to each server they find in whole IP networks. Typically, they use simple dictionary attacks on well-known accounts (like root or certain applications accounts).

The attack targets are not found via Google or DNS entries, but the attackers just try every IP address in a certain subnet (e.g. of known root-server hosting companies). So it doesn't matter that your URL (hence the DNS entry) is rather obscure.

That's why it is so important to:

  • disallow root-login in SSH (howto)
  • use strong passwords everywhere (also in your web applications)
  • for SSH, use public-key authentication if possible and disable password-auth completely (howto)

Additionally, you can install fail2ban which will scan the authlog and if it finds a certain amount of failed login attempts from an IP, it will proceed to add that IP to /etc/hosts.deny or iptables/netfilter in order to lock out the attacker for a few minutes.

In addition to the SSH attacks, it is also becoming common to scan your webserver for vulnerable web-applications (some blogging apps, CMSs, phpmyadmin, etc.). So make sure to keep those up-to-date and securely configured too!


A few 100 is just fine... Last month I found one of my servers had 40k failed attempts. I went trough the trouble of plotting them: Map

Once I changed the ssh port and implemented Port Knocking, the number dropped to 0 :-)


I for one use a "tarpit" in addition to only allowing public key authentication and disallowing root logins.

In netfilter there is a recent module, which you can use with (INPUT chain):

iptables -A INPUT -i if0 -p tcp --dport 22 -m state --state NEW -m recent --set --name tarpit --rsource
iptables -A INPUT -i if0 -p tcp --dport 22 -m state --state NEW -m recent --update --seconds 180 --hitcount 6 --name tarpit --rsource -j DROP
iptables -A INPUT -i if0 -p tcp --dport 22 -j ACCEPT

What that does is, that every attempt to connect to port 22 is listed by the recent module with IP and some other stuff under the name "tarpit" (if you're curious, look at /proc/net/xt_recent/tarpit). Obviously you can use other names.

To list or delist IPs use:

echo "+123.123.123.123" > /proc/net/xt_recent/tarpit
echo "-123.123.123.123" > /proc/net/xt_recent/tarpit

This rate-limits the attempts to 5 in 300 seconds. Please note that users with an existing connection are not bothered by that limit, because they already have an established connection and are allowed to create more (even above the rate limit).

Adjust the rules to your liking but make sure that they be added in that order (i.e. when adding then use them in this order, when inserting then in the reverse order).

This cuts down the noise immensely. It also provides actual security (against brute-forcing) unlike the perceived security of changing the port. However, I'd still recommend changing the port if it's feasible in your environment. It will cut down the noise level a lot as well ...

You can still combine this with fail2ban, although I've been running just fine without it and only the above rules.

EDIT:

It is possible to lock your self out doing this, so you can add something like the following that lets you clear you ban by knocking on a particular port:

iptables -A INPUT -i if0 -p tcp --dport <knockport> -m state --state NEW -m recent --name tarpit --remove

You could implement fail2ban, or similar methods like locking SSH to your IP. Sadly bots attempt to bruteforce access all the time so it is quite normal, you need to make sure you have a good password.