Hacker News new | past | comments | ask | show | jobs | submit login
Three locks for your SSH door (ibm.com)
90 points by rlm on Sept 5, 2010 | hide | past | favorite | 54 comments



There is a trade-off here. Weigh up the risks as you think is best and act accordingly, but try not to let the coolness/hacker factor of the solution affect your security decisions!

On one hand, it is clearly going to be harder for a random zombie machine to find your ssh on a non-standard port that requires knocking and a particular less usual username.

On the other hand, you're breaking from your distribution's standard installation. You increase the risk of breaking on a future upgrade. You could lock yourself out, perhaps, and there's a cost associated with this. In the worst case a distribution upgrade will fix a security hole and you'll be left with it (say for example because you modded the config file, dpkg queried it, you rushed through the prompts and it got left alone).

I accept my scenario is unlikely, but it is also unlikely that someone will crack your up-to-date machine using distribution standard ssh, a secure root password and public keys for day-to-day access.

It is far more likely that someone will access your secure machine from an insecure place with a keylogger running and get cracked that way.


1. modifying the default configuration is fine: you do this for your web server (right?) so why not sshd? in fact, sshd is simpler to configure and i cannot think of one backward incompatibility in many years. disable what you don't need, this includes bits of sshd. what's the point of a configuration file if you can't change it?

2. your point about "using distribution standard ssh, a secure root password and public keys" is a little moot in light of the debian ssh keygen bug? in this case you would have been better off with building ssh yourself (and keeping it up to date).

3. in any case, you are at most risk from your users. if they are compromised, you are also (public key or not).


Wasn't the Debian bug in OpenSSL? Building OpenSSH yourself would not do you any good there if you linked to the distribution's OpenSSL.


I gave up on a non-standard port because I kept having to figure out configuration for programs that implicitly run ssh (darcs, git, I think there were others..)


On Mac/Linux, setting a different default port for your host in ~/.ssh/config will allow git and other applications to automatically use the new port binding on the server.

My ~/.ssh/config basically looks like https://gist.github.com/78ec014f31c8a06f656b

…which allows me to just use "ssh server1.example.com" and "git clone foo@server1.example.com:blah/project" to access those resources without explicitly defining the port number.

---

Edit: The standard msysgit installer for Windows may look in the same place too — I haven't tried.


Ah that's very useful. Thanks.

I only recently realized I could abbreviate hostnames in .ssh/config.


Wouldn't it be much easier to just restrict access to keyfiles and block anyone who fails more than 3 attempts?

Not sure why but the idea of port knocking always seems over complex for little benefit.


Yeah, at least as far as my logs go, just disabling password login seems to cover a superset of the attacks that changing ports would cover, so I don't see much reason to avoid the default port. Every automated attack I've found in my logs is: 1) on the default port; and 2) a password attempt. It seems the recommendation here is to change #1, but to me just changing #2 is easier, and has some other benefits as well. The main place I could see an argument for #1 is if you run a large multiuser server, where it's quite possibly easier to explain to your users how to use a nonstandard ssh port, versus trying to explain to them how to use ssh keys.


Hostgator's nonstandard port for hosting is my biggest complaint about their service, especially because I cannot set up key-based authentication, and I have to ad -e 'ssh -p 2222' to my rsync statements.

But if I'm being honest, back when I signed up with them keypairs would have been a little more difficult than working out that option for rsync.


the advantage of port knocking is that it's a separate line of defence from your ssh server. It'd be damn useful in the case of a remote SSH exploit.


Great point - port knocking would have provided a separate line of defense when that horrible Debian/Ubuntu keygen flaw hit a few years back.


I agree with you -- port knocking and even changing ssh's listening port look a lot like security theatre. They're cool, they're hackish ... and they're completely unnecessary, assuming that you don't allow root ssh logins and have a relatively small subset of ssh users, along with a reasonable password policy.

At worst, the internet will just keep filling your logs with access attempts, none of which will actually accomplish anything.

I did recently decide to start using fail2ban though, not because I'm worried about someone hacking ssh, but because I wanted a centralized system that would monitor various forms of abuse (including obvious spammers).


I see another benefit of using fail to ban. That is, it helps a little to keep the log files (a little) shorter.


It's a reasonable enough way of protecting hosted websites, especially if you're running more than one server. You can monitor multiple logs for abuse from different sources, and then update all servers to drop traffic from those sources. So, if someone runs a WordPress vulnerability scan on a hosted website, you can detect that and immediately refuse any mail/ssh/dns/www/ftp/other service from that IP.

