I thought about this quite a bit before at various times so this is just my brain dump of it but the summary is that I think obscurity provides a very valuable vector in defense posture of any system. In particular, it serves as a:
Deterrent - By making you seem not easily visible to attackers (like a port-remap of common services), increasing the difficulty to be exploited, and/or increasing the perception of cost/benefit from the attacker’s point of view.
Attacker “Tarpit” - Writing exploits and executing attacks for a system is usually the most predictable and “cookie-cutter” part of an attack while all the rest is information collection. Having a layer of obscurity adds to the time needed for that latter part.
If you combine a layer of obscurity with baits and/or honeypots, I believe that you can thwart all but the most strictly focused-on-you attackers.
Imagine an Internet-facing server but instead of just moving the sshd port, you just proxy those connections to a DMZ throwaway honeypot/tarpit machine with a tarpit while your real SSH daemon is hidden behind port-knocking logic on a completely different port from that. My guess would be that you would decrease your chance of successful attack by orders of magnitude unless the attacker knew the exact topology of this setup.
Then to continue this, what if you then intentionally change some sshd protocol handshake to intentionally mislead attack tools to make it not fingerprint it as “ssh”? What if you make sshd selectively stealth-proxy you to a tarpit depending on the client info (eg. version, ip blocks, country of origin, etc)? All of these would highly likely reduce attacks by orders of magnitude even further and they all leverage the fact that the attacker is lacking critical information required for a successful attack.
This all however increases dev/ops/maintenance/support costs and often it also increases pain for the system’s real user trying to utilize the services obscured so it’s not without its downsides. Also, after the obscured knowledge becomes public (which it inevitably does), the whole layer loses most of its efficacy so it’s advantageous to have it be created in a modular way for easier removal after that happens.
Security by Obscurity that originates from a passive approach - the architecture / algorithm is new and doesn’t look like anything else and we don’t have to work to better secure it, is completely different than a proactive approach of Security by Obscurity - code obfuscation process for example.
As mentioned, obscurity can’t be used as a single layer… It must enforce existing sound security layers.
It is a “nice to have” layer. Sound security layers or controls should be prioritised.
Obscurity has it’s own operational challenges - tracking different user names on different machines; maintaining more complex network architecture or naming patterns…
Spotted obfuscating efforts attract unwanted attention - imagine spotting 1000 open SSH ports open on port 22, while one is open on port 2222… I’d start with the one on 2222…