Hacker Newsnew | past | comments | ask | show | jobs | submitlogin
An SSH server that knows who you are (twitter.com/filosottile)
152 points by tech234a on Feb 17, 2020 | hide | past | favorite | 55 comments


Discussed four and a half years ago, albeit the Tweet mentions having a new source of data: https://news.ycombinator.com/item?id=10004678

The top-rated comment mentioning having an "IdentitiesOnly yes" setting in your ~/.ssh/config is still relevant if you want to have multiple SSH keys and ensure that only specific hosts get specific keys.

EDIT: Also link is to a retweet, the source tweet is https://twitter.com/FiloSottile/status/1229093553269362689


The availability of developers' keys on github can be quite useful, a few jobs ago I leveraged this to auto-provision ssh bastion hosts with public keys for all of the collaborators of a repo. Much easier than getting people to send them to you and add them to authorized keys by hand.

https://gist.github.com/femto113/ef9162d670def84b3c684d2d305...


In theory there is a way to do it without needing to have IdentitiesOnly yes. That is, if ssh did something like:

    server -> user: nonce
    user   -> server: nonce2, h(nonce || nonce2 || publickey) (for every publickey)
or alternatively

    user -> server: nonce
    server -> user: nonce2, h(nonce || nonce2 || publickey) (for every publickey)
It would still leak the amount of keys (for the user for the 1st protocol and for the server for the second) but nothing about them. (I would also suggest using a modern hash function for h, such as blake(2) or sha3)

There should be a way to extend this protocol as to not leak the amount of keys.


Look at kssh (Keybase SSH)


this will actually not work. this is why you should not make your own crypto protocols in production if you are not an expert and/or if you have not proven them correct.


That’s a neat demo. Am I right to think it’s exceptionally difficult — without local exec access on a machine — to induce a machine to open an ssh connection to an arbitrary host?


If you try to SSH into some new machine that you own, someone can redirect your request to an attacker's machine (via DNS attacks or MITM), and since it's a new machine, it won't be in your known_hosts file, so it will prompt if you want to trust this machine and 99% of people will say yes.


openssh makes the situation worse because if the key is already in your host file and it's just the ip/domain that changed it will not tell you that it recognises the key.


I mean, if a mitm has your SSH server key, chances are you are screwed anyway.


In the case which I am describing nobody other than you has your key.


But the key you are talking about the SSH client recognising is the server key right? Or did you mean after authorising your SSH client to connect to the unknown machine, and the key you were talking about was the identity public key? I ask because the thread you commented on was discussing users not looking carefully which servers they connect to when connecting to new servers, and that is based on the SSH servers key, not your identity key, which is why I said that if someone who is able to redirect your SSH connection to a different server also owns the correct servers SSH server key (as you said "just the ip/domain that changed"), then there isn't much the client can do to help keep you safe anyway.


> But the key you are talking about the SSH client recognising is the server key right?

Correct

> which is why I said that if someone who is able to redirect your SSH connection to a different server

I will try to be more clear. Often when I am away I use ssh to connect to my desktop pc which has a dynamic IP address. Even though I have already stored the public key of my server in known_hosts it keeps asking me to verify if I trust its public key every time that it changes IP address without even mentioning that it has met said public key before. So if I am not careful enough I might end up accepting the public key regardless, even if I am being MITMed.


Ah, yes, I've always found that to be a little strange. It is cryptographically possible for the server to establish to the client that it is who it says it is, just on a different IP

Sorry for the confusion, I misread your initial comment, thought you were saying it does what we're saying would be a good behaviour, and was confused as to why you thought this was a problem, but it was just I who was confused!


This misunderstanding could have been avoided by formulating your initial statement like this:

>openssh makes the situation worse because +even+ if the key is already in your host file and it's just the ip/domain that changed it will not tell you that it recognises the key.


Probably cannot induce the local machine to connect, but if you enabled agent forwarding, and then connected to a machine, someone who compromised that machine may be able to use your credentials to connect to other SSH servers.

Source: https://heipei.io/2015/02/26/SSH-Agent-Forwarding-considered...


I'm not sure I follow, induce what to open an ssh connection? If you mean the service in question (whoami.filippo.io) it is opening an ssh connection it just displays a message and closes instead of authenticating you and dropping you into a shell. If you mean launch an ssh session from a machine to something in general then yes you have to be able to execute programs on the machine as that's all an ssh client is - another program.


I think the question is if it's possible to add <img src=ssh://> to a webpage and have something dumb happen.


