If by "reuse" you mean having one key per client and using it with multiple servers, then yes, that is very common and being able to do that is arguably the entire point of public key cryptography. If you use a distinct key for every client-server pair you give up a lot of convenience and it becomes very difficult to use hardware-backed keys.
Not disagreeing with you, but I can think of two reasons why you might use distinct keys from the one client (and use ssh config to enforce the separation)
* You want to present different identities to the world and don't want them being conflated, eg separate your github hobby projects from your employer organization.
* You are using ssh certificate authentication, which isn't supported by GitHub yet, but you might be using it for other things, and GitHub should hopefully support it in the future. Since this relies on the name of the cert file matching the private key filename (eg id_ed25519-cert.pub corresponding to id_ed25519), you can't afaik have different certs active for the one key. Personally, I deal with this by simply having different private keys for different purposes, to avoid cert collision.
I'm guessing Andrew knows this, but for anybody else, in the particular case of Security Keys, they're specifically designed to create fresh public/private key pairs for each enrolment, exactly because of the privacy aspect. If you use your iPhone's fingerprint sensor to sign into both Facebook and GitHub not only do Meta and Microsoft not get the fingerprint, they don't even get a way to correlate these identities, they both just get the very minimum we could achieve, proof you are you still, whoever that is.
There are many points to public key cryptography. The important ones enable new capabilities, e.g. communicating with a counterparty that I’ve never met. But it also comes with downsides as you’ve documented.
Generating a new key pair is a moment of work and eliminates many of those problems.
Good question. It's so easy to set up .ssh/config and use a unique key per host I would think most people using SSH would be doing that? I don't know how common that is I guess.
I don't, and I don't suggest people do. Opsec on who controls your servers is compromised in a million other ways if you're a legit business, and even if it's important to hide, there's other low-hanging fruit.
That said, if I had any servers I controlled with other online identities, setting up keys for those identities would be sane, and if I valued privacy over convenience it's not that hard of a tradeoff. But I set up my new machines by typing in my github username to authorize all the pubkeys in there, and for the most part update my old machines the same way - curl -O https://github.com/gauntletwizard.keys ; vimdiff .ssh/authorized_keys gauntletwizard.keys
Host
Restricts the following declarations to be only for those hosts that match one of the patterns given after the keyword. The pattern is matched against the host name given on the command line.
It's cool that there's a sane description there, but what about examples?
> Good question. It's so easy to set up .ssh/config and use a unique key per host I would think most people using SSH would be doing that? I don't know how common that is I guess.
Because of the above, I'd say that it's not common because it's not documented in a discoverable enough way, or doesn't have enough examples - it appears that people don't care enough. If we wanted something else to be the case, then most tutorials on how to use SSH (say, the kind that people might stumble upon in DigialOcean's tutorials or whatever your search engine of choice might prioritize for a given query) should include this as an additional section.
The "normal" way is to have one keypair per device you use (unless using a key on a USB stick or something like that) and use that key for everything you do from that device (private, professional, etc.)
The key identifies you physically (not as an employee, open source contributor or whatever, specifically). And the reason for having different ones in different devices is that it's more secure to generate on each device without leaking it during transfer.
This way you can revoke the keys per device (e.g. you lose your laptop or have it stolen, revoke the key user@laptop and not the one user@university-lab).
I use the same passphrase everywhere (but, again, they're different keys).
The exploit actually performs a login, so you need a private key for that. It's a way for a hacker to track what machines (still) accept the key they've obtained.
Key-based authentication for SSH is often referred to as "pubkey authentication" (because you share your public key with the server) so that's probably where the title comes from. I don't think it exploits the same problem.
You're totally right, this is not the module I am thinking of. We used to do this exact step (yank all admins pubkeys from somewhere, and test logins with it to make an access map) in our pentests but now I am having trouble remembering what we used. Even better that there is a standalone tool then :)
Edit: here is the right module: `auxiliary/scanner/ssh/ssh_identify_pubkeys`, it is sort of nice in that you can give it a range of usernames, pubkeys, and hosts and it will try all combinations, and can be routed through your meterpreter pivots: https://www.rapid7.com/db/modules/auxiliary/scanner/ssh/ssh_...
"Exposes" is a strong word. Public keys are meant to be public. The only reason you might think twice about handing them over is they can de-anonymize you if you were practising identity hygiene.
Having a public register of public keys makes it easy to give people access to your organization, CI/CD etc.
Public keys are not meant to be public. They can be public in that making them public doesn't compromise the corresponding private keys. And generally making them public helps scale key management.
There are cryptographic protocols where public keys are kept private. For example TLS with client certificates (the client's certificate gets sent encrypted to the server). Ditto SSHv2 (the client need not reveal all its public keys, and it does get to authenticate the server before revealing its identity and public keys).
You're right, but my intention was to tackle unfounded nervousness, not to draft a technical document explaining all the ins and outs of keypair cryptography.
> "Exposes" is a strong word. Public keys are meant to be public
That's a very strong overstatement. With this argument, you could argue that data leaks involving names, emails, etc are fine, because emails and names are meant to be public.
Well, yeah, but I just got a chill realizing if I'm just dinking around trying to ssh into a random addresses that I'll be sending my public keys for auth which can be correlated.
Not a big deal, but I forgot about that leak, so "expose" made me read further and be reminded that clearly I am not a blackhat, or any color hat for that matter.
Ok, and then the users have root permissions to interact with the containers? Forgive me for asking but I am thinking about solving similar problems (access to containers via ssh) .. or maybe I should use Teleport instead.
Good point. These are test clusters that we use to reproduce customer issues. They usually have three or even just one node. It is in no way a production environment.
SSH keys can now be used to sign arbitrary content, so any github user with a published key is now able to publish verified content that can be verified offline.
Deploying services on non-standard ports has often been dismissed as security through obscurity, but this is just one example where defense in depth can provide protection even when other best practices are also followed. App-layer scanning across all ports would be substantially more complicated than just standard ports, and additional measures like port knocking could provide even better protection.
WireGuard does really well here, where an authentication failure is indistinguishable from no WireGuard service at all.
I wasn't aware a third party could identify _who controls_ a server with an ssh port... that's a security flaw for sure; definitely give attackers an exact idea of who they need to target for spearphishing!
Until then... I guess just throw wireguard in front of everything.....
44 comments
[ 3.9 ms ] story [ 118 ms ] thread* You want to present different identities to the world and don't want them being conflated, eg separate your github hobby projects from your employer organization.
* You are using ssh certificate authentication, which isn't supported by GitHub yet, but you might be using it for other things, and GitHub should hopefully support it in the future. Since this relies on the name of the cert file matching the private key filename (eg id_ed25519-cert.pub corresponding to id_ed25519), you can't afaik have different certs active for the one key. Personally, I deal with this by simply having different private keys for different purposes, to avoid cert collision.
It is good to be aware of the contents of these allowed credentials, and sweep unused entries. This article has a script that automates the procedure:
https://www.linuxjournal.com/content/ssh-key-rotation-posix-...
Generating a new key pair is a moment of work and eliminates many of those problems.
That said, if I had any servers I controlled with other online identities, setting up keys for those identities would be sane, and if I valued privacy over convenience it's not that hard of a tradeoff. But I set up my new machines by typing in my github username to authorize all the pubkeys in there, and for the most part update my old machines the same way - curl -O https://github.com/gauntletwizard.keys ; vimdiff .ssh/authorized_keys gauntletwizard.keys
Command line option:
Configuration option (.ssh/config): Random blog post that summarizes it: https://www.systutorials.com/how-to-choose-the-key-used-by-s...Curiously, the ssh.com (a more expected search result) docs aren't as useful: https://www.ssh.com/academy/ssh/config
It's cool that there's a sane description there, but what about examples?Slightly more in depth examples, in case anyone is curious about what other options there are: https://linuxize.com/post/using-the-ssh-config-file/
> Good question. It's so easy to set up .ssh/config and use a unique key per host I would think most people using SSH would be doing that? I don't know how common that is I guess.
Because of the above, I'd say that it's not common because it's not documented in a discoverable enough way, or doesn't have enough examples - it appears that people don't care enough. If we wanted something else to be the case, then most tutorials on how to use SSH (say, the kind that people might stumble upon in DigialOcean's tutorials or whatever your search engine of choice might prioritize for a given query) should include this as an additional section.
The key identifies you physically (not as an employee, open source contributor or whatever, specifically). And the reason for having different ones in different devices is that it's more secure to generate on each device without leaking it during transfer.
This way you can revoke the keys per device (e.g. you lose your laptop or have it stolen, revoke the key user@laptop and not the one user@university-lab).
I use the same passphrase everywhere (but, again, they're different keys).
In practice I have used metasploit's `auxiliary/scanner/ssh/ssh_login_pubkey` to do this: https://www.rapid7.com/db/modules/auxiliary/scanner/ssh/ssh_...
But standalone tools are always handy!
(Edited to add a better URL) (Second edit: I linked the wrong module here see my comment below for the correct one.)
Key-based authentication for SSH is often referred to as "pubkey authentication" (because you share your public key with the server) so that's probably where the title comes from. I don't think it exploits the same problem.
Edit: here is the right module: `auxiliary/scanner/ssh/ssh_identify_pubkeys`, it is sort of nice in that you can give it a range of usernames, pubkeys, and hosts and it will try all combinations, and can be routed through your meterpreter pivots: https://www.rapid7.com/db/modules/auxiliary/scanner/ssh/ssh_...
Does it have any purpose?
Having a public register of public keys makes it easy to give people access to your organization, CI/CD etc.
There are cryptographic protocols where public keys are kept private. For example TLS with client certificates (the client's certificate gets sent encrypted to the server). Ditto SSHv2 (the client need not reveal all its public keys, and it does get to authenticate the server before revealing its identity and public keys).
Hmm... I was under the impression that up until TLS 1.3 the client cert was sent in the clear during session negotiation...
That's a very strong overstatement. With this argument, you could argue that data leaks involving names, emails, etc are fine, because emails and names are meant to be public.
Not a big deal, but I forgot about that leak, so "expose" made me read further and be reminded that clearly I am not a blackhat, or any color hat for that matter.
Your average devops person? They will be happy when given a kubeconfig file linked to a role allowing them "kubectl exec" access to the workloads.
https://www.agwa.name/blog/post/ssh_signatures
WireGuard does really well here, where an authentication failure is indistinguishable from no WireGuard service at all.
Until then... I guess just throw wireguard in front of everything.....
ssh whoami.filippo.io - https://news.ycombinator.com/item?id=34301768 - Jan 2023 (79 comments)