It requires a little bit of kludging to do this though. :-( As packaged, it's not much more useful than a hacky shell script.


I'm just gonna rephrase and repeat this bit, because it seems to be not completely understood:

Do not allow password logins. Do. Not.

Have a method to redact keys quickly. The advice of the article becomes irrelevant. If someone gets hold of an unencrypted/crackable private key, they'll likely also have access to the secret portnumber, knock sequence and username, so nothing much gained there.


It seems to me (no security expert by any means) that port knocking and similar schemes are useful because they're orthogonal to SSH infrastructure and thus can provide a certain amount of defense against sshd 0-days and the like.

Consider the Debian PRNG flaw from a couple years ago. As I understand it, most SSH/SSL keys generated on Debian and Debian-derived boxes over a period of about two years were (rather) easily guessable. Even if you were able to redact any compromised keys as soon as this was publicly revealed, who knows how long malicious attackers may have known about it before it was made public. If your server had port knocking enabled you would have had a bit of insulation from this attack.


that's what these try to do:

http://www.fail2ban.org/wiki/index.php/Main_Page

http://denyhosts.sourceforge.net/

denyhosts has the difference that it synchronises this data amongst many hosts.


Heh. I've been working for the last little bit on setting fail2ban up to work with MySQL and sync between three servers. It's actually not nearly as hard to do correctly as I thought.


I think the main goal behind port knocking is to prevent someone from exploiting a pre-authentication vulnerability in the ssh daemon.


Step 1) Setup OpenVPN. Step 2) Block ssh access using iptables or equivalent from all but the VPN connections and one or two trusted IPs (the latter just in case you need to do OpenVPN maintenance). Back in the day, you would have had a separate network for administration. Simulate that with OpenVPN.


It's depressing that your post hasn't received more attention. Your control systems should be on a private control network, not exposed to the wide internet.

OpenVPN is capable of providing a much, much smaller attack surface than OpenSSH (see http://news.ycombinator.com/item?id=1665773), and can be run entirely chroot'd and setuid such that even if an attacker does compromise OpenVPN, they can not necessarily gain further access.

There seems to be a prevailing lack of understanding that bad passwords are not the only concern when using SSH. The daemon itself may be vulnerable to exploit (and in the past, it has been).


For anyone who doubts the merits of obscurity for security:

http://danielmiessler.com/study/security_and_obscurity/

Hint: Why do we camouflage tanks?


I don't think anyone argues that obscurity is worthless. The argument is more that when it fails, it fails unpredictably and completely, so it's not something to be relied on. In a situation where you need every advantage you can get, go ahead and hide whatever will help.

If you're just opening up SSH on your personal computer, you don't need every advantage you can get. Just make sure that your authentication is strong, and you'll be fine.


You're missing the fact that when you remove the camo paint off of a tank you haven't made the armor any weaker, just as putting SSH on a different port doesn't mean you remove authentication.


And you're missing the fact that ssh is not a tank.

We could continue raping that metaphor, or we could just discuss whether or not putting ssh on a different port actually accomplishes anything useful.

For example: it's generally a pretty safe assumption that most remote servers have ssh running on them somewhere. If you are running scripts to find vulnerable or misconfigured ssh hosts, then it makes sense to scan the standard port and try stupid logins. In that case, if the sysadmin moves ssh to a different port, then they "protect" themselves from the various scripts out there, but then again simply having reasonable password policy accomplishes the same thing and without the hassle of having to locate ssh on a different port.

On the other hand, if you're a dedicated attacker and you want to compromise a particular system, then moving ssh to another port does squat; nmap will find it easily enough. Port knocking and/or denyhosts and/or iptables or pf will stop that easily enough, but then again, a dedicated attacker probably won't try ssh first anyway, since that's hard. Attacking something else like your web app or any of your other services, would make a lot more sense.

So, either way, running ssh on a different port is completely superfluous. While you haven't "made the armor any weaker", you also haven't made it any stronger. At all.

Because ssh is not a tank.


I think the argument is that security only by obscurity is not security. Obscure and good is a better alternative. The example for this topic would be a non standard port, but no password - nice and convenient, and it's unlikely anyone would find the port, but when it's found there's no security left.


Why do you think I'm missing that? Was it the part where I said that you should go ahead and obscure things in situations where you need every advantage you can get? (i.e. where I explicitly acknowledged that)

It costs something to use a port knocker. It costs something to use a nonstandard port. If you have strong authentication (say, using 2048-bit ssh certificates), it's probably not worth paying those costs. Maybe it is if you're a bank, but probably not if it's the server that hosts your blog. If you don't have that strength of authentication, it would be better to pay for the better authentication than for the port knocker and nonstandard port.


For those who did not read the article:

Difference between using usual 22 and "unusual" 24 port, 18000 attempts vs. 5 attempts over one weekend.

Seems to weed out script kiddies quite quickly.

Personally, I don't see anything wrong with having 3 locks on the door:

  ACl
  port knocking
  nonstandard port
Another analogy would be one bouncer, one secret knock, and one nonstandard keyhole.

Of course, one still wants to have a difficult to pick key after all that.


So bored intel ops can play spot-the-difference between natural and IR images?


1 and 2 seem to me to be par for the course when setting up a server that you want to be secure... Only allow logins with keys, choose a high port that's not usually scanned, and only allow specific users to log in (law of least privileges).

Is 3 really that necessary? Are there often cases where an up-to-date ssh daemon gets cracked even though it is on a high port and allowing only public key logins of specified users with a small number of retries?


Brute force

Do not under estimate the zerg. Although ssh servers on different ports are "harder" to find, they are still not invisible. Try changing your banner, using 'port knocking', TCIP fingerprint spoofing, and other obfuscation techniques. Nothing is 100%, but you can still have really secure boxes. Proper admins are your best line of defense.


Wouldn't something like fail2ban be enough?


It helps but you can't always assume unwanted logins are going to be brute force attacks. My biggest source of paranoia is a stolen/lost laptop with a saved SSH password/key. I prefer ACLs to port knocking. Depending how important a machine is there's no good reason to allow the entire Internet in. If it means someone has to drive to the office or do some SSH hoping that's a small price to pay.


In most cases I would say yes, however, on the off chance the person doing the attack has an army of bots at their disposal it's not going to do that much good. The reason for this is bots can all have separate IP addresses in totally different IP ranges. I am not saying, "nothing is secure" but merely "read your logs".

This whole post got me thinking about ways to sniff out proxies. I am usually behind on this kind of thing, but bare with me please :).