Exactly that, and I'm reasonably sure the answer is no.


I am sure there is some setup where that will work. Set a URL handler to open Emacs, format the filename as a TRAMP path, something like that. There are plenty of things that try to transparently SSH places, and I'm sure someone has accidentally hooked that into their browser.


Can somebody comment on why the exposure of public keys is a problem?


> Can somebody comment on why the exposure of public keys is a problem?

It is not, it just makes you identifiable. Public SSH keys are… well, public.


Aside from IdentitiesOnly setting. I assume storing keys outside of ~/.ssh and calling each key via config file or ssh -i would render this useless. Perhaps even a simple bash function to rotate the needed key in/out of .ssh.


You can still store your keys in ~/.ssh as long as you don't use the default file names. By default, ssh will only announce id_rsa, id_dsa, id_ecdsa and id_ed25519. But if your key for GitHub is stored in, say, ~/.ssh/id_github, it won't be offered unless explicitly requested with -i or the IdentityFile config option.


I wonder how does it match my public key at github? Does it use a popular accounts index, or maybe he crawled a bit?


> I wonder how does it match my public key at github?

> Does it use a popular accounts index, or maybe he crawled a bit?

Ben Cartwright-Cox (aka. benjojo) [1] crawled many “github.com/USERNAME.keys” some time ago [2].

Filippo, being colleagues, probably asked for a copy of his database to run this experiment.

For example, here are the public SSH keys Linus Torvalds uses on GitHub [3].

[1] https://github.com/benjojo

[2] https://blog.benjojo.co.uk/post/auditing-github-users-keys

[3] https://github.com/torvalds.keys


I thought this was pretty obvious.... but ok, so don't ssh places you're not supposed to?


Why is this obvious? I don't know much about crypto but I'd imagine it's possible for an protocol to not reveal the identity of the authenticating party.

For example a server can send a challenge which requires knowledge of the private key to solve but does not reveal anything from the client on failure.

If the server has multiple authorized_keys it could just send multiple challenges and accept a reply for any of them.

Am I missing something? This seems like a nice privacy feature.


If you don't know the identity of the authenticating party, how does the authenticating party log in to their account?


They tell you which account they want to log in as, which isn't necessarily their global identity they'd like to share with you.


Exactly: you wouldn't be able to ssh git@github.com/repo/proj but rather have to use user@github.com/proj/repo and this would be better.


I really don’t think there’s anything obvious about the fact that logging into an SSH server also exposes other login information stored in your computer. Given that creating a Github account is one of the first things beginner devs are guided towards it’s worth keeping such beginners in mind.

And it’s not so much “places you’re not supposed to” as “places you know haven’t been compromised in any way”, which is difficult to know unless you’re the sysadmin.


The fact that people are using this tool regularly and fail to grep a basic understanding of what and how the protocol works in mind blowing.


Is it really? It’s what Github recommends for every new user without explaining in real depth what’s going on.


For example there was an RCE in iTerm2 in October, whenever tmux integration is turned on (https://nvd.nist.gov/vuln/detail/CVE-2019-9535). It's unlikely you have a good reason to believe your terminal stack is secure.


Well specifically it is sharing the public keys that you have in your SSH folder. It's like trying all your keys in a a keyhole since you don't know which one gets you in. This is really no fault of SSH - the fault lies completely with Github for sharing all their users' public SSH keys.


…but they're public keys.


This. Exactly what are we afraid of here? It's working as designed.


It's not directly a security problem as in your computer is gonna get hacked, but it can ruin your opsec if you don't want people to realize that you're the person controlling a specific key.


I would hope if you're doing serious opsec you're using ephemeral keys or isolated virtual environments for various endeavors.


Yep. I would also hope if you're 'doing opsec' you would know how your tools work.


You are definitely right in that the public keys themselves don’t present a threat. I think on a penetration test this would show up as “Information Revealed” rather than something that is “Exploitable”. By sharing a username - you might be able to correlate this person to other platforms and technically increase your attack surface area.


What if you're supposed to ssh to two different places. but you don't want them to know you're the same person?


If that's important, you'll need to generate two sets of keys, explicitly assign one to each place and set IdentitiesOnly in your SSH configuration.

Most people don't care about this and so I'm comfortable with the default not being IdentitiesOnly

It's probably more surprising for any early adopters of FIDO for SSH, since WebAuthn (to do FIDO on the web) and its predecessor U2F both do ensure your identity can't be correlated between sites, but the new SSH support does not provide that.


Oh, wow, that does surprise me. I haven't gotten around to using FIDO for SSH but I didn't realize it works differently from WebAuthn.

Anyway, yes, I'm also comfortable with the default, I'm just pointing out why "don't SSH places you're not supposed to" isn't a relevant argument.


In WebAuthn the remote site is storing typically three facts about each non-resident WebAuthn credential for a user. It has a cookie (an opaque blob of fixed size, which it was given by the remote FIDO authenticator during enrollment - and it must play this back every time it wants you to authenticate) and a public key (which it will use to confirm your signatures during subsequent login to prove you still have the authenticator), and practicality it probably also stores a name or an icon or something so users can remember which of their credentials is which.

When you enroll your authenticator creates random credentials (made easier by using Elliptic Curve crypto so almost any random bits are a valid key unlike RSA) and then (unless you're using a much more expensive/ sophisticated device or a FIDO2 device in its resident credentials mode) it encrypts its own private key and delivers that as the cookie value. The remote server actually has your private key... but encrypted with a symmetric key that only exists inside your FIDO authenticator so it's actually safe.

OpenBSD's approach to using FIDO for SSH keeps this cookie element locally, not on the remote server. So the actual keys used will be constant across multiple servers and thus could be correlated to track you.

The other effect is that (again because that cookie is on your local client not the remote server like for WebAuthn) you can't use a cheap (non-resident enabled) FIDO authenticator from anywhere except the machine you used to enroll it. The authenticator plus a random (new enough) SSH client don't have enough information between them to get you in, they also need that cookie which is on, say, the laptop you left in a hotel room.

If that use case is essential for you, you can apparently use resident credentials. I haven't tried it, but a newer Yubico Security Key (with the numeral 2 printed on it to signify that it implements FIDO2) should be able to store everything, authenticated with a PIN, so then you can use a new enough SSH client plus that Security Key plus your PIN to log in from anywhere.

Alternatively if you have a cheaper FIDO device or choose not to use the resident mode of a newer one, this does have the effect that you can create different cookies from different laptops and then you can approve the resulting different keys for different purposes if that suits you. It could make sense to approve your company laptop's keys for checkin to corporate Git repos while the personal laptop has your GitHub keys while keeping just one FIDO key on your keychain throughout the day...

Edited to add: Residential credentials for SSH is apparently planned for OpenSSH 8.3, not OpenSSH 8.2 and so not available yet.


How do you know whether you're SSHing to a place you're not supposed to or not? There's no CA telling you that it's legit like there is for https. 99% of people don't manually verify the host key fingerprint.


SSH does support CAs, there's just no PKI in place. But you can totally set up an internal SSH CA and sign the host keys of every server in your company.


There is a PKI: DNSSEC with SSHFP records.


That's principally a PKI for SSH host keys, which aren't the keys people talk about when we talk about SSH CAs.


Is it really that much more common to sign user keys rather than host keys? I've been quite fond of signing hosts, personally.


When people talk about SSH CA's, they're talking about systems where you are granted access to a fleet of servers not by having your id_rsa.pub copied into a bunch of authorized_keys files through some automated process, but rather by having the whole fleet trust a CA key, and then having the CA key sign certificates for users (typically: through an identity provider). The wins are:

* It's a lot easier to provision users because the per-server configuration is static.

* You can issue short-lived keys for users so that a lost laptop won't be carrying lots of dangerous SSH keys.

* You can force users through your standard authentication flow and get things like MFA without requiring the SSH servers to understand MFA individually.

Outside of this use case, it's not common to sign SSH keys at all. SSHFP isn't widely used; in fact, almost nobody uses it (because almost nobody uses DNSSEC in the first place). But even if you were set up to use it, SSHFP wouldn't do the things we're talking about when we talk about SSH CAs. In fact, it'd be hard to come up with a worse place to put user keys than in the DNS, which is public, even (in fact: especially) with DNSSEC.


Yeah, I've done it for users, but it's basically the same for host keys; you sign the host key with the CA, stick `HostCertificate /etc/ssh/ssh_host_ed25519_key-cert.pub` in your sshd config, and stop getting prompted to manually verify host keys on connection. Would that not still be called a CA?


Would anything stop you just loading let's encrypt onto it?

Will regular HTTPS certificates work?


No, ssh uses ssh keys to sign keys.


I remember a few years back someone was on an onion IRC server advertising "free shells". My first thought was "Ohhhh someone found a nice and juicy client-side security hole! No thanks!"




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: