Secure SSH

Posted by ashwoods on Mon 30 Oct 2006 at 15:52

SSH is not only the secure replacement for rlogin, rsh and telnet, which has been used in the past to do remote administration work, but there are also neat tricks like port forwarding, vpn tunneling and file transfers that you can do with minimal configuration work, leaving only one port open to the internets.

If you keep your SSH server up to date and choose your passwords wisely, you can sleep well at night without worrying about all those script kiddies and bots scanning your ports and attacking your SSH server with brute force or dictionary attacks.

You will however see constant attacks in your logs like these:

Oct 20 16:03:51 server02 sshd[26405]: Illegal user ftpuser from ::ffff:81.56.195.220
Oct 20 16:03:52 server02 sshd[26407]: Illegal user ftpuser from ::ffff:81.56.195.220
Oct 20 16:03:53 server02 sshd[26409]: Illegal user ftpuser from ::ffff:81.56.195.220
Oct 20 16:03:54 server02 sshd[26411]: Illegal user ftpuser from ::ffff:81.56.195.220
Oct 20 16:03:56 server02 sshd[26413]: Illegal user ftpuser from ::ffff:81.56.195.220

This doesn't mean a hacker is trying to break in using some SSH exploit, these are normally automated attempts from zombie bots or script kiddies with dictionary attacks to break into your system, sometimes using virus infested machines to do the work. You can get hundreds of attempts every day, and this might make you feel a little bit uneasy.

Even if SSH is very secure out of the box, there are several things you can do to make it more secure and avoid all those emails logs full of bot attacks, without having to configure a full blown IDS system. The following tips apply to OpenSSH on a debian system, but should be very similar in other systems.

How you secure SSH will depend on your specific needs, so the first step is to consider your current use of SSH. Are you a roadwarrior and connecting to your servers from different computers or IP addresses, do all the users of the system really need SSH?

It is better to make the changes locally, as you might lock yourself out while reconfiguring your network.

Step 1 : Secure the default SSH configuration.

You can find more detailed information on debiansec or OpenSSH, this basic steps are:

a) Don't allow root to remote login

PermitRootLogin no

It is safer to login as another user and use su.

b) Limit the users or groups that can login in remotely.

AllowUsers me
AllowGroups mygroup
DenyUsers paul
DenyGroups paulsgroup

Unless you are a ISP you can normally limit the users that can login to a few. You can also limit your users to certain machines or hosts.
c) Allow only Protocol 2:

Protocol 2

Protocol 1 is less secure and obsolete.

d) Use PubkeyAuthentication authentication instead of passwords:

PubkeyAuthenticationPasswordAuthentication No
ChallengeResponseAuthentication no

Instead of using a password to login, a keypair is placed on the server and the client. The client can prompt for a paraphrase, but no password is sent over the network. If you connect from several computers, you have to have the key on each one or carry it around in a USB stick. Howto configure.

e) Change the default port 22 to something higher

Port 2899

I consider this security by obscurity. This makes it only one step "harder" for a determined hacker (all he has to do is scan your ports), but it does help with most automated bot attacks, most scripts check only for port 22 because scanning ports is time consuming. This trick alone will empty most of your logs of attack junk.

f) don't listen on all addresses if posible:

ListenAddress 192.168.1.5

Step 2: Re-configure your firewall - block those connections in the first place
There are several ways of doing this. The easiest way is to limit connections to certain IP's or subnets. This may not be practical if you are constantly on the road and need SSH access, more complex set ups like port knocking are also possible.

a) configure your firewall to allow only certain IP's (or subnets) if posible.

b) install some nice brute force attack detectors - there are several packages that can detect a brute force attack and block those IP's automatically.

On debian I use the aptable denyhosts python script, that automatically blocks ssh brute-force attacks by adding entries to /etc/hosts.deny. You do have to check if you are not blocking legitimate IP's, attacks can be spoofed or come from an innocent virus infested machine.

Other similar programs update your iptables configuration, like apf + bfd, that scan your log files for breakin attempts and create automatic rules blocking the IP of the attacker.

Step 3: Extra security - One time passwords and port knocking

The steps mentioned above will clear up your logs and make your system more secure. But there are certain scenarios that could benefit from some extra security work. If you have many users that must have access from anywhere in the world (including unsecured computers), and having them carry their key in a USB stick is not practical, you can make them use one time passwords, libpam-opie:

