
Web login using SSH - levosmetalo
https://github.com/altitude/login-with-ssh
======
scrollaway
This is something I've had the occasion to discuss before, and it's a good
idea not because "it's ssh" or "it's decentralized" (those are just good
benefits), but because it moves the authentication to an _actual
authentication protocol_ and, were it to catch on, would have to be done from
the browser itself.

Does this ring a bell? That's right, it's BrowserID ladies & gents. I'll never
let this go, Persona was a _great_ thing for the web and its death is mourned.

I think I've seen ssh auth implemented before but this is the smoothest POC
yet. Your next step: Make a firefox extension that integrates this, as a proof
of concept for in-browser authentication.

~~~
drdaeman
I'd disagree. My personal opinion is, BrowserID/Persona was a bad thing for
the web and it's a good thing it haven't hit any big. Sure, it was better than
most popular protocols out there, but it was still wrong.

My opinion is that BrowserID had a very flawed core concept. I firmly believe
that my _identity_ is something that I [can] naturally _define_ and _possess_.
But everyone since OpenID had stolen this from the end-user and identities
became something that you're provided with - and I find the very term
"identity provider" unnerving.

With identity providers you're not you anymore, but merely your Facebook
account or your email address or your domain name - a things you only
temporarily _lease_ from a _third-party_ like an email provider or a domain
registry. Sure, there's some common sense, legal protections and stuff, but
I'm don't like merely relying on those. I think, in a sane world, at least
personal (i.e. non-group) identities must be merely asserted, not provided -
and they must originate from a person themself.

On the contrary, this login-with-ssh thingy and few other schemes (gpgAuth and
WebID) are much closer to what the things should be like. While they don't yet
completely resolve the distinction between an identity and a credential (it's
really hard), they root your identity in something that you can actually
define for yourself and handle without depending on anyone else - a key pair.

~~~
superuser2
Normal people will lose key material. Systems administrators sometimes lose
key material! In a sane world, it needs to be possible for someone with common
sense to revoke and reissue your credential if you lose it. If this is
categorically posisble, then your identity is leased, not owned.

Your SSH private key is not your identity, it's just some bytes. Your identity
is determined by _what public key is considered to be "you"_, i.e. what's in
~/.ssh/authorized_keys. Your infrastructure provider can usually change this,
with or without your permission.

Unless you own the _land_ where the hard disk public key -> account mapping
resides, your identity is leased.

~~~
ploxiln
Here's an idea: you can designate "emergency contacts", other keypairs that
can be used to recover your identity, perhaps those of your family members.
They could declare the intention to recover your credentials, and then you
would have 2 weeks to publish a signal that you still possess your keypair, to
block the recovery. You could also revoke their designation at that point, if
they are abusing it.

If two weeks pass without incident, then they can publish a new public key
half which is considered yours, and presumably give the private half to you.

~~~
drdaeman
This. And maybe even use Shamir's secret sharing (or a similar scheme) to
split the backup/recovery key among the family members or trusted close
friends - so a single person won't be able to compromise your security.

