Hacker News new | ask | show | jobs
by stephenr 4158 days ago
The parent's "solution" assumes the browser is reading the markup and connecting directly to the SSH server.

As I've said, this is a fucking horrible idea from a security stand point.

This whole concept is bonkers given that client side certs already exist and already work, but if you have some reason to connect to SSH from a browser session (i.e. lets say you were providing a remote dev shell), a plain hyperlink that hands of the connection to the system's default "ssh" handler (i.e. a terminal app of some kind) is still the best solution here.

Let the SSH client worry about SSH keys. Let the browser worry about HTTP and HTML.

2 comments

Sorry, I re-worded "solution" to the lighter "suggestion" after posting, and I agree that there is likely a more fool-proof architecture (e.g. one not vulnerable to XSS; even HTTP headers would be an improvement, I suppose).

The idea (as I understand) is that you trust the data that you've received from the server, and the server knows the public key of the sshd that it wants you to use for login, so it provides the fingerprint for that public key.

I agree that browsers shouldn't use SSH; it's overkill. But in the example (for humor), the browser does worry about SSH keys, because it is an SSH client. "Just use DNS with DNSSEC" won't work for direct IP addresses. Using client side certs is unnecessary, as the trusted web server is only telling you the conditions under which it is okay to authenticate. If you already trust the integrity of the data, it isn't more dangerous (from a security standpoint) than when you you get a page over HTTPS that tells you to POST to /login.

Besides the fact that we both think that the browser as an SSH client is silly, I don't think the suggestion of providing the fingerprint in DNS with DNSSEC is any more secure than a trusted web server providing it, but it would not work for direct IPs.

explain a real world scenario where you have a web server with a valid certificate but you don't have a DNS entry for the server?

You're inventing ridiculous scenarios to justify a nonsense concept of integrating html, browsers and ssh.

explain a real world scenario where you have a web server with a valid certificate but you don't have a DNS entry for the server?

For example, if the certificate is assigned to an IP address. Not extremely common, but some people use it. [1]

You're inventing ridiculous scenarios to justify a nonsense concept of integrating html, browsers and ssh.

I stated (twice) that I think having the browser act as an SSH client is a silly idea. Not sure how I'm interpreted otherwise.

Both of my posts only point out that your intended correction (to just use DNS) wouldn't work for all cases, while the original post would work fine for authentication as far as I can tell. And that there are no inherent security concerns using in-band fingerprints, as opposed to looking them up via DNS w/ DNSSEC, if you already trust the integrity of the server response.

You keep replying along the lines of "well it's a bad idea to do SSH in the browser anyways", and I've already agreed with you there, because you're correct.

[1] https://support.globalsign.com/customer/portal/articles/1216...

> I stated (twice) that I think having the browser act as an SSH client is a silly idea. Not sure how I'm interpreted otherwise.

I'm purely talking about the concept of linking to SSH from a HTML page. The original concept of "http auth by anonymous SSH" is ridiculous, and I'm glad you agree with that.

So in terms of using a link to open an SSH session in general (lets assume a non-ridiculous use-case, like opening a session on a dynamically created remote environment).

I explained a solution that works right now, needs a couple of new DNS records and potentially a one-line change in the user's ssh config file, to provide automatic, safe acceptance of the fingerprint.

Your argument is that it won't work with an IP address, but that they might still have a TLS certificate for the server IP address, which implies that the person/organisation running the server, spent all their money on "ownership" of a public IP via RIPE NCC (apparently 1650 euro/year), and an expensive SSL cert ($350/year) tied to that IP, but that they can't afford a $10 domain name to make SSHFP over DNS (w/DNSSEC) work.

but that they can't afford a $10 domain name

The reason they would spend the money on the ownership of the IP and cert isn't because they can't afford the domain name. It's generally done for "mission critical" reasons because it takes out a class of weaknesses. DNS hijacking, DNS servers failing, DNS blocking by governments, etc. It could even be for vanity reasons, they may self sign, or w/e. It doesn't really matter, because the chance that these servers are going to be serving HTML to your standard web browser is pretty slim.

But I still think it'd be weird for DNS to be used here.

Using DNS for this:

  https://1.1.1.1 -> ssh://1.1.1.1:443 -> cannot connect (or require manual override)
  https://example.org -> ssh://example.org:443 -> check fingerprint in DNS w/ DNSSEC -> connected