Use OPIE one time passwords for PAM authentication. A one time password is useful to avoid having your password sniffed and reused if you log in via an unencrypted channel or from a compromised system. The PAM module enables OPIE for programs such as SSH which use PAM for authentication.

Sounds interesting, but I have never set this up myself, and even if OPIE passwords are really good against keyloggers, I prefer using key-host based authentication.

Another very interesting concept is Port Knocking:

port knocking is a method of externally opening ports on a firewall by generating a connection attempt on a set of prespecified closed ports. Once a correct sequence of connection attempts is received the firewall rules are dynamically modified to allow the host which sent the connection attempts to connect over specified port(s)

In other words, your SSH port is closed, until you send a specific secret combination of packets. So even a hacker would have a hard time finding your SSH port in the first place.

Here is a list of several port knocking implementations, and a here's a shorewall config.

Some extra advice!

This advice concerns linux security in general, most people are lazy so I will repeat them.

Enforce good passwords: install libpam_cracklib: a PAM module that tests passwords to make sure they are not too weak during password change.

Read your logs! Install logcheck and/or logrotate to make your log reading life easier.

Keep your system up-to-date!
For non-critical debian systems you can use something like unattended-upgrades to keep the security packages updates automatic.

There are several packages that can improve security with little effort: tiger, harden, bastille and a firewall of choice.

**** Disclaimer: Do I really need this? I am not an expert, so read all the docs anyways.***
Am I missing anything?

**** This is a copy of article I wrote for my blog, and posted it here because of its usefulness. For "current versions" (if i ever have to update it) will be here: http://www.xthought.org/blog/2006/secure-ssh ****
cheers, ashley

 

 


Posted by wuzzeb (64.5.xx.xx) on Mon 30 Oct 2006 at 18:10
Another thing to do is something like this... I use it instead of denying based on hosts.deny and such

iptables -A INPUT -i eth0 -p tcp --dport ssh -m state --state NEW \
-m recent --set --name recentssh
iptables -A INPUT -i eth0 -p tcp --dport ssh -m state --state NEW \
-m recent --name recentssh --update --seconds 120 --hitcount 4 -j DROP
iptables -A INPUT -j ACCEPT -i eth0 -p tcp --destination-port ssh

<drop new connections in input>

It only allows 4 logins per 2 minutes per address. Then if you look in the log, every script only trys to log in with admin, adam, ... (4 names that start with a), and as long as you don't have any of those... works for a smaller server I admin.

[ Parent | Reply to this comment ]

Posted by ajt (84.12.xx.xx) on Mon 30 Oct 2006 at 21:23
[ View Weblogs ]
I've tried this, but after a while in Sarge it blocks all inbound SSH attempts. I don't know if it's a bug in the kernel, iptables, or something stupid I did in my SSH rules. I'll have to give it ago again, I think it's a neat way of controlling things if I can get it to behave.

http://www.debian-administration.org/articles/187

--
"It's Not Magic, It's Work"
Adam

[ Parent | Reply to this comment ]

Posted by Anonymous (213.164.xx.xx) on Mon 30 Oct 2006 at 21:38
Are you saying that your problem is that instead of blocking a specific ip address from accessing ssh for a given time, it blocks *all* ssh access for a given time?

[ Parent | Reply to this comment ]

Posted by ajt (84.12.xx.xx) on Mon 30 Oct 2006 at 21:58
[ View Weblogs ]
It seems to be that way. If I reboot the kernel it's okay for a few days or a week or so, then it falls over in a pickle. I added a line to log requests, and it looks like when it's "not working" a single legitimage inbound SSH request generates a stream of "hits" which, trips the hit counter.

I'll have to try it out again one weekened, to see if I can figure out what is going on.

--
"It's Not Magic, It's Work"
Adam

[ Parent | Reply to this comment ]

Posted by ComradeP (163.1.xx.xx) on Tue 31 Oct 2006 at 11:12
Here's the two iptables lines that Work For Me (tm):

$ cat /root/bin/limit_ssh
#!/bin/sh
/sbin/iptables -I INPUT -p tcp --dport 22 -m state --state NEW -m recent \
  --set

/sbin/iptables -I INPUT -p tcp --dport 22 -m state --state NEW -m recent \
  --update --seconds 60 --hitcount 4 -j DROP