[https://en.wikipedia.org/wiki/Shamir's_Secret_Sharing](https://en.wikipedia.org/wiki/Shamir's_Secret_Sharing)

------
rdancer
Public key authentication of _clients_ (as opposed to _servers_ ), has been
part of SSL since v1.0. This is just adding a misdirection, the underlying
protocol is the same X.509 we've had since the late 1980s.

The main problems are:

1\. Certificate authenticity -- the key has to be added to authorized_keys on
the server. This includes certificate revocation and expiration, and re-
establishing trust after certificate is lost.

2\. Private key management -- how do I migrate keys to a new browser or a new
machine? Where are the keys stored anyways? Absolute PITA in every existing
implementation.

3\. Key generation -- we need some more user-friendly tools if this is to
catch up

~~~
chrissnell
The U.S. Military does a passable job of this with the Common Access Card
(CAC). You insert it into a smart card reader and then visit the restricted-
access website. Your browser/OS prompts you for a PIN which, I believe, is
used to decrypt your private key. Your browser validates the remote site
against a set of DoD-provided root certificates that you configure on your
computer before hand. Then, some kind of key exchange happens--this has always
been a bit fuzzy to me--and the keys on your CAC card are used to authenticate
you to the remote site.

It's not perfect, of course. You can lose your CAC card and then you're
screwed unless you have a way to get new one. It requires a smart card reader
which is not standard on most computers. The cards themselves can get damaged
by corrosive liquids or sweat (learned this the hard way). Still, it's not a
bad way of authenticating and I feel much better about it than a SSH private
key that hasn't been encrypted with a passphrase.

~~~
rdancer
For example in Estonia, every citizen has an ID card, and every ID card is an
ISO-7816 smartcard. So they can have this nationwide. Then again, that's a
country of 1.3M, and you only get the card when you're 15yo. Foreign visitors
obviously don't have one.

These examples illustrate rather the near impossibility to implement this kind
of a scheme successfully, even when backed by a state.

------
struppi
The is a great idea, but the usability is probably not good enough to make it
work.

What I like: I am authenticated by some proof of ownership, and, unlike with
password authentication, the "thing I own" is never transferred over a wire or
stored at the server. This is even better than what I have now (unique
passwords for every site, managed with 1Password, and 2FA for important
sites).

But the SSH callback would have to be automatic - Via a browser plugin, or
even better, implemented by the browser itself. I don't think I want to start
a terminal and past a string every time I log in to a site.

The "paste this into your terminal" also opens up a completely different can
of worms - Social engineering!

~~~
merijnv
So...basically you want SSL client certificates but with a slightly less sucky
UI?

I mean, https already supports this, it's just that setting up servers to deal
with client certs sucks and the UI for users is also pretty bad. But the
infrastructure is already there without poorly reinventing the wheel over SSH.

~~~
struppi
Right, that's exactly what I want. Or something like BrowserID / Persona was
supposed to be. It has to be slick and frictionless, otherwise it won't stand
a chance.

You know, there is a reason nobody uses client certificates...

~~~
scrollaway
Aye in the end I don't think the protocol itself matters as much as the
concept of doing (asymmetric) auth in the browser rather than layered over
http. Yelling "but it already exists! client certs!" is kinda unproductive,
like you said there's a reason nobody uses them.

------
dlitz
Neat idea, but I think there's a confused deputy(?) attack possible here.

Specifically, I think there's a missing binding between the SSH session used
for authentication and a user's web session.

Let's say that Alice has an account on bob.com. Mallory sets up mallory.net
and sets up demo-ssh.mallory.net as a DNS alias (or TCP proxy) pointing to
demo-ssh.bob.com.

1\. Alice visits mallory.net, which Mallory controls

2\. Mallory visits bob.com and starts an authentication session.

3\. bob.com presents an SSH challenge to Mallory

    
    
        ssh demo-ssh.bob.com -l 7d7662f63f70de7714 -p 2222
    

4\. Mallory forwards the challenge from bob.com to Alice, optionally
substituting their own hostname:

    
    
        ssh demo-ssh.mallory.net -l 7d7662f63f70de7714 -p 2222
    

5\. Alice runs the command to authenticate to "demo-ssh.mallory.net". But this
actually authenticates Mallory as Alice to bob.com!

6\. Upon detecting a successful login, mallory.net accepts Alice's login to
avoid raising suspicion.

The only sure sign that this has happened would be that demo-ssh.bob.com and
demo-ssh.mallory.net would have the same host keys, but OpenSSH isn't designed
to prohibit duplicate host keys.

~~~
dlitz
One potential way to solve this would be to include the origin in the
challenge, which the server could check:

    
    
        ssh demo-ssh.bob.com -l 7d7662f63f70de7714 -p 2222 https://www.bob.com
    

Mallory's attack then would have the possibility of being detected:

    
    
        ssh demo-ssh.mallory.net -l 7d7662f63f70de7714 -p 2222 https://www.bob.com
    

However, this still relies on the user manually checking the origin of the
challenge every single time, and users aren't very reliable. It might be
better suited to a browser extension than to a manual copy-and-paste process.

------
joopxiv
I would argue that using a client certificate would be a much more practical
way for web authentication. This would eliminate the need to start a SSH
session when trying to login.

~~~
detaro
My university uses client certs for some services. It's a pain with tons of
odd error cases. With a technical user base, this might actually have better
worst-case experiences (but worse average-case, when client-side certs work
and you always use one machine they are smooth).

It would be awesome if YubiKeys or other SmartCard-like devices were more
widespread and better supported in browsers, because it would make client-cert
workflows way easier. It's really mostly an UX issue.

~~~
joopxiv
I can agree with this, but I think the hardware tokens compared to regular
client certificates have the same issue: better average case (if it works it
much easier to use it on multiple machines) but worse worst-case (a missing
driver will completely shut you out).

~~~
detaro
It should be possible to build tokens that work without special drivers,
requiring "just" application support. (Many 2FA tokens emulate HIDs/keyboards)

------
mbrock
Sweet. You can fetch keys from GitHub by username without authenticating, so
that could be a convenient way to avoid having to paste keys.

~~~
talleyrand
I'm confused. Would this mean I could just grab anybody's public key and log
in - as them - to a service that supported this?

~~~
pluma
No, you could just grab anybody's public key to verify their login (when they
use their private key).

