Bullet proof your server #2 - SSH

See also: Part 1.

OpenSSH pufferfishWelcome back! In the first part of this multi-part tutorial on FOSSwire, I look at some simple ways you can boost your security for the Apache web server. In this part, I'm going to look at securing the OpenSSH server, which is used for remotely logging in to your server.

OpenSSH is pretty secure as it is, but it never hurts to tweak a few settings here and there to make sure the most commonly exploited vectors are covered. So, without further ado, let's jump in and look at what we can do.

1 - Disable SSH protocol 1

This one's a very basic step and one that everyone should be doing. The SSH protocol, version 1, has known insecurities in it and can be a way for someone malicious to get into your server.

There's almost zero reasons why you need to keep allowing the use of protocol 1 on your server nowadays, so disable it.

You'll need to open up your /etc/ssh/sshd_config file in your text editor of choice, and search for the line beginning with Protocol (although it's normally near the top).

The Protocol line should read:

Protocol 2

That means - accept version 2 of the protocol, and nothing else. Save your config file and restart sshd.

2 - Enable key-based logins

Logging in with a password is all well and good, but you can get better security by using a private and public key pair. I've covered how to generate your key in a previous tutorial, so read up on that here.

To enable key-based logins on the server, make sure these directives are set in the configuration file:

PubkeyAuthentication yes
AuthorizedKeysFile .ssh/authorized_keys

Once that's done, you need to copy your key to the server.

3 - Don't enable password-based logins

Further from setting up key-based authentication, you can go the next step, which is to allow only key-based logins. By disabling all password logins, no-one can remotely attempt a brute force attack against any account passwords on your system. The downside is that all users that need to log in need to have a key set up and working properly.

If you're ready to take this step, make sure you can log in with a key properly (so you don't lock yourself out), then set this directive in sshd_config:

PasswordAuthentication no

Save and restart sshd, and anyone without a key gets thrown straight back out.

4 - Don't run on port 22

The default port for SSH is 22. Everyone knows this, which is a bad thing. The potential attacker will go out, and probe as many machines as they can find, to see if port 22 is open. If it is, they'll start knocking.

Even if they don't get in, you can save yourself the hassle, by moving to a non-standard port. Pick a number above 1024, and use that as your port number in the config file. For example, if I want port 1617, I would put:

Port 1617

Now, I just need to remember when connecting to specify the port in what ever software you're using to connect. For SSH's command line client, for example, like so:

ssh -p 1617 myserver

5 - No remote root logins

This one is pretty much common sense. Don't let root log in via SSH. That doesn't mean you can't get root privileges remotely, as it's easy enough to set up a user with permissions to use su or sudo.

Almost every Unix system has the superuser called root, so attackers will use this as a username they know exists on your system, and try to brute force the password.

To deny root logins, set this directive in your sshd_config:

PermitRootLogin no

See you next time!

Avatar for peter Peter Upfold - http://peter.upfold.org.uk/

Peter Upfold is a technology enthusiast from the UK. Peter’s interest in Linux stems back to 2003, when curiosity got the better of him and he began using SUSE 9.0. Now he runs Linux Mint 9 on the desktop, runs a CentOS-based web server from home for his personal website and dabbles in all sorts of technology things across the Windows, Mac and open source worlds.

Home » Articles »