(this allows 4 connections in 1 minute, rather than 2, but obviously you can play with the --seconds value.)

This, and a crontab line like this:

# crontab -l
# m h  dom mon dow   command
@reboot /root/bin/limit_ssh

... is in my experience sufficient to block practically all brute force attacks.

After installing the rules, to test they're working try something like this:

$ for f in `seq 5` ; do echo $f ; echo Hello | nc localhost 22 ; done
1
SSH-2.0-OpenSSH_4.3p2 Debian-3
Protocol mismatch.
2
SSH-2.0-OpenSSH_4.3p2 Debian-3
Protocol mismatch.
3
SSH-2.0-OpenSSH_4.3p2 Debian-3
Protocol mismatch.
4
SSH-2.0-OpenSSH_4.3p2 Debian-3
Protocol mismatch.
5


^^ observe that it should just silently hang at the 5th connection attempt. After one minute, you should be able to ssh into localhost again.

[ Parent | Reply to this comment ]

Posted by d1663m (63.93.xx.xx) on Fri 3 Nov 2006 at 22:55
I set this up just yesterday. I have so far caught two attempts. One was denied because they were trying to login as root. Only four attempts were made (thanks to the filter). Then today another was caught and denied after four attempts.

VERY nice.

[ Parent | Reply to this comment ]

Posted by marki (89.173.xx.xx) on Mon 30 Oct 2006 at 22:26
I noticed similar behaviour... I'm not sure if it was blocking all IPs, but at least some of them. Fortunately I have explicitly allowed connection from another server.

[ Parent | Reply to this comment ]

Posted by thoger (62.168.xx.xx) on Tue 31 Oct 2006 at 12:37
Can be related to well known problem with ipt_recent. It's mentioned in one of the comments for article you linked:

http://www.debian-administration.org/articles/187#comment_40

[ Parent | Reply to this comment ]

Posted by ajt (204.193.xx.xx) on Tue 31 Oct 2006 at 13:15
[ View Weblogs ]
I think you are correct, it seems to describe exactly the problem I'm having on my Debian Sarge (2.6.8-3-686) box.

http://blog.blackdown.de/2005/05/09/fixing-the-ipt_recent-netfilt er-module/

--
"It's Not Magic, It's Work"
Adam

[ Parent | Reply to this comment ]

Posted by ashwoods (213.47.xx.xx) on Wed 1 Nov 2006 at 21:05
that is one of the reasons i normally recommend setups like using denyhosts (or similar programs) where you don't have to touch iptables config too much ;)

btw, does anybody know of a resource for blacklists to block IPs geographically?

[ Parent | Reply to this comment ]

Posted by sytoka (213.103.xx.xx) on Sat 9 Dec 2006 at 07:24
I use another way because i had also some problem with recent module. I just estimate the number of connection per minute i accept and limit to this number.

 iptable -A INPUT  -i eth0 -p tcp --dport 22 -m state --state NEW \
                   -m limit --limit 3/min --limit-burst 3 -j ACCEPT
 iptable -A INPUT  -i eth0 -p tcp --dport 22 -m state \
                   --state ESTABLISHED -j ACCEPT
 iptable -A OUTPUT -o eth0 -p tcp --sport 22 -m state 
                   --state ESTABLISHED -j ACCEPT


It is very simple, fast and works great on many services.

[ Parent | Reply to this comment ]

Posted by ajt (84.12.xx.xx) on Sat 9 Dec 2006 at 10:22
[ View Weblogs ]
Thanks for the suggestion, I'll have to give that a go.

--
"It's Not Magic, It's Work"
Adam

[ Parent | Reply to this comment ]

Posted by johny_kedd (194.157.xx.xx) on Wed 31 Jul 2013 at 09:00
I found a nice article how to secure the SSH daemon under Debian: http://upcode.tk/securing-a-debian-7-0-wheezy-ssh-daemon/

[ Parent | Reply to this comment ]

Posted by yarikoptic (165.230.xx.xx) on Mon 30 Oct 2006 at 18:23
Another program analogous to hostsdeny is
http://packages.debian.org/unstable/net/fail2ban

It also can be used to monitor other services (apache, *ftpd, etc) to react (ban) abuser's IP

[ Parent | Reply to this comment ]