Using PHP and Javascript I think you could weed out the majority of proxy users; avoid IP spoofing, protect sensitive places a little better. Use php to get the users IP address. Find location of that IP. Find timezone/time of that ip. Have a range set up to catch errors. Now use JavaScript to get the time.

Javascript will return the time specific to the system. If the two times do not match up then you possibly have someone using a proxy.

There are some issues with this type of system, traveling business man, but it could be useful at some point.


I'm not familiar with the bleeding-edge practices for securing a server, I just use techniques like the ones in the article, but shouldn't there be a more RFC-friendly approach to locking down a server?

For instance, instead of this irregular "knock" routine, which is a fuss to implement, why can't there be a standard protocol for requesting firewall access? There's a standard for punching holes in local firewalls to open external ports, so why can't the same thing be applied in reverse to remote hosts?

With a proper access control mechanism, ssh-key driven, LDAP-backed or otherwise, it should be possible to send a packet to the remote firewall with enough information to verify identity and open the port as required. That would prevent scan attacks from working because none of the probes would be properly signed and the host port would appear closed.


I made a clitd script I back when I had a box set up at highschool. If anyone tried to connect to standard tcp services that I decided were not supported (time/port 7 and such), I would add their subnet to hosts deny for a day. It was pretty useful for fending off attacks that pre-empted with a port scan.


Point and laugh: I just locked myself out of a production machine (a very, very minor production machine that serves almost no traffic) by changing the sshd port number without first poking a hole in the firewall.

Now I get to drive out to the datacenter. Whoops.


LoginGraceTime can be greatly decreased to 5 seconds in most cases. I recommend this unless you are connecting over extremely slow links.


I'd like to remind people too to use DenyHosts: http://denyhosts.sourceforge.net/

It's awesome, gets rid of a bunch of brute forcing ips that you see in your secure.log.


Using a non-standard port for ssh eliminates the need for this altogether. This is almost a no-brainer, and it's the first thing I do when standing up a server.


Using a non-standard port for ssh eliminates the need for this altogether. This is almost a no-brainer, and it's the first thing I do when standing up a server.

No, it doesn't. Running a port scan and finding your "hidden" SSH port takes very little time.

Placing your SSH port behind a hosts.allow restriction ensures that you've reduced your attack surface to only the hosts (or networks) you've permitted.

Better still, set up OpenVPN, use its HMAC[1] support to stop unknown users early, and don't expose any other daemons to the internet.

[1] http://openvpn.net/index.php/open-source/documentation/manua... (See --tls-auth file option).

To quote:

The rationale for this feature is as follows. TLS requires a multi-packet exchange before it is able to authenticate a peer. During this time before authentication, OpenVPN is allocating resources (memory and CPU) to this potential peer. The potential peer is also exposing many parts of OpenVPN and the OpenSSL library to the packets it is sending. Most successful network attacks today seek to either exploit bugs in programs (such as buffer overflow attacks) or force a program to consume so many resources that it becomes unusable. Of course the first line of defense is always to produce clean, well-audited code. OpenVPN has been written with buffer overflow attack prevention as a top priority. But as history has shown, many of the most widely used network applications have, from time to time, fallen to buffer overflow attacks.