Discussion: Bullet proof your server #2 - SSH

  1. # Posted on 03 January 2008 at 07:57 AM

    <strong>Story added...</strong>

    Your story has been submitted to fsdaily.com! Come and promote your article by voting for it here on FSDaily! Let your readers know they can vote for your story too....

  2. duh (guest)

    # Posted on 03 January 2008 at 08:08 AM

    Maybe you should add a cmd to restart the sshd deamon ?

  3. Rada (guest)

    # Posted on 03 January 2008 at 08:37 AM

    Moving your sshd to a different port is security through obscurity, and if you're even going to do it (Even though it's a stupid non-solution, as opposed to banning the IP altogether if it tries to login more than a certain amount of times) you should be very aware that you are not more secure. Besides, the doorknocker problem is solved entirely by disabling passworded logins and using key-based authentication. If key-based authentication is not a feasible solution to your server, you should install a service like DenyHosts or similar.

    For more discussion about DenyHosts see http://nixy.dk/2007/10/22/using-daemontools-supervise-on-freebsd/

  4. Rada (guest)

    # Posted on 03 January 2008 at 08:38 AM

    Whoops, sorry. The link was http://nixy.dk/2007/10/12/denyhosts-on-freebsd-62/

  5. Eike Herzbach (guest)

    # Posted on 03 January 2008 at 08:39 AM

    If you want to make that port default for your client and avoid disconnects:

    $ cat ~/.ssh/config ServerAliveInterval 7 TCPKeepAlive yes Port 1617

  6. Jeroen (guest)

    # Posted on 03 January 2008 at 08:48 AM

    Security through obscurity is NOT security. It's foolish to believe that this is even slightly more secure than using the standard port 22.

    If you're afraid of brute-force, a daemon like Fail2ban is pretty decent at solving that for you.

  7. Jeffrey S (guest)

    # Posted on 03 January 2008 at 08:48 AM

    Don't forget DenyHosts. It can easily pick up on multiple failed-password attempts and automagically add the attackers to hosts.deny. It's one of the first packages I emerge on a new box.

  8. Elijah (guest)

    # Posted on 03 January 2008 at 08:48 AM

    Great post, the port change is a good suggestion.

  9. Noah Everett (guest)

    # Posted on 03 January 2008 at 08:48 AM

    Great tutorial. Thanks.

  10. MonkeyC (guest)

    # Posted on 03 January 2008 at 08:59 AM

    To the No-Security-Through-Obscurity flag-wavers.

    Will you please acknowledge that obfuscation lowers the number of attempts made on the port to crack a system? And that the time between discovering an 0-day in the wild and patching the system is not finite, but it is short? So dodging hack scripting against port 22 isn't a complete lost cause, it's just not the entire onion either.


  11. Dave (guest)

    # Posted on 03 January 2008 at 09:12 AM

    Although changing port from 22 to another one isn't a safeguard against people hacking into it, it does add another layer of obscurity that may foil someone trying to break in.

    That, in combination with the other measures, is a good way to increase your SSH security.

    But, don't forget to tell someone who you may have working on your server that the port has changed, because it certainly adds to confusion! :)

  12. Mace Moneta (guest)

    # Posted on 03 January 2008 at 09:13 AM

    Changing the port does improve security - by making it 65535 times more annoying to find the SSH port. With a proper firewall configuration slowing the process, that can add days to an attack before the first login attempt. Sometimes security by obscurity is useful as an additional tool - not the exclusive tool - providing protection.

    The downside to using a different port is that some services (e.g., web blogging sites) that support SSH do not support arbitrary ports (or key login, for that matter).

    Probably the two most useful items are disabling protocol 1, and not permitting root logins. As others have mentioned, a secondary system that blocks repeated failed attempts in the firewall is also useful, though you'll need to deal with false positives as a result of forgetful users.

  13. Randall (guest)

    # Posted on 03 January 2008 at 09:14 AM

    Fail2Ban is an alternative to DenyHosts, written in python. It can temporarily ban IPs for failed SSH and FTP logins, Apache auth failures, etc.


  14. MonkeyC (guest)

    # Posted on 03 January 2008 at 09:17 AM


    Oh perfect. Bash adding hurdles to dodge poorly made scripts, then suggest adding more layers, like Fail2Ban, which add MORE vulnerabilities.


    So now someone can manipulate my firewall by injecting crafted failed login attempt text.

  15. Wesley Workman (guest)

    # Posted on 03 January 2008 at 09:21 AM

    Just to add what Randall said, Fail2Ban is a very easy and quick addition that adds a large amount of security. It works by reading your ssh logs and using IPTables. Tt enables you to ban a given number of failed attempts for a given duration. Extremely helpful in preventing brute force.

  16. Internet_pixie (guest)

    # Posted on 03 January 2008 at 09:25 AM

    Gahh! OK fine. Key-based authentication is more secure than password-based. But if people follow your article they will find it an uber hassle! Every time they want to login they will have to type in their "secure but stupidly long" passphrase.

    If the article is going to promote the use of keys it should also explain how to use ssh-agent or helper scripts like keychain.

  17. Brandon (guest)

    # Posted on 03 January 2008 at 09:51 AM

    Actually you don't need complicated things like DenyHosts or Fail2Ban to ratelimit failed login attempts on ssh. The problem can be solved at the iptables level in Linux using the hashlimit module.

    Here's an example, where "NEW_TCP" is my table for incoming semi-legit TCP SYN traffic (already filtered for funny portscanner flag combos and so-on), and "BADGUYS" is my destination table for probable attack traffic (rate-limited logging + DROP):

    Send incoming port 22 ssh connections to LIMIT_SSH

    iptables -A NEW_TCP -p tcp --dport 22 -j LIMIT_SSH

    Ratelimit incoming ssh connections per source IP to no more than a 2/minute average, with a burst of 3. Read the ipt_hashlimit docs for details on all of the tunables:

    iptables -N LIMIT_SSH iptables -A LIMIT_SSH -m hashlimit --hashlimit-name sshrate --hashlimit-mode srcip --hashlimit 2/min --hashlimit-burst 3 --hashlimit-htable-size 20 --hashlimit-htable-max 30 --hashlimit-htable-expire=300000 --hashlimit-htable-gc 60000 -j ACCEPT iptables -A LIMIT_SSH -j BADGUYS

  18. Redhat Rocky (guest)

    # Posted on 03 January 2008 at 10:09 AM

    I recommend using:

    PermitRootLogin without-password

    which disables root ssh logins via password as opposed to what one would expect it to do.

    Setup root with a separate ssh-key for those emergency situations (like say, a forgotten root password!).

  19. Tom Burton (guest)

    # Posted on 03 January 2008 at 10:10 AM

    Wow, saw this on Digg. I myself have just started playing with key-based logins, and I have to say they are pretty useful, especially for scripting.

    You're tips are good, some of them are integrated into a program I've written for Ubuntu/Debian: ProShield.

    It does other things, like making sure you are up to date. Check it out http://proshield.sourceforge.net

  20. James Coletti (guest)

    # Posted on 03 January 2008 at 10:15 AM

    Just a note to Debian (and possibly other distros) users. I believe just setting "PasswordAuthentication" to "no" will not disable password logins entirely. If through testing you realize you can still log in to your system with a password and without a key, try disabling PAM by adding "UsePAM no" to your sshd config.

  21. Derek Anderson (guest)

    # Posted on 03 January 2008 at 10:29 AM

    +1 MonkeyC

    Adding an automated ban function is one of the worst mistakes an admin can make. Think about it; you are giving remote attackers with the ability to spoof packets the additional ability to LOCK YOU OUT! This is ludicrous! Worse, they can ban ARBITRARY hosts. What happens when these people start spoofing attack packets from your DNS server, your web proxy, or your up2date repo?

    Kaminsky poked a lot of holes in this during one of his DNS talks years ago. Do you really want remote users to be able to modify your firewall rules?

  22. Ben (guest)

    # Posted on 03 January 2008 at 10:46 AM

    Umm.. Unless your distro is living in the dark ages. Key authentification is enabled by defaults. All the # out items in the sshd_config should be the "defaults" that are compiled into the ssh deamon. Or they are when you use the openssh right from portable.

    • Ben

  23. Ben (guest)

    # Posted on 03 January 2008 at 10:51 AM

    Oh FYI on the moving ports (something I don't subscribe to, but I frankly don't care anymore), please do yourself a favor and pick a port BELOW 1024!!!! Anything above that can be used by a normal user, and thus can open you up to other issues if your deamon were to "magically" drop offline.

  24. Mahmoud (guest)

    # Posted on 03 January 2008 at 10:56 AM

    I do not think that fail2ban would work when key authentication is the only method used. Moreover, Brute force attacks are not useful against key authentication.

    Obscurity adds a layer of security, although you can not depend on it but I think it is worth using. 1. Changing port 2. listening on a different IP, other than the one used for web services.

  25. Johann (guest)

    # Posted on 03 January 2008 at 11:35 AM

    Changing the port might thwart some script kiddies but it does not secure the server 65535 times as someone suggested. All it takes is one port scanner run to the server to find out what the SSH port is.

    I personally don't see a need to change the port number; IMO the inconvenience outweighs the security gain from the tweak.

    Better measures would be TCPWrapper and use of public/private keys, which makes it almost impossible to break into.

  26. name (guest)

    # Posted on 03 January 2008 at 12:14 PM

    you should mention the use of the "AllowUsers" directive. Accounts should only have access specifically turned on; otherwise, test accounts and/or system accounts could potentially be breached.

    Also, you should mention running the latest version of whatever SSH daemon you happen to use. New vulnerabilities and side-channel attacks get updated/patched often.

  27. Catsby (guest)

    # Posted on 03 January 2008 at 12:26 PM

    Wow, I can't believe no one has mentioned the first (and to me, most important) rule that I add to all my SSH installations, if possible:

    AllowUsers johndoe janedoe

    By allowing just a few users, a "deny first, then allow" security policy is set. This eliminates the uncertainty of locking down every system account. I've found that the most effective security measures are to deny everything by default, and then only poke holes for known allowances. This is just like how you shouldn't try to set up IPTables by individually blocking every unwanted port - you simply allow the few you want, and then block the rest by default.

    Most of the security problems I've experienced regarding SSH have been successful brute-force login attempts to ancient client accounts that no one has remembered to disable.

  28. or4n (guest)

    # Posted on 03 January 2008 at 01:37 PM

    Why would you even keep SSH port open 24/7? Just use knock daemon so you can open SSH port to your IP for say 30 seconds so you can log in and then close it again ;) If you have stateful firewall (like iptables), it won't close your already open SSH-session.

    Here you can find more info about http://www.portknocking.org/

    This way you can keep your password based login and still be secured :)

  29. Mark (guest)

    # Posted on 03 January 2008 at 03:22 PM

    Yeah, moving the port number for SSH does make it slightly more secure, but with the proper security practices in place (password complexity, brute force detection), the difference is negligible at best, and it can be a big hassle for your users. But I guess if you are paranoid...

  30. CCNA Discovery (guest)

    # Posted on 03 January 2008 at 04:46 PM

    These were some interesting tips. Everyone needs to be aware of these holes instead of blindly reading instructions and running their servers.

  31. Dude (guest)

    # Posted on 03 January 2008 at 05:07 PM

    Also look into

    AllowUsers AllowGroups DenyUsers DenyGroups

    So that you can control where people can come from for which account and group.

  32. Bryan (guest)

    # Posted on 03 January 2008 at 05:20 PM

    Gah! I have heard that argument over and over again about changing ssh to a non-standard port.

    "security through obscurity is no security at all" Says the broken record.

    I believe heavily in security metrics because numbers are awfully hard to argue with.

    In a university environment a machine with ssh on port 22 in my DMZ would receive an average of ~100 invalid login attempts per day (averaged over the course of 2 months).

    This same machine in the same DMZ running SSH on port 51234 received an average of zero... no, not a average of zero... just zero.

    This effectively eliminates all scripted attacks, worms, Trojans, bots and most uninitiated real attackers.

    In fact if you run it on a very high port -- say 51234 -- most people won't even find it with a port scanner.

    One would have to statically define the port range as most port scanners quit far before 51234.

    At that rate scanning ports 1-51234 would take an insane amount of time per host, and most attackers scan huge blocks of hosts.

    At that point hopefully an IDS/IPS would pick up the port scan and make the whole thing moot.

    Seriously. Its not a fool proof security measure and I certainly wouldn't use it as the only means of protecting SSH, but its an effective layer. And those same people that are so quick to spew out the "Security through obscurity" cliche are also the same that are quick to pull out the "Layered Security" ones.

  33. # Posted on 03 January 2008 at 06:21 PM

    [...] Link here. [...]

  34. # Posted on 03 January 2008 at 09:26 PM

    [...] Bullet proof your server #2 - SSH Disable SSH protocol 1, Enable key-based logins, Don’t enable password-based logins, Don’t run on port 22, No remote root logins. (tags: tutorial server security opensource) [...]

  35. # Posted on 03 January 2008 at 10:25 PM

    [...] FOSSwire » Bullet proof your server #2 - SSH hadn&#8217;t known about &#8217;ssh-copy-id&#8217; - cool stuff (tags: ssh security linux howto sysadmin) [...]

  36. Johann (guest)

    # Posted on 03 January 2008 at 10:37 PM


    Changing SSH port works well if you have few servers to manage. When you manager large number of servers, you end up having to maintain server-to-SSH-port list, which in my opinion is a pain.

    You could, of course, use a common high-port for SSH across all servers. But then, it kinda defeats the point of shifting to high-port anyway because once attacker finds out your SSH port, then he can attack your other servers with the same port.

    In my opinion the most secure protection is the TCPWrapper combined with key-base authentication. This makes it very difficult for attackers to gain access to the server, even if they know that the port 22 is alive.

  37. # Posted on 06 January 2008 at 10:23 AM

    [...] Bulletproof&nbsp;ssh Filed under: BSD, Linux, OSX, Security &#8212; 0ddn1x @ 2008-01-06 17:22:57 +0000 http://fosswire.com/2008/01/02/bullet-proof-your-server-2-ssh/ [...]

  38. # Posted on 07 January 2008 at 06:38 AM

    [...] recently posted a comment on FOSSwire.com in response to other comments condeming the author for suggesting moving ssh to a port besides 22 [...]

  39. # Posted on 07 January 2008 at 10:05 AM

    [...] Bullet proof your server #2 - SSH [...]

  40. # Posted on 10 January 2008 at 08:15 AM

    [...] from FOSSwire wrote up a nice tutorial on securing SSH in 5 simple steps and covers the [...]

  41. # Posted on 10 January 2008 at 04:11 PM

    [...] most common and safe method to access remote Linux or Unix system. The article is freely available here. Share This Related posts:Local and remote X sessions on different consolesSecure shell (ssh) [...]

  42. i621148 (guest)

    # Posted on 11 January 2008 at 08:05 PM


    ALL : ALL \ : severity auth.info \ : twist /bin/echo "You are not welcome to use %d from %h..."


    hosts.allow 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.

    Prevent those with no reverse DNS from connecting.

    ALL : PARANOID : RFC931 20 : deny

    Allow anything from localhost. Note that an IP address (not a host

    name) MUST be specified for portmap(8).

    ALL : : allow ALL : : allow ALL : : allow ALL : : allow ALL : : allow ALL : : allow ALL : : allow

    allow ssh from anywhere

    uncomment the line below if you are going on a trip

    sshd: ALL

    me @ work

    ALL : : allow

    You need to be clever with finger; do not backfinger!! You can easily

    start a "finger war".

    fingerd : ALL \ : spawn (echo Finger. | \ /usr/bin/mail -s "tcpd\: %u@%h[%a] fingered me!" root) &amp; \ : deny

  43. i621148 (guest)

    # Posted on 11 January 2008 at 08:07 PM

    these files above have pretty much stopped all brute force attacks appearing in my logs...

  44. Chris (guest)

    # Posted on 12 January 2008 at 11:14 PM

    Here is what I used to do.

    1 - change port (it does make things a bit better stops automated trojan scanners who scan entire ranges on port 22 and keeps my security log clean, if I see brute attempts on a non standard port I know its probably someone who 'really' wants to get in) Inconveniance is certianly less then training users to all use keys.

    2 - disable password auth but leave keyboard interactive on.

    3 - limit who can login, I typically allow ssh group in, so a default deny as someone said.

    4 - disable tcpkeepalive and use encrypted keepalive instead.

    5 - set MaxStartups to an appropiate setting to make it harder to brute force, likewise with LoginGraceTime and MaxAuthTries.

    I then decided to allow direct root login but only with my key not via passwords, the problem is the no password setting does not disable keyboard interactive so I have changed keyboard interactive back to normal password auth and have the no password on root, which is useful if for whatever reason you are prevented from logging in to your normal account and been able to su to root.

    I have used denyhosts in the past but as someone else also said it itself is a potential dos tool against your own server as someone can spoof your ip or even your gateway ip effectively locking you out your own machine.

    Lets face it also if you leave the port on 22 you will typically get at least a dozen or so login attempts each day and you would then develop a habit t not investigate these logins as they would be considered routine meaning a human brute forcer is likely to be unoticed whilst a different port your routine will be brute force attacks so when a humen tries to brute force it will be much easily noticeable, combined with the downsides I stated about using tools like denyhosts I can only reccomend changing ssh port.

  45. # Posted on 15 January 2008 at 03:17 PM

    [...] FOSSwire » Bullet proof your server #2 - SSH (tags: security ssh server howto tutorial admin administration linux sysadmin) [...]

  46. # Posted on 23 January 2008 at 04:26 PM

    [...] FOSSwire » Bullet proof your server #2 - SSH SSH, one of my favourite tools in the timelady arsenal:) (tags: ssh security sysadmin tutorial linux nas network networking reference server shell administration hack howto configuration system tools) [...]

  47. # Posted on 11 February 2008 at 11:22 PM

    [...] bookmarks I cam across these two... sorta similar http://www.howtoforge.com/ssh-best-practices http://fosswire.com/2008/01/02/bulle...-server-2-ssh/ Which could fall under the prevention category. Obviously you can write first and foremost about [...]

  48. xUx (guest)

    # Posted on 14 February 2008 at 09:08 AM

    You should give a try to http://lmf.sf.net , it's a great tool which can be used for brute force attacks and such. I personally use it to monitor sendmail, ssh, ftp activity and block those unwanted connections.

    My 2 cents, good article + comments

  49. foo (guest)

    # Posted on 17 March 2008 at 08:43 AM

    Or, if you're not using Linux, you can use OpenBSDs beautiful PF to handle brute force attacks. Your /etc/pf.conf should contain something like:

    table persist

    block in quick from

    pass in on $ext_if inet proto tcp from any to any port ssh keep state (max-src-conn 5, max-scr-conn-rate 8/10, overload flush global)

    You might want to add yourself to a pass in quick before the block in quick from , in case you should get yourself added to that list.

    pass in quick on $ext_if inet proto tcp from $trusted to any port ssh

  50. # Posted on 30 March 2008 at 04:29 AM

    [...] a long name like mine, it saves quite a bit of time in the long run. It&#8217;s also a good idea to disable root login via SSH and enable key-based SSH authentication for [...]

  51. # Posted on 13 May 2008 at 09:21 PM

    [...] Part of the text was taken from FOSSWIRE [...]

  52. Jerry McBride (guest)

    # Posted on 26 August 2008 at 11:50 PM

    I go a bit further by moving the assigned sshd port every hour via cron. When I need to login, I look at the time, determine the current port assignment, then login. I also use denyhosts and have cron email me a nightly report of the days firewall activity.

    Works for me...

  53. Tony Yarusso (guest)

    # Posted on 28 October 2010 at 06:17 PM

    I've never considered changing the port to be a security measure, but I still find it handy. The reason being that it does reduce the volume of attempts, which makes my log files smaller and easier to sift through, which is convenient. (Just reducing the numbers doesn't increase security, because the people who were more likely to get through before are still likely to get through now, so that would be false logic.)

Home » Articles » Bullet proof your server #2 - SSH