SSH keys are asymmetric. Think of public keys as locks and private keys as ...
well, keys. You hand out copies of the lock but you keep the key to yourself.
Anyone can put a lock on a box and know you're the only one who can open it.
You tell them what lock to use and then use your key to open it to show them
you are who you claim to be.

------
j_s
This topic (not this project) was last discussed 5 months ago with 150+
comments:

[https://news.ycombinator.com/item?id=8970402](https://news.ycombinator.com/item?id=8970402)

There has also been mention of a few other SSH + browser ideas:

[http://sshkeybox.com/](http://sshkeybox.com/)

[https://www.minaterm.com/](https://www.minaterm.com/)

------
IgorPartola
So I like this. Here's how I see this working for the majority of people who
don't know what SSH is:

1\. Browsers support syncing between different devices using some type of
cloud provider (think Google's sing into Chrome, Safari's iCould integration,
etc.). This obviously would need some type of client side encryption to be
secure. Could be achieved with a plug in as a stop gap.

2\. Browser support for this type of auth. Basically, you'd do <input
type="identity" protocol="ssh" nonce="abc">, which would render as a drop down
with a list of identities the browser has (which correspond to your private
keys). You simply choose one, then submit the form. The server sees your
public key (which it may remember after registration), the nonce, and the
nonce signed with your private key, verifiable against your public key (I am
hand-waving the actual authentication here. This implementation is susceptible
to at least replay attacks unless the nonce is remembered by the server.)

That's pretty much it. If you think about it, this is how LastPass works now,
except instead of sending a one time signed nonce back to the server it sends
a username and plain text password.

------
thwarted
I experimented with an alternative HTTP authentication scheme (like basic or
digest, using the "WWW-Authenticate" header) that used ssh keys to
authenticate the client. Some of the idea was based on this Joyent blog [0]
post about signing the date header, but more robust and meant for a user
rather than scripted access. The idea was that the browser would interface
with a specific ssh-agent with specific keys loaded for specific sites.

Unfortunately, I didn't get very far and stopped working on it a while ago,
but one thing I did learn was that the source code for links was much easier
to come up to speed on and use for rough experiments than the source code for
a full-on graphical browser.

I still have notes for it... somewhere.

[0] [http://joyeur.com/2012/01/03/a-bit-more-about-the-new-
joyent...](http://joyeur.com/2012/01/03/a-bit-more-about-the-new-joyent-cloud-
api/)

------
themckman
What I've always REALLY wanted to see with regards to SSH and the web is an
implementation of the SSH Agent API over web sockets or something. That way if
I had some Ansible scripts I wanted to run from a web UI (like something
similar to Rundeck) I wouldn't need a key sitting on my server to run those
commands. The program invoking Ansible would provide an appropriate value for
SSH_AUTH_SOCK that would be connected to my browser and tada. Now, I'm not
entirely sure it is feasible, but we've implemented enough crypto in the
browser lately, I'd bet it is.

~~~
voltagex_
I wonder if you could "bypass" the browser by having a socket on your box that
connected to a websocket server (?) that then forwarded your request to the
remote box. I haven't had coffee so I'm probably missing something.

Edit: [https://github.com/mcavage/node-ssh-
agent](https://github.com/mcavage/node-ssh-agent) is interesting.

You could have a browser extension that connects back to a local daemon.

------
jamescun
I've had this idea before, nice to see it implemented. The reason I've never
pursued it as I'm not quite sure what the actual user experience or benefit
over traditional 2FA systems is.

~~~
aroch
I wouldn't mind if my hosting providers offered this in lieu of password auth.
All my servers are already pubkey-authentication only and I always have my
keys/an SSH client handy

------
OJFord
I've been meaning to search for exactly this for 'personal production' use. I
think it fits the bill in a great way.

Say you have a blog, or even some kind of small application, only you
develop/administrate it, and only you ever will. SSHing in couldn't be
simpler, but front-end authentication sucks. Everything available feels
overkill to just authenticate that you are you. Most recently, I just used
HTTP basic auth, resolving to see if there was a way to use SSH 'soon'.

------
PinguTS
So, what is the advantage over just using Client Certificates, which are
supported by all major browsers?

This is how you authenticate with StartSSL.com for example.

------
fiatjaf
This is as easy and usable by normal people as would be "web login by signing
a string with your PGP key". No way.

The solution for this kind of thing is still something like OpenID, however
simpler, so everyone can implement everywhere they want, even using custom
SSH-OpenID servers, and normal people can use with their Google emails.

------
SixSigma
With OpenBSD the pf packet filter can block any port unless there is an active
Ssh connection from you too.