Posted by reluctant (65.78.xx.xx) on Mon 30 Oct 2006 at 18:25
You say: PubkeyAuthenticationPasswordAuthentication No
but it should say: PubkeyAuthentication Yes
to enable public key authentication.

Also, this site has excellent articles and comments on topic already:

Brute Force Protection with BlockHosts
http://www.debian-administration.org/articles/342

Automatically Blocking SSH Attackes From Script Kiddies?
http://www.debian-administration.org/articles/250

Keeping SSH access secure
http://www.debian-administration.org/articles/87

My favorite tweak is the fail2ban package mentioned in the articles above.

Regards.

[ Parent | Reply to this comment ]

Posted by Anonymous (213.47.xx.xx) on Tue 31 Oct 2006 at 07:37
Thanks, I have corrected the article.

I know there are several articles out there about securing SSH, but I wanted to make ONE article where 'everything' is in one place. I did not intend to explain the use of each program or configuration file, so I provide plenty of links :)

never used fail2ban, will try it out, but it essentially works as the two log viewers I already mentioned. Will include it after I play with it a little :)


[ Parent | Reply to this comment ]

Posted by Anonymous (89.0.xx.xx) on Mon 30 Oct 2006 at 22:16
Where are the log file you were looking at?
I couldn't see a matching file in /var/log/

[ Parent | Reply to this comment ]

Posted by marki (89.173.xx.xx) on Mon 30 Oct 2006 at 22:24
On Debian it should be in /var/log/auth.log

[ Parent | Reply to this comment ]

Posted by Anonymous (199.111.xx.xx) on Tue 31 Oct 2006 at 23:43
DenyHosts can be used to parse the logs

[ Parent | Reply to this comment ]

Posted by ashwoods (213.47.xx.xx) on Wed 1 Nov 2006 at 21:01
and if use logcheck or similar programs, the interesting parts of the logs will be mailed to you :)

[ Parent | Reply to this comment ]

Posted by undefined (192.91.xx.xx) on Wed 1 Nov 2006 at 17:54
on the subject of opie (OTPs, one time pads)...

i use opie and it has its good & bad points.

good
+ calculators are available for PDAs
+ responses can be printed/written and physically secured
+ avoids key loggers

bad
- on most public systems where i would fear a key logger, ssh w/ opie is thwarted in other ways (windows box w/o putty, http outbound connectivity only; not insurmountable problems, but large enough hurdles to sufficiently discourage)
- requires calculator or preprinted list of responses
- other ways to avoid key loggers in graphical environments (on-screen keyboard, cut & paste, etc)
- subject to brute force attacks because the "count" is not decremented by an incorrect password (but denial of service attacks would be possible with the alternative)
- uses md5 which is being attacked academically, but will eventually succumb practically
- requires ssh & pam configuration tricks to disallow passwords but accept OTP responses (if you want to only accept OTP to avoid password-based brute force attempts)
- requires use of OTPs everywhere (or how comfortable are you with someone knowing your root password after you log in and su to root, even though you've disallowed root login in ssh)

don't let that list discourage you, but just be aware of the problems so you can minimize them ("...because knowing is half the battle!" ;-)

[ Parent | Reply to this comment ]

Posted by Anonymous (68.179.xx.xx) on Mon 13 Nov 2006 at 16:19
I've also found that restricting the logins of some users to sftp stops them logging into a shell but still allows SFTP access:

To do this, edit /etc/passwd and do the following change:

Just change the last bit:

From:
user:x:1001:1001:,,,:/home/user:/bin/bash

To:
user:x:1001:1001:,,,:/home/user:/usr/lib/sftp-server

[ Parent | Reply to this comment ]

Posted by sytoka (213.103.xx.xx) on Sun 10 Dec 2006 at 13:07
Do you know if it's possible to change the shell with OpenLDAP.

With NIS, it was very esay. You have juste do write a line in /etc/passwd of that kind

+user_name::::::/usr/lib/sftp-server 


And on that computer and only that computer, you replace the shell !

You could do the same on a group, juste change 'user_name' by '@group'.

I do no know howto do this with OpenLDAP and all my users are in ldap.

In a more general way, i would like to have a filter on the result of an LDAP request depend on many parameters like the IP address, the username...

[ Parent | Reply to this comment ]

Sign In

Username:

Password:

[Register|Advanced]

 

Flattr

 

Current Poll

What do you use for configuration management?








( 828 votes ~ 10 comments )