So as a second line of defense, OpenVPN offers this special layer of authentication on top of the TLS control channel so that every packet on the control channel is authenticated by an HMAC signature and a unique ID for replay protection. This signature will also help protect against DoS (Denial of Service) attacks. An important rule of thumb in reducing vulnerability to DoS attacks is to minimize the amount of resources a potential, but as yet unauthenticated, client is able to consume.

--tls-auth does this by signing every TLS control channel packet with an HMAC signature, including packets which are sent before the TLS level has had a chance to authenticate the peer. The result is that packets without the correct signature can be dropped immediately upon reception, before they have a chance to consume additional system resources such as by initiating a TLS handshake.


I don't find using hosts.allow terribly useful as the people that tend to want to ssh into servers that I control are often mobile, with IP addresses that change regularly.

The point I'm making, though, is that every instance of someone running a dictionary attack against one of my servers was a script kiddie running a tool against a range of IP addresses. Changing the port ssh runs on to something high eliminates this entirely.


The point I'm making, though, is that every instance of someone running a dictionary attack against one of my servers was a script kiddie running a tool against a range of IP addresses. Changing the port ssh runs on to something high eliminates this entirely.

Those are the attacks you see. The script kiddie with a 0-day would be much less obvious.

There are straight-forward ways to architect your infrastructure such that you solve the dictionary attack problem AND the 0-day problem, none of which require the hand-waving security (and user annoyance) of moving SSH to a non-standard port.

The security provided by a non-standard port is laughable -- it's like putting a child-proof lock on your front door.

If you're worried about dictionary attacks, turn off password authentication. If you're worried about 0-day vulnerabilities in SSH, leverage defense-in-depth (require well-secured VPN connectivity before allowing SSH access). If you're worried about user's machines being compromised and their keys stolen, leverage two-factor auth.


while denyhosts (or fail2ban just for ssh) is of extremely questionable benefit, it's not because using a non-standard port for ssh eliminates the need for it altogether.

Once the correct port is located, you're in precisely the same situation that you are if you hadn't moved ssh.


Security by obscurity, thumbs down.

nmap -sV -p1-65000 ip


Ok, maybe not so flippant comment this time...

I thumbs downed the article because as a security professional we try to stress the importance of actual security rather than obscuring the problem for long term success.

Take port knocking for example, interesting idea but what a pain in the ass... just disable root and set a strong password.

Changing the port from 22 will prevent all of the automated botnet driven SSH brute force attacks, which do little more than messy up your log directories.

Best thing you can do is use SSH brute force blocking script which reports attackers back to a webapp which the security community can use to track infected hosts. example: http://danger.rulez.sk/projects/bruteforceblocker/blist.php

Fail2ban is a nice one too as it supports many services including http-auth.


this is how matasano got owned. an easily guessable account got broken into and root priv escalation was used. if they were using port knocking an attacker would have had to be in the middle, which is possible but adds an extra 'auth' layer so increases overall intrusion hardness.

also, everyone keeps talking up these scripts to stop brute forcing... two iptables rules will do this for you.


Actually, this works for a practical reason: scanning ports takes time and resources, and script kiddies are more likely to move on to the next target if they don't find a worthwhile target in the first few thousand ports. It won't help against a determined attacker, of course, but it does reduce the number of less-skilled attacks.


People keep mentioning this, and I really don't understand why.

Do you have a username/password or username+certificate that a script kiddy is likely to hit in their first 10,000 attempts?

If yes, you have a much larger problem that can't be solved by port knocking or moving ssh to a different port.

If not, then you're trying to solve a problem which doesn't exist anyway.


If there is a 0-day or unreleased SSH vulnerability, your login security doesn't matter. In those cases, it helps if the s'kiddies skipped your site altogether because they couldn't be bothered to wait to find where your ssh port is.


Ah, thanks. That's a big if, but it has happened, so it makes some sense.


Wrong.

http://danielmiessler.com/study/security_and_obscurity/

Ask yourself why, if obscurity is worthless, does every military put camouflage on its tanks?


[deleted]


RTFA.

But no, he's arguing that even if you had the best armor in the world, an international agreement that all tanks must park at the top of the nearest hill would be Bad for the life expectancy of the crew.


Conclusion You've seen three ways of hardening SSH access to your machine: modification of sshd configuration parameters, selecting which users can log in by means of PAM, and use of port-knocking sequences to hide the existence of SSH access. Although I mentioned that there is no way to secure fully any machine, adding these three layers will make your server more than just a little safer.




Consider applying for YC's Spring batch! Applications are open till Feb 11.

Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: