Before going any further, you should probably read the linked article. In conclusion, however, the author makes a point that -
Security by obscurity is not enough by itself. You should always enforce the best practices. However, if you can reduce the risk with zero cost, you should do that. Obscurity is a good layer of security.
Is the cost zero?
It’s a bad idea to use it as a single layer of defense. If the attacker passes it, there is nothing else to protect you. But it’s actually would be good to use it as an “additional” layer of defense. Because it has a low implementation cost and it usually works well.
The entire premise of the article seems to be based on an assumption that adding a layer of obscurity to an otherwise secure system can serve as a good layer of additional “security”, since the cost is low or zero anyway, so why not do it, right?
In the majority of cases, however, things are not as simple. In most cases, there are better alternatives.
Nothing is ever for free
Bear with me here. It is relevant. I promise.
A well-known property of all things is that things generally tend to have some kind of state. This applies almost universally to all everything around us, regardless if we are considering information security or squeezing juice from oranges.
Transitioning things from one possible state to another always comes at a cost. This cost could be one-time - you squeeze your oranges, you get your juice, and you are all happier for it - but you expended some energy in the process. It’s a trade-off. Oh well.
The transitioning cost can also be postponed - you got your orange juice, to which, it turns out, you are mildly allergic. You love orange juice, so you will proceed to enjoy it immediately, but the consequences will come eventually, in the form of a mild annoying allergic reaction.
Another kind of cost you can incur while changing state is continuous cost - to be able to make some juice, you first need to spend some money on oranges. And you will have to do so every time you want some more.
Simply put, transitioning things from state A to state B always and universally comes with some kind of cost, to be paid immediately, later, and possibly continuously forever.
As a general rule, most if not all “security through obscurity” approaches tend to have non-zero cost both immediately and continuously. The reason for it is that in information technology, most things tend to have some kind of “default” state (think, default configuration), that once changed needs to be considered and propagated further to anyone and anything interfacing these systems.
So the cost can’t be zero. In the long run, it can’t even be a low cost, once you consider the consequences of your changes in the context you are.
Let’s talk ports
Probably the most discussed example of security through obscurity, and hell, this discussion is probably as old as the concept of remote access itself is about changing default port allocations for web-facing services to avoid them being hit from public internet and to reduce the possibility of a system being compromised in one way or another.
We will also reuse the SSH service for our example of a threat modeling exercise.
Before doing anything, however, we need to consider the goal of what we are doing - what is the purpose of changing the default port allocation? The answer the author proposes is to reduce the likelihood the SSH service will be hit by bots from the public internet. This is a broken premise on its own, but we will get to that later.
In this context, let us consider what the benefits of having SSH on a non-default port are -
- Less bot traffic and noise from the public internet.
- The likelihood of the service being compromised due to poor credentials, a vulnerability in the service daemon itself - reduced.
Doing this however will not be for free. Remember that this is a change of state, so it can’t be free.
- We need to reconfigure the SSH to use a non-default port.
- We need to reconfigure every other service using SSH to use the non-default port if any.
- We need to inform everyone who might be using the SSH service on this server to use the non-default port.
- Every time we interface with the service we need to use the non-default port ourselves.
- Everyone else using this service also needs to use the non-default port.
From the above, we can already see that the cost is not zero, not even close. Considering in the larger context of things, the cost might even increase depending on the wider context - how many users there are? Who is using the service? Will this increase the support cost? Will people forget? What port number to use? Should you have more than one server, would you use one port for all of them or a random one for each of them? What about services that might expect the port to be the default and can’t have this behavior changed?
The broken premise
All things considered, at this point, you might be thinking that, well fine, the costs are there, sure, but we can tolerate these costs, for the sake of increased security, right?
The thing is, with our non-default port problem we have been operating on a broken premise all along. The goal we set before is invalid, and we have inadvertently invented a solution to a problem that should not exist in the first place. Let us consider it.
What is the goal we have been aiming for so far? As previously defined, it is to prevent our SSH service from being hit from the public internet, reduce the possibility of a system being compromised due to poor credentials and reduce the possibility of a system being compromised due to potential exploits in SSH software.
The problem with our “solution” to this problem is that it does not deliver for any of these, not really. The potential exploits are still there, we just moved the target for it to be less easy to discover. But someone still CAN discover it. What we have done is we have hidden the problem, not solved it.
This is especially bad because there are actual solutions to the problem that can both deliver on solving all of the issues we aimed for, and do it without incurring most of the perpetual cost the switching of ports approach would incur for us.
So what’s the solution then?
The best solution to a problem is usually not having the problem in the first place. Continuing our SSH line of examples, the solution would be to not have SSH exposed to the public internet in the first place and properly configuring the SSH service for a good balance of security and usability.
For this specific scenario, there are several solutions to explore - depending on your specific use case, private network overlays, VPNs, bastion hosts, static and dynamic firewall rules etc. are all valid options to consider.
Your goal here should be to prevent a possibility of access in the first place, not rely on the resource remaining obscured and not discovered by an adversary.
Besides, the above countermeasures would serve to not only isolate SSH, they would serve to isolate other services too.
It is not uncommon for hosts to have more than one service of something, and the problem example we have been exploring in the context of SSH applies equally to all of them. Consider a common web host with public 80,443, a MariaDB instance on 3306, RabbitMQ management on 15672, and finally SSH on 22.
Realistically you might want your 80 and 443 accessible from the public internet (clearly), your 3306 accessible to the host and YOU, and 15672, and 22 is available for you only.
In this context changing the ports would serve absolutely no purpose but annoy your own future self, and you would still need to implement better defenses for all these services anyway. But if you have these better defenses, does moving ports still make sense? No. Because you can’t access them from public internet anyway, so the problem is completely eliminated simply on the merit of having good practices implemented outright.
In threat modeling, your first and foremost consideration, as far as access patterns are concerned, should be - who needs access, where, and how do we prevent anyone else but the intended audience from accessing the service we are trying to lockdown. The usual answer here is private networking, firewalls, and other access controls that completely eliminate the issue instead of just hiding it.
The best approach you could possibly take is to eliminate potential issues at their source, instead of focusing on patching around the problem.
To explore a little further, let us re-evaluate the scenarios presented in the original article, and appropriate countermeasures to them.
I have a server that runs the SSH with it’s default port 22 and my credentials are: root:123456. What is the likelihood of being compromised?
Prevent root login and password policy should not allow for weak passwords, or better yet, public-key authentication is used. You could also have second-factor authentication required for increased security in the case of, especially valuable hosts. The only option remaining here is compromising the SSH server software iself.
SSH runs in port 22 and my credentials are utku:123456. What is the likelihood of being compromised?
No root, but the problem is still there. Again, eliminate weak passwords and enforce strong authentication.
SSH runs in port 64323 and my credentials are utku:123456. What is the likelihood of being compromised?
The likelihood of having the host being compromised is reduced but it is not eliminated. Not only will doing this introduce additional cost and inconvenience, but it will also give you a false sense of security. The problem is still not solved, not by any reasonable measure.
Let me introduce another scenario here. Completely made up, of course.
SSH is bound to port 22, my credentials are
foobar:strongpassword, and public-key authentication is required. My only way to escalate privileges is to provide my paressword and use
sudoor similar escalation tool.
Root access is disabled and SSH port is set to listen on a private network interface, accessible only from a redundant gateway hosts located in 2 different data centers.
Hosts in the private network are prevented from accessing each others SSH service - because there is never a need to allow my webserver to SSH into my database server, even with my credentials.
The gateway hosts have no other publicly exposed services other than the VPN software, and SSH port is also not publicly bound, and can only be reached from the VPN interface.
The port used by the VPN software is firewalled to only allow access from roughly the same geographical region you are physically located in, or if possible - limited to static IP ranges in your home/office/other somewhat trusted location exclusively.
Access to the VPN is audited and logged - all new connections from previously unknown origins result in alerts.
As a redundancy to everything above, tools and interfaces provided by the vendor are used - IPMI, rack remote VNC, etc. When unavailable, a special gateway can be deployed with another vendor sole purpose of which is to be able to access gateways.
With something like above, not only are you protecting your SSH services - you are also protecting anything else you might have on those hosts. Not only is this a better approach, but it is also a reusable one, saving you effort and time later. Besides, it completely eliminates the need for having oddball security through obscurity “solutions”.
Most security through obscurity practices can and will incur a significant cost, either immediately or eventually.
Your best bet in security, as with everything, is to consider your context and implement defenses that are appropriate to solve or better yet eliminate the problem. This will in turn eliminate the need to have security through obscurity practices in the first place.
If your solution to a problem does not feel like a solution, not really, then it probably isn’t and you should continue looking.
Obscurity, camouflage and concealment
I have received some feedback on the article and some argue that my view on the topic is too generalized, arguing that
Security by obscurity is a critical component of defense in depth, especially in order to properly apply passive security measures.
While I do agree that “hiding things” is a very important part of the security domain, I distinguish between “security through obscurity” and targeted, specific camouflage and concealment. Let me elaborate.
For me, the difference between security through obscurity and targeted camouflage, and concealment is largely intent and how deterministic the results are and can be. Concealment and camouflage is largely an intentional act aimed to achieve a deterministic result - hiding something, potentially with a reasonable guarantee of success, while obscuring something merely implies an attempt in concealment with a largely non-deterministic result. For me, this is a very important distinction between the two concepts - the effectiveness of camouflage and concealment is largely dependent on how well you implement it and how good your technique is, while security through obscurity relies largely on the incompetence of a third party.
Camouflage and concealment is all about technique - security through obscurity is a reliance on your adversary not being very good at what they do and hoping for your adversary to not do something that is commonly understood and often done. Camouflage and concealment will fail if your adversary is better than your defense baseline. Security through obscurity will fail if the skills and determination of your adversary are merely adequate.
To put it simply, painting a landmine green brings obvious value when hiding it in a foliage - this is camouflage. Painting a landmine bright red and covering it with leaves hoping for no rain or wind to blow the leaves off and hoping for your adversary to be blinded by the sun while looking for it is security through obscurity.
When considering the argument made in this article, I suggest you limit its scope of application to security through obscurity as explained here, even if you don’t personally agree with this particular definition.