From 28097602dcf26885624f5cf66acfbdd7c5a9eda9 Mon Sep 17 00:00:00 2001 From: Wonderfall Date: Sat, 9 Apr 2022 20:01:14 +0200 Subject: [PATCH] improvement --- content/posts/openssh-fido2.md | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/content/posts/openssh-fido2.md b/content/posts/openssh-fido2.md index f8c381c..1b5fe4a 100644 --- a/content/posts/openssh-fido2.md +++ b/content/posts/openssh-fido2.md @@ -5,19 +5,21 @@ draft: false tags: ['security', 'linux'] --- -Passwordless authentication with OpenSSH keys has been the *de facto* security standard for years. SSH keys are more robust since they're cryptographically sane by default, and are therefore resilient to most bruteforce atacks. They're also easier to manage while enabling a form of decentralized authentication (it's easy to painlessly revoke them). So, what's the next step? And more exactly, why would one need something even better? +Passwordless authentication with OpenSSH keys has been the *de facto* security standard for years. SSH keys are more robust since they're cryptographically sane by default, and are therefore resilient to most bruteforce atacks. They're also easier to manage while enabling a form of decentralized authentication (it's easy and painless to revoke them). So, what's the next step? And more exactly, why would one need something even better? The main problem with SSH keys is that they're not magic: they consist of a key pair, of which the private key is stored on your disk. You should be wary of various exfiltration attempts, depending on your theat model: - If your disk is not encrypted, any physical access could compromise your keys. - If your private key isn't encrypted, malicious applications could compromise it. -- Even if your private key is encrypted, malicious applications could register your keystrokes. +- Even with both encrypted, malicious applications could register your keystrokes. All these attempts are particularly a thing on desktop platforms, because they don't have a proper sandboxing model. On Windows, non-UWP apps could likely have full access to your `.ssh` directory. On desktop Linux distributions, sandboxing is also lacking, and the situation is even worse if you're using X.org since it allows apps to spy on each other (and on your keyboard) by design. A first good step would be to only use SSH from a trusted & decently secure system. Another layer of defense would obviously be multi-factor authentification, or the fact that you're relying on a shared secret instead. We can use FIDO2 security keys for that. That way, even if your private key is compromised, the attacker needs physical access to your security key. TOTP is another common 2FA technique, but it's vulnerable to various attacks, and relies on the quality of the implementation on the server. -Fortunately for us, [OpenSSH 8.2](https://www.openssh.com/txt/release-8.2) (released in February 2020) introduced native support for FIDO2/U2F. Most OpenSSH distributions should have the middleware set to use the `libfido2` library, including portable versions such as the one [for Win32](https://github.com/PowerShell/Win32-OpenSSH). Basically, `ssh-keygen -t ${key_type}-sk` will generate for us a token-backed key pair. The key types that are supported depend on your security key. Newer models support should support both ECDSA-P256 (`ecdsa-sk`) and Ed25519 (`ed25519-sk`). If the latter is available, you should prefer it. +Fortunately for us, [OpenSSH 8.2](https://www.openssh.com/txt/release-8.2) (released in February 2020) introduced native support for FIDO2/U2F. Most OpenSSH distributions should have the middleware set to use the `libfido2` library, including portable versions such as the one [for Win32](https://github.com/PowerShell/Win32-OpenSSH). + +Basically, `ssh-keygen -t ${key_type}-sk` will generate for us a token-backed key pair. The key types that are supported depend on your security key. Newer models support should support both ECDSA-P256 (`ecdsa-sk`) and Ed25519 (`ed25519-sk`). If the latter is available, you should prefer it. To get started: @@ -33,7 +35,9 @@ You can also generate a resident key: ssh-keygen -t ed25519-sk -O resident -O application=ssh:user1 ``` -`-O resident` will tell `ssh-keygen` to generate a resident key, meaning that the private "handle" key will also be stored on the security key itself. This has security implications, but you may want that to move seamlessly between different computers. In that case, you should absolutely protect your key with a PIN beforehand. `-O application=ssh:` is necessary to instruct that the resident key will use a particular slot, because the security key will have to index the resident keys (by default, they use `ssh:` with an empty user ID). If this is not specificed, the next key generation might overwrite the previous one. Resident keys can be retrieved using `ssh-keygen -K` or `ssh-add -K` if you don't want to write them to the disk. +`-O resident` will tell `ssh-keygen` to generate a resident key, meaning that the private "handle" key will also be stored on the security key itself. This has security implications, but you may want that to move seamlessly between different computers. In that case, you should absolutely protect your key with a PIN beforehand. `-O application=ssh:` is necessary to instruct that the resident key will use a particular slot, because the security key will have to index the resident keys (by default, they use `ssh:` with an empty user ID). If this is not specificed, the next key generation might overwrite the previous one. + +Resident keys can be retrieved using `ssh-keygen -K` or `ssh-add -K` if you don't want to write them to the disk. Next, transfer your public key over to the server (granted you have already access to it with a regular key pair): @@ -49,6 +53,6 @@ PubkeyAcceptedKeyTypes ssh-ed25519,sk-ssh-ed25519@openssh.com Adding `sk-ssh-ed25519@openssh.com` to `PubkeyAcceptedKeyTypes` should suffice. It's best practice to only use the cryptographic primitives that you need, and hopefully ones that are also modern. This isn't a full-on SSH hardening guide, but you should take a look at the [configuration file GrapheneOS uses](https://github.com/GrapheneOS/infrastructure/blob/main/sshd_config) for their servers to give you an idea on a few good practices. -Restart the `sshd` service and try to connect to your server using your key handles (by passing `-i ~/.ssh/id_ed25519_sk` to `ssh` for instance). If that works for you (your FIDO2 security key should be needed to derive the real secret), feel free to remove your previous keys from `.ssh/authorized_keys` on your server. +Restart the `sshd` service and try to connect to your server using your key handle (by passing `-i ~/.ssh/id_ed25519_sk` to `ssh` for instance). If that works for you (your FIDO2 security key should be needed to derive the real secret), feel free to remove your previous keys from `.ssh/authorized_keys` on your server. If you don't have a security key, you can buy one from [YubiKey](https://www.yubico.com/fr/store/) (I'm very happy with my 5C NFC by the way), [Nitrokey](https://www.nitrokey.com/), [SoloKeys](https://solokeys.com/) or [OnlyKey](https://onlykey.io/) (to name a few). If you have an Android device with a hardware security module (HSM), such as the Google Pixels equipped with Titan M (Pixel 3+), you could even use them as bluetooth security keys. \ No newline at end of file