Port knocking is stupid. It violates Kerckhoffs’s principle¹. If you want more secret bits which users need to know in order to access your system, increase your password lengths, or cryptographic key sizes. If you want to keep log sizes manageable, adjust your logging levels.
The security of port knocking is also woefully inadequate:
• It adds very little security. How many bits are in a “secret knock”?
• The security it does add is bad: It’s sent in cleartext, and easily brute-forced.
• It complicates access, since it’s non-standard.
1. <https://en.wikipedia.org/w/index.php?title=Kerckhoffs%27s_pr...>
Security-by-obscurity is dumb, yes. But in the context of supply-chain exploits in the theme of this xz backdoor, this statement is also myopic:
> If you want more secret bits which users need to know in order to access your system, increase your password lengths, or cryptographic key sizes.
If your sshd (or any other exposed service) is backdoored, then the "effective bits" of any cryptographic key size is reduced to nil. You personally cannot know whether or not your exposed service is backdoored.
Bottom-line is: adding a defense-in-depth like port knocking is unlikely to cause harm unless you use it as justification for not following best-practices in the rest of your security posture.
Chaining multiple different login system can make sense. A more sensible solution over port knocking would be an alternative sshd implementation with a tunnel to the second sshd implementation. Naturally the first one should not run as root (similar to the port knocking daemon).
That way it would not be in clear text, and the number of bits of security will be order of magnitude larger even with very simple password. The public facing sshd can also run more lightweight algorithms and disable loggings for lower resource usage.
Regardless if one uses two sshd or port knocking software, the public facing daemon can have backdoors and security bugs. If we want to avoid Xz-like problems then this first layer need to be significant hardened (With SELinux as one solution). Their only capability should be to open the second layer.
Chaining login methods would not help if the outermost login method is backdoored with an RCE.
That is where hardened with SELinux comes in. The outermost login method only capability beyond communication in the initial connection should be to open a tunnel to the next level, so any remote code execution could only execute the code to open the tunnel.
Building security in depth correctly is not simple. It takes work to construct layers so that one compromised layer do not cause whole system failure.
I don't think I agree. This backdoor means that it doesn't matter how long your key lengths or cryptographic key sizes are; that's kinda the point of a backdoor. But an automated attempt to find servers to exploit is not going to attempt something like port knocking, or likely even looking for a sshd on a non-standard port.
Kerckhoff's law goes (from your link):
> The principle holds that a cryptosystem should be secure, even if everything about the system, except the key, is public knowledge.
With this backdoor, that principle does not hold; it's utterly irrelevant. Obscuring the fact that there even is a ssh server to exploit increases safety.
(I dislike port knocking because of your third point, that it complicates access. But I don't think your assertions about its security principles hold water, at least not in this case.)
(Ultimately, though, instead of something like port knocking or even running sshd on a non-standard port, if I wanted to protect against attacks like these, I would just keep sshd on a private network only accessible via a VPN.)
> This backdoor means that it doesn't matter how long your key lengths or cryptographic key sizes are; that's kinda the point of a backdoor.
If we’re talkning about this specific backdoor, consider this: If the attacker had successfully identified a target SSH server they could reasonably assume had the backdoor, would they be completely halted by a port knocker? No, they would brute-force it easily.
Port knocking is very bad security.
(It’s “Kerckhoffs’s <law/principle/etc.>”, by the way.)
Security through obscurity is only a problem if obscurity is the main defense mechanism. It's perfectly fine as a defense-in-depth. This would only be an issue if someone did something stupid like set up a passwordless rlogin or database server expecting port knocking alone to handle security.
Also as pointed out elsewhere, modern port knocking uses Single Packet Authorization which allows for more bits. It's also simpler and uses a different mechanism than ssh (which due to its age, has historically supported a bunch of different login and cryptography techniques), which reduces the chance that an attacker would be able to break both.
Port knocking is definitely dumb, but "increase your password lengths, or cryptographic key sizes" does nothing if your ssh binary is compromised and anyone can send a magic packet to let themselves in.
Strict firewalls, VPNs, and defense-in-depth is really the only answer here.
Of course, those things all go out the window too if your TCP stack itself is also compromised. Better to just air-gap.
Many people argue that a VPN+SSH is a reasonable solution, since it uses two separate implementations, where both are unlikely to be compromised at the same time. I would argue that the more reasonable option would be to split the SSH project in two; both of which validates the credentials of an incoming connection. This would be the same as a VPN+SSH but would not convolute the network topography, and would eliminate the need for two keys to be used by every connecting user.
However, in this case, the two-layer approach would not be a protection. Sure, in this case the SSH daemon was compromised, and a VPN before SSH would have protected SSH. But what if the VPN server itself was compromised? Remember that the SSH server was altered, not to allow normal logins, but to call system() directly. What if a VPN server had been similarly altered? This would not have protected SSH, since a direct system() call by the VPN daemon would have ignored SSH completely.
It is a mistake to look at this case and assume that since SSH was compromised this time, SSH must always be protected by another layer. That other layer might be the next thing to be compromised.
>This would not have protected SSH, since a direct system() call by the VPN daemon would have ignored SSH completely.
I don't know how VPNs are implemented on Linux, but in principle it should be possible to sandbox a VPN server to the point where it can only make connections but nothing else. If capabilities are not enough, ebpf should be able to contain it. I suspect it will have full control over networking but that's still very different from arbitrary code execution.
That would be possible, yes, but it’s not the current situation. And since we can choose how we proceed, I would prefer my proposal, i.e. that the SSH daemon be split into two separate projects, one daemon handling the initial connection, locked-down like you describe, then handing off the authenticated connection to the second, “inner”, SSH daemon, which also does the authentication, using the same credentials as submitted by the connecting user. This way, the connecting user only has to have one key, and the network topology does not become unduly twisted.
Huh, I briefly looked at the documentation for UsePrivilegeSeparation option and it looks very similar to what you're describing. Interesting why it didn't prevent this attack.
Note that UsePrivilegeSeparation is no longer an option; it is mandatory since OpenSSH 7.5, released seven years ago.
Best practice would have your internet exposed daemon (vpn or ssh) running a fairly locked down box that doesn’t also have your valuable “stuff” (whatever that is) on it.
So if someone cracks that box, their access is limited, and they still need to make a lateral move to access actual data.
In the case of this backdoor, if you have SSH exposed to the internet on a locked down jump box, AND use it as your internal mechanism for accessing your valuable boxes, you are owned, since the attacker can access your jump box and then immediately use the same vulnerability to move to an internal box.
In the case of a hypothetical VPN daemon vulnerability, they can use that to crack your jump box, but then still need another vulnerability to move beyond that. Not great, but a lot better than being fully owned.
You could certainly also accomplish a similar topology with two different SSH implementations.
Sure, but that violates the end-to-end principle.