Using the in-band HTML or HTTP method:

  https://1.1.1.1 -> ssh://1.1.1.1:443 -> check fingerprint in trusted HTML/HTTP -> connected
  https://example.org -> ssh://example.org:443 -> check fingerprint in trusted HTML/HTTP -> connected
Assuming that the browser has already been modified to correctly handle whatever the SSH links do (e.g. by launching another program that has the fingerprint added) and the SSH link meets some security checks (same common name, same port running both the httpd and sshd), it seems wrong to me to have different capabilities based on if the common name is an IP address or a FQDN. I see the DNS solution to be kind of a "if all you have is a hammer..." solution, rather than a tailored solution for the link handling.

Anyways, thanks for the follow up post, I think I see your POV and agree with you that the DNS method would require much less work in order to get it work, given the current implementation.

The DNS solution has the benefit of working regardless of how the session is initiated.

I also don't see any benefit to domain/port matching. It's a different protocol, it should be treated as such

Call it an amendment. I am neutral on the whole "connect to SSH through an HTML client", but I'll tell you what: the fingerprint is a necessary connection parameter, as much as the hostname or port. Not an afterthought.

Solve it however you like.

$ ssh --fingerprint ab:cd:...

or

ssh://user@hostname?ab:cd...

or

FINGERPRINT_VAR=ab:cd:... ssh somehost

or

what

ever.

One is ugly, the other is uglier. Fine. At least they're actually secure.

Guess: how many people actually check the full fingerprint before accepting it? On a good day, I remember the first four letters (2 bytes). Whenever I tell people, it's blank looks all around. What's a fingerprint?

And these are people who use SSH.

UI is important. UI matters. Good UI helps. UI UI UI UI UI.

The fingerprint is a required parameter for connection! Not just the hostname, also the fingerprint.

Sure, let the client cache it and automatically allow leaving it out on subsequent connects. But don't allow initial, fingerprintless connections. Never.

Implemented properly, this addresses the DNSSEC alternative. Do you have DNSSEC installed, do you trust it? Okay, get the key from there. Don't have it? And it isn't specified in the connection parameters? Woops, no connect. Impossible. Why? Because without a pre-supplied fingerprint, no SSH client should ever connect.

We don't need to debate DNSSEC here, the clients will speak. I know I'd be including the fingerprint in the connection parameters directly, but do as you please.

Make a get-fingerprint-insecurely tool, that just connects to a host and prints you what it thinks is the key. This allows people to still make insecure connections, but it's explicit. Make MITM and insecurity the cumbersome and explicit way. Not default.

This is such a frustrating, last-mile, almost-right-thus-wrong issue.

You're right in theory. In practice, unfortunately, people don't check the fingerprints. And the sad thing? We could do something to fix that.

Join the Fingerprints are a required connection parameter-movement.

PS: I think we're on the same side here. I don't go to sleep dreaming of SSH fingerprints: I'm just against allowing MITM by design. Of course, certificates, or any other means of ensuring the connection is not MITM'ed is just as good. Fingerprints as required connection parameters are just the easiest way to get that done, right now, today, in our way of working. But once everyone uses certificates properly: fine, forget about them. This non-MITM design needs to become part of everyone's understanding of SSH.

I agree that blindly accepting fingerprints is a bad idea, but I still think this can be solved for the majority of use-cases, with largely existing options, and without forcing the UI to be worse for users (when setup correctly)

From my understanding (I haven't tried this in practice yet), setting both StrictHostKeyChecking and VerifyHostKeyDNS to 'yes' will give most of what you want - it won't prompt to accept random keys (that's the StrictHostKeyChecking=yes bit) but it will explicitly trust SSHFP records it finds in DNS (thats the VerifyHostKeyDNS=yes bit). Obviously, you need to make sure your SSH client is using a DNS resolver library that actually supports & checks DNSSEC secured records.

Obviously you could just enable StrictHostKeyChecking (without VerifyHostKeyDNS) and use a simple shell script wrapper for SSH to accept a FP and append it to the known_hosts file before calling true ssh.

'ssh-keyscan' is your 'get-fingerprint-insecurely' tool in a nutshell.