Security of ssh across a LAN, public key versus password
openssh at tr.id.au
openssh at tr.id.au
Tue Oct 22 07:24:46 AEDT 2024
Hi Chris,
> There's a couple of headless systems on the LAN where login security
> is important to me and I've been thinking about the relative merits of
> password and public-key authentication.
> <snip>
At home, I have a smaller LAN than you, but at $DAYJOB I work with much bigger fleets. Whether at home or work, everything is Linux-based, and OpenSSH is the primary form of remote access. I say these things to let you know that I appreciate your concerns, and although I've seen a variety of approaches, there is a surprising amount of commonality to "good enough" practice (I don't say "best practice" because I know cybersecurity wonks like to go to town as though we're all working for the NSA).
Firstly, I've seen a lot of security incidents affecting customer virtual machines, and some of these incidents involved the OpenSSH service on the customers' virtual machines. However, every single time when the incident was attributable to unauthorized ssh access, it was because the customer changed the default settings. The images we provided were configured to only offer keypair authentication by default; some customers deliberately change the default setting to permit passphrase authentication, and that's when they get hacked. Note that the keypairs they did use were typically generated via the openstack dashboard, which doesn't even add a passphrase to the private key. So, I've seen plenty of evidence that keypairs are much, much better than password auth, even in the very relaxed situation where the keypair is unencrypted by default.
Furthermore, for our compute host fleets and control plane nodes, I've never seen password auth enabled anywhere I've worked. Instead all engineers have been expected to use keypair authentication for everything. There wasn't even much rigor about this, eg I'm sure some operators I've worked with at various points through history have kept unencrypted private keys on their local storage. And yet, even with a sometimes relaxed approach, I've never seen a security incident arise due to unauthenticated ssh access to the infrastructures.
tl;dr In my experience, you get a lot of bang for your buck simply by denying all password authentication, and only permitting keypair authentication. If you're already doing this much, then you're on the right track.
Yes, you can and should take extra steps to harden your private key. Put a passphrase on it and keep the passphrase in a password store; use FIDO2 keys such as ed25519-sk; back the key with GPG; and this list isn't exhaustive. Personally I use a mix of the first two approaches: often preferring ed25519-sk (or certificates backed by ed25519-sk), but falling back to encrypting the key with a random passphrase when some combination or sk keys or certs is contra-indicated (eg old systems which don't yet understand sk.)
On your own LAN, where you presumably control everything and don't need to compromize with anyone, you could consider my favorite approach, which is configure everything to accept certificate authentication, and only permit certificates which have been signed by an sk key. This gives you seamless time-limited access that is backed by 2FA. It does, however, require buying at least one hardware key such as a Yubikey. It also assumes that all your copies of OpenSSH are on version >= 8.2. And if you haven't used certs or sk keys before, there is a bit of a learning curve when you set either of these up for the first time.
There is another benefit to keypairs, which is you don't need to keep entering your passphrase. Using either proxyjumping or agent forwarding, keypairs allow much more seamless access. They are just so much more convenient that I would still prefer keypairs even if the security wasn't any better.
There is also much to be said for preventing anyone from even attempting unauthorized access in the first place. If no one from outside your LAN needs to get in, then simply deny port 22 at the level of your outward-facing firewall. If some external access is required, then see if you can generate an allowlist. I've had good experiences using a cron job to generate ipsets based on whois data for specific ISPs. Then whoever is with that ISP can get access, but no one else. I found this 100% killed botnet noise from my logs.
And, putting the most important bit last, always consider your cybersecurity threat model before deciding what are the best measures to implement. If you need to worry about sophisticated and well-resourced threats who are strongly motivated to get into your LAN for some reason, then it's a whole different ballpark to just needing to stop some random botnets. If you're only worried about getting hacked by random botnets, then almost 100% of what you need is covered by just avoiding passphrase authentication, preferably with a firewall allowlist. Whereas, if you're on the hitlist of a nation-state, then you also need to think a lot more about physical security and supply chains, in addition to whatever worries you have about configuring OpenSSH.
tl;dr Disable password auth, preferably put 2FA on your keypair auth, and preferably deny access before it even has a chance to try authenticating, and you should be fine for a typical mom-and-pop LAN.
Cheers,
Tim
More information about the openssh-unix-dev
mailing list