Be conservative with hosts.deny, hosts.allow
With any new system, do this
/etc/hosts.deny ALL: ALL
That takes precedence, so only people you want in, or services you want offered, can actually get through. Not all services check hosts.deny, but many do (especially the important ones like http, ssh, smb, smtp), including the web server and ssh. So, if some user gets through the outer firewall, the services will still be refused unless we have made provision for them in hosts.allow.
Edit the hosts.allow file to let people in. I typically put my own IP in there, plus some services I like, such as ssh. The 129.237. line refers to the KU internet numbers, so nobody from another place can use my stuff.
/etc/hosts.allow ALL: 127.0.0.1 ALL: my.ip.number.here sshd, sshdfwd-X11: localhost sshd, sshdfwd-X11: 129.237.
Turn on the Firewall
Make sure the firewall is turned on. On recent RedHat/Fedora, there is system-config-firewall, but plenty of addon firewall config tools exist. On Ubuntu, the firewall is not turned on by default because they assume the user won't turn on any services (or that somebody who turns on services without the firewall deserves what he gets). Install & run "ufw" or "firestarter" or such.
Shut off Undesired Services
Make sure telnet and finger services are not running, or remove them.
Turn off/remove nfs server
Turn off/remove anonymous ftp. In fact, turn off any ftp server.
Turn off (don't uninstall) sendmail service. You still need the sendmail program to send emails sometimes, but you don't need to run the service.
Tighten up the SSH Service
You DO have to run ssh, or else you have no way to log into your system remotely. But we can protect against many types of attacks. Above, the "deny.hosts" approach is mentioned. That is something of a "last line" of defense. There are other blocks that can be put in place *before* that is reached. First, the firewall itself can weed out some requests, and then the ssh configuration can be set to thwart some of the worst abuses, and after that a "denyhosts" approach can monitor attackers and lock them out.
I found advice about securing the ssh server ».
Set the following options in the /etc/ssh/sshd_config configuration file.
Unless you require protocol 1, disable it. If you don't know whether you require it, you probably don't.
(or without-password, see below)
Over half of the intrusion attempts for SSH on my servers are lame password guesses for root, simply because they know the account exists. Better to login with your restricted account and use the sudo or su commands to elevate your permissions.
By default, login is allowed for all users. Unfortunately this will also apply to daemon accounts if incorrectly configured, and to the user who changed his password to 'hello'. Better to restrict access to trusted users like yourself.
For multiple usernames separate with spaces, or alternatively add the usernames to a group and use
There have been "brute force" attacks reported against ssh servers and many pages have appeared to suggest solutions. One solution is to be conservative in granting any access by carefully tailoring hosts.allow. If you can't do that, I'd suggest you consult some web pages about it.
The key there is to tighten up the /etc/ssh/sshd_config file to have (at least) these safeguards
Protocol 2 PermitRootLogin without-password PasswordAuthentication no ChallengeResponseAuthentication no ClientAliveInterval 60 ClientAliveCountMax 30
"without-password" means that the root user is NOT allowed to log in if he tries to manually enter a password, but it will allow the user to log in if a PGP private/public key pair is already installed to identify the user's computer. PGP is a whole other problem...
Try an Automatic Monitoring Framework to Block Hackers
There are separate programs that can be run to detect brute force attacks. I run a somewhat old-school program called "denyhosts" that on all of the systems I try to protect. It is usually pre-packaged for most Linux distributions, but it will not be pre-configured.
Here's how I like to set up denyhosts.
This file describes the names of the hosts which are allowed to use the local INET services, as decided by the '/usr/sbin/tcpd' server.
ALL: 127.0.0.1 ALL: POLS110.pols.ku.edu sshd : /etc/denyhosts.blocked : deny sshd: .ku.edu sshdfwd-X11: 129.237. vsftpd: 129.237. httpd: .ku.edu vsftpd: .ku.edu smb: 129.237.
3. create an empty file /etc/denyhosts.blocked, for example by running
$ touch /etc/denyhosts.blocked
There is one big down-side to denyhosts. Once somebody is blocked, it is *really tedious* to unblock that user. The last time I checked (2010-07-05), there was still no "point and shoot" method to remove blocked users, and some crapola was required.
On fedora-list, saw more info in using iptables to tighten up ssh access. Rick Stevens posted this message »
I have iptables rules that only allow ssh tries from our networks or machines I know of. To wit:
# Accept SSH from our networks... -A INPUT -s aaa.bbb.ccc.0/24 -p tcp -m tcp --dport 22 -j ACCEPT -A INPUT -s ddd.eee.fff.0/24 -p tcp -m tcp --dport 22 -j ACCEPT # Accept SSH from my machine at home... -A INPUT -s ggg.hhh.iii.jjj/32 -p tcp -m tcp --dport 22 -j ACCEPT (more rules...)
At the end, put in a blanket "don't allow SSH from anywhere else" rule:
# Block any ssh attempts from outside our network... -A INPUT -i eth0 -p tcp -m tcp --dport 22 --tcp-flags SYN,RST,ACK SYN -j REJECT --reject-with icmp-port-unreachable
If you must leave ssh open to the outside world, use a simple iptables ruleset to limit attempts:
# This rejects ssh attempts more than twice in 180 seconds... # First, mark attempts as part of the "sshattack" group... -A INPUT -p tcp --syn --dport 22 -m recent --name sshattack --set # Optional: Include this line if you want to log these attacks... -A INPUT -p tcp --syn --dport 22 -m recent --name sshattack --rcheck --seconds 180 --hitcount 2 -j LOG --log-prefix "SSH REJECT: " # Finally, reject the connection if more than one attempt is made in 180 seconds... -A INPUT -p tcp --syn --dport 22 -m recent --name sshattack --rcheck --seconds 180 --hitcount 2 -j REJECT --reject-with tcp-reset
If more than one ssh attempt is made in 180 seconds (three minutes) from a given IP address, this blocks that IP address for that duration. You get one try. If you fail, you must wait 3 minutes before you can try again.
Note that even a successful login is counted. If you log in and immediately log out, you still have to wait 3 minutes to get in again.
Change the "--hitcount 2" bits to "--hitcount 3" if you want to give yourself two tries to get in. You can also change the "--seconds 180" to "--seconds 300" to make the delay 5 minutes. The values I give above are enough to discourage most script kiddie attempts to get into your box.