I have my passwords secure, but I heard people complaining about perfomance of a server going down drastically when a bruteforce attack is taking place. How can I secure my ubuntu 10.10 server from such attacks? Is there an apparmor profile for this? Or some other way to address it?
There are different solutions. The best one is using RSA authentication that uses public/private keys to authenticate users.
Check this great manual for different approaches (RSA authentication included): http://www.la-samhna.de/library/brutessh.html
I'm using the 3rd solution on my server because I don't want to make it complicated for my non-technical users: using
iptables to limit the number of connections per minute that makes bruteforce attacks inefficient and ineffective.
Here is the solution I'm using:
iptables -A INPUT -p tcp --dport 22 -m state --state NEW -m recent --set --name SSH -j ACCEPT iptables -A INPUT -p tcp --dport 22 -m recent --update --seconds 60 --hitcount 4 --rttl --name SSH -j LOG --log-prefix "SSH_brute_force " iptables -A INPUT -p tcp --dport 22 -m recent --update --seconds 60 --hitcount 4 --rttl --name SSH -j DROP
As mentioned here: this will allow three port 22 connections from any given IP address within a 60 second period, and require 60 seconds of no subsequent connection attempts before it will resume allowing connections again. The --rttl option also takes into account the TTL of the datagram when matching packets, so as to endeavour to mitigate against spoofed source addresses.
As stated in the mentioned guide, it's better to use a white list to separate trusted users from these rules:
iptables -N SSH_WHITELIST
then add trusted hosts:
iptables -A SSH_WHITELIST -s $TRUSTED_HOST -m recent --remove --name SSH -j ACCEPT
and after that make the rules:
iptables -A INPUT -p tcp --dport 22 -m state --state NEW -m recent --set --name SSH iptables -A INPUT -p tcp --dport 22 -m state --state NEW -j SSH_WHITELIST iptables -A INPUT -p tcp --dport 22 -m state --state NEW -m recent --update --seconds 60 --hitcount 4 --rttl --name SSH -j ULOG --ulog-prefix SSH_brute_force iptables -A INPUT -p tcp --dport 22 -m state --state NEW -m recent --update --seconds 60 --hitcount 4 --rttl --name SSH -j DROP
I get brute-force ssh attacks on my servers with a rate of 1 to 2 per day. I have installed denyhosts (ubuntu package: denyhosts). It's a very simple but effective tool for that purpose: essentially it periodically scans your logs to detect brute-force attacks and puts IPs from where these attacks originate into your /etc/hosts.deny file. You won't hear from them again and your load should be reduced considerably. It is very configurable via its config file /etc/denyhosts.conf to tweak issues like how many wrong attempts consitute an attack etc.
Due to its transparent workings you can easily see what's going on (email notification: 'aha, another dastardly attack thwarted!') and undo mistakes due to your users mistyping their passwords repeatedly .
Of course, everything previously said about switching to other authentication methods holds but sometimes your requirements disagree with those of your users.
Also, new-connection rate limiting in iptables might be a better choice then denying access via hosts.deny. So, have a look at fail2ban as well. But if you know that ssh brute-force is your main concern (manually look through /var/log/auth.log to determine this), go with this very easy and low impact tool.
- Change the sshd port to something nonstandard
knockdto implement a port-knocking system
- Use iptables'
hashlimitmatches to limit consecutive SSH attempts
- Do not use passwords, but use SSH keys instead
First of all you should consider not using passwords and use keys instead. There is no need to use a password. If this works for you, you can configure the OpenSSH-server not to react on password logins.
Using fail2ban, could be an option as well.
How widely is the server exposed on the network? Perhaps you can have a talk with the network admin and check if it's possible to monitor and restrict network access to the server. Even if the account logins are safe, it seems that the server could suffer from simple DoS / DDoS attack.
An alternative to fail2ban is CSF: ConfigServer Security & Firewall.
It comes with LFD: a Login Failure Daemon that can detect multiple failed login attempts on various services, and will block the offending IP address (temporarily or permanently).
It has some other options that can help against flood attacks, and possibly detect intrusions.
- You must use CSF as your firewall in order for LFD to do its job. So if you have an existing firewall, you will need to replace it with CSF, and port your configuration over.
- It is not packaged for Ubuntu. You will have to trust the auto-updates from configserver.com, or disable automatic updates.
- I have heard it is quite popular, so smart intruders will probably know how to disable intrusion detection before they are detected!
Do you intend to allow SSH service to the world? Or just to team members at particular places? My answer depends a bit on the severity of your challenge.
In either case, one thing you should do is make sure that the SSH server does not allow password logins for the root user.
- In /etc/ssh/sshd_config make sure you never allow a root login except with an SSH key.
In my systems, I've got this setting
but I notice in newer Ubuntu they have
If you read "man sshd_config" I think it means this newer "prohibit-password" means same thing and is certainly more obvious in meaning. That is NOT default on some Linux systems, but probably should be.
Now, about your problem. Does your system server only some users in particular places? Do this!
edit /etc/hosts.deny and insert
Then edit /etc/hosts.allow and list IP numbers or a range that want to allow to use SSH. The notation there is a little confusing because if you want to allow all systems with IP numbers like 126.96.36.199 through 188.8.131.52, you put in an entry like this in hosts.allow
ALL: 127.0.0.1 sshd: 111.222.65. sshdfwd-X11: 111.222.65.
That is a bruteforce, powerful solution. If your users can be enumerated by IP range, do it!
This solution existed before IP tables was created, it is (I think) a lot easier to administer, but it is not as good as an IP tables solution because IP tables routines will spot enemies sooner than the programs driven by hosts.allow and hosts.deny. But this is a sure fire, simple way to close out a lot of problems, not just from SSH.
Note the problem you create for yourself. If you want to open up an FTP server, web server, or whatnot, you will have to make entries in hosts allow.
You can achieve same basic purpose by fiddling with iptables and the firewall. In a sense, this is a preferred solution because you are blocking enemies at the outer boundary. Ubuntu has "ufw" (uncomplicated firewall) and "man ufw" has plenty of examples. I'd rather have a nice GUI to wade through this, I don't have to do this all the time. Maybe others can tell us if there is one now.
- Other posts here suggested using SSH public key only for your users. That will certainly help, at the price of complexity and frustration for your users. In our lab, there are 15 computers. Users go among computers. Requiring SSH key authentication would cause a big hassle because people go from one computer to the next.
Another source of frustration will happen when some users accumulate different ssh keys for various servers. Because I have SSH keys for about 12 different projects, now ssh fails because I have too many public keys (Requiring either "ssh -o PubkeyAuthentication=false" or creation of an entry in the .ssh/config file. It is a PITA)
- If you must leave the server open to SSH from the big wide world, then definitely you should use a rejection routine to block locations that frequently try to log in. There are 2 nice programs for this, the ones we have used are denyhosts and fail2ban. These programs have settings that allow you to ban offenders, for a duration you like.
In our Centos Linux systems, I noticed they dropped the denyhosts package and only offer fail2ban. I liked denyhosts because it built up a list of troublesome users/ip ranges and then in hosts.deny, that list was noted. We installed fail2ban instead and it is OK. My understanding is that you'd rather block these bad users at the outer edge of the server, so the ip tables based blockers, like fail2ban, are actually better. Denyhosts works on the secondary level, after enemies have gotten past iptables they are then rejected by the sshd daemon.
In both of these programs, it is a bit tedious to get users out of jail if they forget their password and try a few times to log in. It is a bit difficult to get people back in when they make login mistakes. You'd have guessed there would be a point-and-click GUI where you could just point and let people back in, but it is not that way. I only have to do this every few months and forget how between times, so I wrote instructions for myself on my web page http://pj.freefaculty.org/blog/?p=301