Every night I get hundreds, sometimes thousands, of failed ssh logins on my RedHat 4 server. For firewall reasons from remote sites, I need to run on the standard port. Is there anything I should be doing to block this. I notice that many come from the same IP address. Shouldn't it be stopping those after a while?
You can use iptables to rate-limit new incoming connections to the SSH port. I'd have to see your entire iptables configuration in order to give you a turnkey solution, but you're basically talking about adding rules like:
These rules assume that you're accepting ESTABLISHED connections earlier in the table (so that only new connections will hit these rules). New SSH connections will hit these rules and be marked. In 60 seconds, 5 attempts from a single IP address will result in new incoming connections from that IP being dropped.
This has worked well for me.
Edit: I prefer this method to "fail2ban" because no additional software to be installed, and happens totally in kernel-mode. It doesn't handle parsing log files like "fail2ban" will, but if your problem is only with SSH I wouldn't use something user-mode that requires software installation and is more complex.
fail2ban can help with this by blocking IP addresses with too many failed log in attempts.
I'd recommend using a non-standard port for SSH if you can (ie. port 10222) but since you mentioned you can't do that I'd recommend using something such as DenyHosts.
http://denyhosts.sourceforge.net/
Great package, easy to install and configure.
While it may be nice to be able to ssh into your system from arbitrary locations on the internet, there are automated password attack systems which will lock onto an open ssh port and apply various joe account and dictionary attacks against your system. This can be aggrevating to read in your nightly log summary and is a waste of your bandwidth.
If you have a web server on the same system, you can use php and tcp wrappers to restrict ssh inbound traffic to known systems, plus give you a back-door key to permit yourself access from arbitrary systems on the internet.
Here's how you do it:
deny all ssh connections in /etc/hosts.deny:
Allow known systems by IP in /etc/hosts.allow, plus add a file for temporary access:
Create a php file in your web server and give it a non-obvious name like my-sshd-access.php:
Forgive the php code -- I swiped it from somewhere else, so it could probably stand to be cleaned up a whole bunch. All it does is add the IP address of the system accessing it to the /etc/hosts.allow.temporary-sshd-access file, which is read by sshd (due to its inclusion by /etc/hosts.allow) at connection time.
Now when you are at some arbitrary system on the web and want to ssh to this system, first use a web browser and hit this file (or use wget or equivilent):
Now you should be able to ssh in to your system. If this is somewhere you will likely be ssh'ing in from frequently, it would be trivial to read the contents of the /etc/hosts.allow.temporary-sshd-access file and permanently add the IP address to /etc/hosts.allow.
You may want to look at denyhosts as well.
FYI: OpenSSH 6.7 drops tcpwrappers support, meaning denyhosts probably isn't the solution for new installations.
Do yourself a favor and disable the password login. Use exclusively authentication keys (google ssh-keygen for instance - Example: http://www.puddingonline.com/~dave/publications/SSH-with-Keys-HOWTO/document/html/SSH-with-Keys-HOWTO-4.html ) Your server will be more secure, you will connect to it more comfortably (check ssh-agent, ssh-add, keychain) and you will be no more the victim of ssh brute force attacks.
another solution is just move ssh to another port. these worms are pretty stupid.
Another option might be to require all ssh connections be verified by a certificate and do away with passwords altogether.
I use to use Denyhosts, but I found I was only connecting regularly remotely from a handful of places, so I blocked all port 22 connections except from anywhere else, and use port knocking so I can connect from anywhere with my laptop if I have to.
Any solution which involves automatically blocking IPs after multiple failures introduces risk of denial of service attacks. As long as there's a good password policy in place to reduce the effectiveness of brute force or dictionary attacks, I wouldn't worry too much about them.
If you limit the users/groups to only those who should be allowed to ssh in in the first place, and disable logging in as root, you should be more than secure enough. And, if that's not sufficient, there's always key-based authentication.
Honestly, if you have to run SSH (and on port 22), you can't avoid these. If you must accept passwords, you're in even worse shape.
Your best bet is to configure your log analysis software to exclude the SSH logs. Then run a separate instance to only look at SSH logs, and use procmail to filter out the unsuccessful attempts. You might even write scripts to watch for successful logins from IP addresses with multiple unsuccessful attempts.
There's no way to stop people from probing your SSH server. Denyhosts, fail2ban, and the iptables example will work up to a point, but with the additional danger of accidentally blocking legitimate users. The best method is to suck it up and try to automate the log-analysis process to reduce the amount of time you have to think about it.