>obscuring your login service via non-standard ports or even a requirement to try several ports in sequence really only buys you security equivalent to lengthening your password by two characters per port.
Not even that. It's like a separate two-byte password because you get to guess and confirm the port separately from the password.
Lengthening your password by N bits multiplies the number of necessary guesses by 2^N. Having a separate N bit password adds 2^N to the number of of necessary guesses. So if your real password's effective key length is more than 16 bits, using a random port effectively adds less than 1 bit of entropy.
Also, rate-limiting port scans is way harder to do than rate-limiting authentication.
It occurred to me that if you want to multiply the number of necessary guesses by running sshd on an alternate port, you'd need to run multiple sshds. (Of course all but one of these sshds should be decoys.) Doubling the number of sshds is then like adding one bit to the password.
The likely result of that would be that a smart hacker would cross you off his IP list upon discovering you are running a bunch of sshds. After all, if you are devious enough to do that, it's unlikely your real sshd will fall to his script in any case. You are a waste of bandwidth better spent chasing low-hanging fruit.
Which is better: to have someone hack into your machine and install a keylogger and wait for you to connect to your servers using SSH to get your passwords or someone hacking into your machine and stealing immediately the private keys!?
While I'm not sure if you can argue 'no protection' while at the same time admitting that the number of attacks was greatly reduced for a while: I always hated that advice with a passion.
No, do not run SSH on a non-default port. It's nothing but an obscurity hack, does little good and breaks a lot of workflows (routers that prioritize port 22 as interactive traffic, firewalls that explicitly allow ssh - on port 22 of course, tools that are awkward to use as soon as you need to use a different port than the _standard_ one).
I admit that I mocked people recommending that practice in the past. That's childish of course, but if the data of this submission is correct I can now add a more serious 'Please do not do that' argument to my list.
There's a strong reason for advocates (like myself) for running ssh on non-standard ports: it reduces 99% of automated attacks and bots.
Yes, you could use fail2ban and ban half the internet, but that just clogs your filtering rules and makes your system waste memory and cycles. Case in point: one of my servers with ssh on port 22 had +9,000 denied IPs over less than one year. On a non-std port, ~100.
There's almost no drawback to using a non-standard port. Everything that uses ssh allow port customization (and I wouldn't trust something that doesn't).
> routers that prioritize port 22 as interactive traffic
Internet routers don't typically do any QoS (except to reduce the priority - bittorrent/etc), let alone prioritize 22. And within your own network, you have control over QoS anyway.
Also, I disagree with the OP:
>...those who have moved their main login service to a non-standard port pay less attention to their logs than the rest of us
I believe it's exactly the opposite. When you're used to carefully inspect your logs on an ongoing basis, you don't want to see it polluted by automated attacks.
Now when you use a non-std port and discover people doing port scans, you'd better pay attention...
My take: If the fail2ban solution bans 9000 IPs - why would you care? If password authentication is disabled (is it?), who cares? What's _gained_ here, except for a potentially smaller log file?
Everything that uses ssh allow port customization
(and I wouldn't trust something that doesn't).
Sure. I agree. The problem starts, if you mix a lot of clients. Say, I'm using two different OS' (Windows, Linux). For Windows that means putty for me (one interface) or WinSCP (two interfaces to manage). On Linux I'm using ssh (ssh foo@host:port) or scp (scp -P port ..).
I certainly CAN manage .ssh/config files and reduce that mental overhead a bit. But my argument is that this makes no sense. It - in my world - doesn't buy you security, but might cause mental laps and cache misses that annoy you.
> What's _gained_ here, except for a potentially smaller log file?
- Smaller and easier to parse log files
- Less time wasted parsing log files (or creating scripts to filter out automated attacks)
- Less RAM & CPU cycles (particularly important when running low memory VMs)
I still fail to see a reason to NOT do that.
It won't increase your overall security, but it doesn't reduce it either, so why not do it? Just to save you from adding 'alias ssh=ssh -P xx' to your .profile?
> You can redirect ssh failure messages to a specific log
> file, separate from all others
That's exactly the point. Now you redirect ssh failure messages to a specific log file (with all the garbage and automated attacks), and you'll very soon start to ignore it. And then your overall security is reduced, simply because you aren't paying attention.
Or, you can spend time combing through hundreds of invalid messages, trying to separate the wheat from the chaff. Either in one or multiple separate files, it doesn't really matter.
Anyway, not trying to convince anybody here. I respect the opinion that some may prefer to leave everything as the default.
For me, I just vehemently disagree with OP's point that using a non-std port doesn't have concrete benefits and/or reduce the security. To me it's exactly the opposite. At least if you know what (and why) you're doing.
It is my host. I don't need all the log noise. I am taking the same standard precautions on the higher port that one is supposed to take with the default port. Why should I care about your workflows over mine?
You shouldn't. If I did imply that, please point out where. I certainly didn't to make that impression.
I just doubt that a change of port makes sense, I don't claim that it's a amoral or anything. You do it? Yeah, go ahead. Please don't recommend it as 'best practice' is all that I ask for, with both the argument and my condensed workflow examples listing scenarios why this might not be useful.
Port 22 should only be used if the SSHd needs to be accessible to strangers; I think a lot of people use alternate ports. Go a step farther by running Kippo[1] (or other SSH honeypot) on port 22 to accept SSH traffic and waste attackers' time. Not only do attackers forgo scanning for the true SSH port, but they believe they've successfully intruded into the system and leave keystroke-by-keystroke logs of their actions in the decoy shell.
Very interesting. A cool variant would be to, by default, offer the decoy shell on port 22 but also run the real SSH on port 22... But only activating it temporarily for the IP that just did succesfully port-knock. This should be trivial using some local redirection rules (so you'd run, say, SSH on port 19381 but use a transparent redirect to port 22 when an IP succesfully port-knocks in).
>As I've argued elsewhere, obscuring your login service via non-standard ports or even a requirement to try several ports in sequence really only buys you security equivalent to lengthening your password by two characters per port. After all, TCP and UDP port numbers are limited to 65536 distinct values, within the scope of a 16-bit value. Moving your service to a non-standard port means that the would-be intruder has to guess a two-byte value. Introducing a sequence of ports buys you the added obscurity of two bytes per port.
It needs to be pointed out that it is actually worse than that. Guessing a password is O(2^n) on the length of the password. Making the attacker guess a random m bit value before starting to guess passwords is O(2^m + 2^n). To put numbers behind this, a password with 32 bits of entropy has ~4 billion possible combinations, 16 bits of random port + 32 bits of password has 65536 + ~4 billion possible combinations (also known as ~4 billion), while a 34 bit password would have ~16 billion possible combinations.
It's true that just changing the port doesn't add much to protect against brute-force attacks, but it's not the full story. Many automatic scanners try port 22 and then give up for that host. I've found that changing the port means that I'm hit but far fewer scans.
One could also use port knocking. Using just a single port it would add the 16 bits of randomness making it 32 bits of extra randomness which is significant.
Another advantage of using a different port is that it's often quite easy to detect port scans against a host so an automated tool can easily just block the scanning IP. Slow scans exist but if someone is willing to take that amount of time then there's not much you can do to stop them from eventually finding your service.
As we all know security through obscurity only buys you time like the article points out. Please correct me if I'm wrong but a pretty simple solution exists here. I run SSH over port 22 and do the following which I think is a pretty reasonable and safe solution (again, please correct me if I'm wrong):
1. Configure a decent firewall, edit iptables and disable anything you aren't or don't plan to use.
2. Disable root login completely.
3. Install fail2ban just in case and set it to block IPs of failed attempts for 2 to 24 hours
4. Use key based authentication and disable SSH logins using passwords altogether.
I'd recommend going a step further on number 4 and put a strong password on your key. A lot of people believe that key based authentication in and of itself is enough but if you somehow leak your keys and there's no password on them then an attacker has just easily gained access to your machine. Now I'm guilty of not using a password with my keys because like a lot of people it feels like it defeats the purpose but you can actually set things up so that you only need to enter your password once and it won't ask you for it again for a while just like the sudo "grace period" which lets you sudo without a password after you've entered it once. I do plan to give my keys a password and stop being so lazy in the very near future.
I know the Linode library as well as a few posts that have made it to the front page here explain how to do this. Here are the links:
When I ran an ssh server on port 22 (with root login and password login turned off), I would see quite a lot of random log-in attempts using root and various stupid passwords.
When I switched to some other port, they stopped. Less noise in my logs, hurray! Now, if I see something weird in my logs, chances are it's important.
"As we all know security through obscurity only buys you time..."
No. Your definition of "security through obscurity" is totally wrong, so your sentence makes zero sense.
If I say: "This server uses port-knocking, you must on three ports between 1..65535 in the correct order before you can attempt to login using SSH on an unknown port"
There is absolutely zero security through obscurity here.
Just as there's zero security through obscurity when someone says: "I've got a server with SSH on port 22 open, you need a login/password to get in". Attackers do not know the login/password but that is still certainly not "security through obscurity".
Just as attackers do not know which three-ports knocking sequence they should use to log in. All they know is that they'll first need to try to find the correct port-knocking sequence amongst the 65536 exp 3 possibilities before being able to try to find the SSH port and then try to force the login/password.
Just as using a random SSH port is certainly not "security through obscurity".
Security through obscurity is when there's a design or an implementation detail that is obscured. Like when a snake-oil vendors creates a "one-password to store them all" website and doesn't say how it's doing the storing / encryption / authentication / etc.
That is security through obscurity.
Saying: "You need to know the secret root password to login" or "You need to know the secret port-knocking sequence before the SSH port shall allow" is not, has never been and shall never be "security through obscurity".
Bruteforcing 65536^3 sequences is trivial compared to bruteforcing an actual ssh login; what protection you get comes from the fact that the attacker doesn't know there's port-knocking at all. So it really is just obscurity.
The only downside to this is that you send more data with spiped.
"""
Can significantly increase bandwidth usage for interactive
sessions: It sends data in packets of 1024 bytes, and pads
smaller messages up to this length, so a 1 byte write could
be expanded to 1024 bytes if it cannot be coalesced with
adjacent bytes.
"""
-- https://code.google.com/p/spiped/source/browse/trunk/README
More secure, but more overhead. That said, I love spiped. I use it to secure a few mysql replication streams and a couple other things. Works great.
I wonder if there is anything like spiped that provides something similar to openvpn's tls-auth (HMAC auth) functionality, for protocols that already provide encryption.
It would also be nice if SSHd had an option to block an IP address after a certain number of failed attempts. Sure, you can hack something together with iptables but that's just horrible.
Fail2ban is massively heavyweight on a cheap virtual server however, easily consuming half your memory if you aren't careful, and still obscene amounts of RAM for the functionality, with tight ulimits.
Maybe I'm old-fashioned, but I find even 4MB complete overkill for the required functionality.
All the damn thing needs to do is keep a couple of running counters on a short buffer of IPs and run iptables when limits are met, and a periodic parse of a log file. This feels like something where 64k ought to be enough for anyone, much less 640k!
Sure, we can get by with a fifth of a gigabyte of swap space for this task. Ugh. I've spent too much of my life in debugger CPU views. Jack's quivering tower of abstractions writhes in repulsion.
It's written in python, which takes about about 2m-5m just to get out of bed with nothing loaded or running. (I don't consider that a lot BTW, not a ding on python.)
There's about 200K of source code, but basically all the overhead is the python runtime.
(The memory usage of python doing nothing varied on different machines, but was always virtually identical to the usage of fail2ban.)
Also, the virt usage is mostly large memory mapped logfiles, not actual swap usage.
Another thing that occasionally cheeses me off is the restriction on canonical ports < 1000 to user 0. Yes, I know it's standardized. Yes, I know that when it was codified the world looked very, very different. It's still annoying and requires cargo-cultish hoop-jumping (albeit well understood hoop jumping) to run a decently secure service.
Do yourself a favor and use public key authentication rather than passwords. It's both more secure and (together with ssh-agent) more convenient.
Unless you're logging in from other people's machines a lot that is (where you would need to access your private key from a USB stick) but that's obviously not a good idea anyway.
The whole point of ssh is to be able to log into one's machine from elsewhere on the wide internet. I find it's precisely when I'm somewhere public (i.e. coffee shop or public transport wifi) that I want access to my home machine - on my work machine (i.e. in the office) anything I need is already there. If you don't need it to be publicly accessible, why would you be running sshd at all?
Before I can respond to that, I think there's a misunderstanding about what "public service" means. HTTP is a public service: you open it up to the world, and want anyone to be able to connect to it. It is intended and hoped that as many people use it as possible. If your website is slashdotted, then that's GREAT! In contrast, I don't want 100000 people to try logging in over SSH to my private server. To put it another way, SSH is only a public service in the cases of:
* CVS over SSH
* rsync over SSH
* Commercial SSH tunnels
Logging into my authoritative nameserver over SSH, however, is not a public service. And since it's not a public service -- that is, intended for the public -- I don't treat it like one.
If you're trying to tell the rest of us something you're going to have to be more concrete. So you "don't treat it like a public service". Great. What does that actually mean? ("I don't make it accessible on a public port from the public internet" was the most obvious technical interpretation, but it sounds like you didn't mean that)
You could block all but whitelisted IPs at your firewall, then get a VPN and add the endpoint IP to your whitelist. This way ssh (and anything else you don't want the public to access) is protected from random drive-bys, but you can still get to it from pretty much anywhere.
VPNs are a good idea in general if you are doing anything from a public access point that involves logging in.
As far as I can tell, SSH is my VPN. What would I get from a VPN that I don't get with SSH? And whatever VPN solution I used would still have to offer me a way to log in to the VPN from random public IPs, on a standardized port (or via some standardized discovery mechanism) - so I don't see how it could possibly be any more secure.
To get back to the point of the original article: ssh does not protect your server from getting hit by drive-by ssh login attempts.
In terms of security in depth, VPN provides another layer. If someone gets your VPN credentials, all they've done is given themselves a new endpoint, not gained access to any of your stuff.
VPN also protects web surfing, which ssh does not.
>In terms of security in depth, VPN provides another layer. If someone gets your VPN credentials, all they've done is given themselves a new endpoint, not gained access to any of your stuff.
One strong layer is better than two weak ones. If you're willing to remember 20 characters, a 20 character ssh password is much safer against these brute force attacks than 10 character VPN password + 10 character ssh password.
(as for non-bruteforce attacks, if someone compromises the VPN software they now have access to your home box without needing a second attack, so it comes down to whether the VPN software is more or less likely than SSH to have bugs - and my impression is that the SSH codebase is possibly the most thoroughly audited in the world)
>VPN also protects web surfing, which ssh does not.
Non-https traffic is going to be unencrypted over the open internet anyway, so I see no harm in it being unencrypted on the cafe network. (And if you're worried about being under surveillance, routing all your traffic via your home internet connection makes that easier than using a variety of public access points).
I meant a commercial VPN service. I agree that if you're just VPNing into the same box that is running ssh, it's no more secure than ssh by itself.
With the commercial VPN service, you run your own server exactly the same way as before, but restrict ssh access to only your VPN endpoint IP. Now your attack surface is way way smaller. (And your ssh logs are nice and clean.)
> Non-https traffic is going to be unencrypted over the open internet anyway, so I see no harm in it being unencrypted on the cafe network.
It's just so much easier to sniff traffic on unsecured WiFi than anywhere else. Not every site you log into implements https, or implements it correctly, and there are a variety of nasty things that can be done with that.
Think of running a Wordpress blog on your own server...how many people bother to force https for that? But if someone hijacks your Wordpress admin session, they've basically got your whole server.
The whole hi/low ports as security was always bogus. From day one. Ask those who implemented it from that era, and they will now agree. If someone had a shell account on a machine, they could have 'root'. If they had root, they can bind low ports (and anything else). The fact that Linux still requires a root user to bind a listener to a <1024 port was just the Linux guys being conservative. They wanted adoption, not someone saying 'Linux is insecure because they let non root bind to low ports'. They now have adoption, and quite a bit of legacy decisions still in there.
I used to fume about 15 years ago. These days, I'm much more zen about this. (or trying to be zen).
Also, I welcome posts like this. I've come to understand that what was once understood by many, may not be when you add 10 or 5 years. For example, the recent HN post from dadgum.com about C's most powerful operator being 'switch'. This is well known. However, maybe there are 17 or 15 year olds who lurk HN. In order for them to learn, they should be exposed to that knowledge.
So, while we are trying to help one another, here is some advice. One really good way to run sshd securely is to use a different operating system other than Linux. This isn't because Linux is bad, it is just that certain decisions were made that will not change. People might extrapolate what I just said too far. Let me illustrate this as a conversation for entertainment.
world says: 'drudru just said don't run linux anywhere'
drudru says: 'Nope. What I'm saying is if you need high security, yet open to the world, sshd install, don't run it on Linux. Run it on an OS and config designed for security. You can still use Linux and other OSs for other things.'
world says: 'Ok, if I do that, how do I ssh to my Linux hosts?'
drudru says: 'Since your sshd host is running not on Linux and it is secure, you can use it to login to your other hosts. You should run it on a static IP address. Then you will only allow ssh in to all your other hosts from that known secure IP and host key. You can have multiple jump machine/static IPs, say 2 on different networks for redundancy.'
world says: 'I've heard OpenBSD was secure. I don't want to learn OpenBSD, FreeBSD, etc.'
drudru says: 'You should just run on Heroku or something equivalent. It will allow you to outsource the entire problem.'
world says: 'I cannot run my Hadoop,Cassandra, etc. on XYZ cloud platform.'
drudru says: 'I am pretty sure you can. There are a lot of new solutions out there if you get a moment to search.'
ALTERNATE ENDING
world asks: 'Can I run sshd on Windows securely?'
drudru says: 'You should just run on Heroku or something equivalent. It will allow you to outsource the entire problem.'
RING RING
drudru says: 'hey, good luck with that. gotta go.'
Not even that. It's like a separate two-byte password because you get to guess and confirm the port separately from the password.
Lengthening your password by N bits multiplies the number of necessary guesses by 2^N. Having a separate N bit password adds 2^N to the number of of necessary guesses. So if your real password's effective key length is more than 16 bits, using a random port effectively adds less than 1 bit of entropy.
Also, rate-limiting port scans is way harder to do than rate-limiting authentication.