mscdex / ssh2

SSH2 client and server modules written in pure JavaScript for node.js
MIT License
5.53k stars 665 forks source link

Feature Request: support certificate authentication. #551

Open donleyp opened 7 years ago

donleyp commented 7 years ago

In OpenSSH one can use a CA-signed key and certificate pair to sign-in to an SSH server with CA authentication turned on. The server sets a public certificate as the "trusted ca" and the client then uses a private key signed by that certificate to connect to the server.

The private key is just like an id_rsa file You also need the signing public certificate file.

In OpenSSH this is passed using a convention: Example: id_rsa <- the name of the signed private key. id_rsa-cert.pub <- the public certificate used to sign the private key.

you would then connect to your server with this command: ssh -i id_rsa username@server.com

I would like to see SSH2 support this authentication mechanism.

My suggestion for interface would be to add a "certKey" option to the connection options where we can include the certificate.

mscdex commented 7 years ago

AFAIK it should already work as such private keys are designed to be supported. Does it not work when you just supply the privateKey (e.g. with the contents of id_rsa in your example) or use one via an ssh agent?

donleyp commented 7 years ago

It does not work. In OpenSSH I have to have both the id_rsa and id_rsa-cert.pub files present.

When I try to only use the private key with SSH2 it returns an error at client-authentication with this error message: Error: All configured authentication methods failed.

mscdex commented 7 years ago

Ok and just to clarify what ssh-keygen parameters are you using to generate these key/certificate pairs?

jdiamond commented 6 years ago

Was looking for this, too. Here's a pretty good description of what they are and the ssh-keygen commands used to create them:

https://blog.habets.se/2011/07/OpenSSH-certificates.html

Avinm commented 6 years ago

Any update on this one? Instead of generating a new public key in client.js, I tried sending the 'id_rsa-cert.pub'. From what I could understand, this seems to be passing the authentication (onUSERAUTH_PK_OK is being called in the stack trace), but I am stuck with the below error:

InvalidAsn1Error: Expected 0x2: got 0x8a
    at newInvalidAsn1Error (/Users/emavin/Desktop/ssh2-master/node_modules/asn1/lib/ber/errors.js:7:13)
    at Reader.readString (/Users/emavin/Desktop/ssh2-master/node_modules/asn1/lib/ber/reader.js:168:11)
    at ECDSASigASN1ToSSH (/Users/emavin/Desktop/ssh2-master/node_modules/ssh2-streams/lib/utils.js:135:21)
    at /Users/emavin/Desktop/ssh2-master/node_modules/ssh2-streams/lib/ssh.js:1623:19
    at /Users/emavin/Desktop/ssh2-master/lib/client.js:596:9
    at SSH2Stream.authPK (/Users/emavin/Desktop/ssh2-master/node_modules/ssh2-streams/lib/ssh.js:1618:3)
    at SSH2Stream.onUSERAUTH_PK_OK (/Users/emavin/Desktop/ssh2-master/lib/client.js:567:14)
    at Object.onceWrapper (events.js:273:13)
    at SSH2Stream.emit (events.js:182:13)
    at parse_USERAUTH (/Users/emavin/Desktop/ssh2-master/node_modules/ssh2-streams/lib/ssh.js:4329:12)

Here is my modified version of client.js

rbayliss commented 5 years ago

I couldn't figure out how to make this work either... I tried passing in the private key as the privateKey, and the cert as the publicKey, which didn't work. My use case is connecting to an AWS Lightsail server from a Lambda function. Using the AWS Lightsail API, you're able to obtain a temporary SSH key, but it's a signed key (private key + cert key). If I save the private key data into a file mykey and the cert key data into mykey-cert.pub, I can run ssh -i mykey ec2-user@... and connect just fine. The verbose output from that command shows:

debug1: SSH2_MSG_NEWKEYS sent
debug1: expecting SSH2_MSG_NEWKEYS
debug1: SSH2_MSG_NEWKEYS received
debug1: rekey after 134217728 blocks
debug1: Will attempt key: mykey  explicit
debug1: Will attempt key: mykey RSA-CERT SHA256:wFM/y6uB4+7G6NCO013BYd+WjqqXBYZz+R3CPm0QLKU explicit
debug1: SSH2_MSG_SERVICE_ACCEPT received
debug1: Authentications that can continue: publickey
debug1: Next authentication method: publickey
debug1: Trying private key: mykey
debug1: Authentications that can continue: publickey
debug1: Offering public key: mykey RSA-CERT SHA256:wFM/y6uB4+7G6NCO013BYd+WjqqXBYZz+R3CPm0QLKU explicit
debug1: Server accepts key: mykey RSA-CERT SHA256:wFM/y6uB4+7G6NCO013BYd+WjqqXBYZz+R3CPm0QLKU explicit
debug1: Authentication succeeded (publickey).
baelter commented 5 years ago

The CA signed key type is not supported it looks like? DEBUG: Agent: Skipping unsupported key type: ssh-rsa-cert-v01@openssh.com

Tried adding pubKeyFullType = pubKeyFullType.replace(/-cert-.*@openssh.com$/, '') to onUSERAUTH_PK_OK but it only got me a little further.


11:53:42 AM web.1 |  DEBUG: Parser: Verifying MAC
11:53:42 AM web.1 |  DEBUG: Parser: IN_PACKETDATAVERIFY (Valid HMAC)
11:53:42 AM web.1 |  DEBUG: Parser: IN_PACKETDATAAFTER, packet: USERAUTH_PK_OK
11:53:42 AM web.1 |  DEBUG: Parser: IN_PACKETBEFORE (expecting 16)
11:53:42 AM web.1 |  singed: <Buffer 00 00 00 07 73 73 68 2d 72 73 61 00 00 01 00 42 41 34 d3 48 c1 8d b5 4e ec 18 27 06 42 2f 70 ac 45 e0 ab be 06 56 0b 4f 4a 6e e1 4e 9f 9b 7b fb 14 62 ... 221 more bytes>
11:53:42 AM web.1 |  [ERROR] Expected 0x2: got 0x34
11:53:42 AM web.1 |  InvalidAsn1Error: Expected 0x2: got 0x34
11:53:42 AM web.1 |      at newInvalidAsn1Error (/node_modules/asn1/lib/ber/errors.js:7:13)
11:53:42 AM web.1 |      at Reader.readString (/node_modules/asn1/lib/ber/reader.js:169:11)
11:53:42 AM web.1 |      at ECDSASigASN1ToSSH (/node_modules/ssh2-streams/lib/utils.js:133:21)
11:53:42 AM web.1 |      at /node_modules/ssh2-streams/lib/ssh.js:1622:19
11:53:42 AM web.1 |      at /node_modules/ssh2/lib/client.js:536:28
11:53:42 AM web.1 |      at Socket.onclose (/node_modules/ssh2/lib/agent.js:181:7)
11:53:42 AM web.1 |      at Object.onceWrapper (events.js:284:20)
11:53:42 AM web.1 |      at Socket.emit (events.js:196:13)
11:53:42 AM web.1 |      at Pipe.<anonymous> (net.js:586:12) ```
aleksmsd commented 5 years ago

As of Version 6.2.0, @baelter's statement rings true, and force-swapping the pubKeyFullType results in an InvalidAsn1Error Error. (it can throw with multiple different messages aside from Expected <ref>: got <ref>) However, as of Version 8.2.0 (latest I checked), force-swapping "ssh-rsa-cert-v01@openssh.com" to "ssh-rsa" actually works perfectly fine.

TimWolla commented 5 years ago

see #808

azaiter commented 4 years ago

see #808

Above PR doesn't really solve connecting to SSH2 hosts that can only authenticate through ssh-rsa-cert-v01@openssh.com for example.

Example debug output when using above PR branch:

SSH DEBUG:  DEBUG: Client: Connected
SSH DEBUG:  DEBUG: Parser: IN_INIT
SSH DEBUG:  DEBUG: Parser: IN_GREETING
SSH DEBUG:  DEBUG: Parser: IN_HEADER
SSH DEBUG:  DEBUG: Remote ident: 'SSH-2.0-Teleport'
SSH DEBUG:  DEBUG: Outgoing: Writing KEXINIT
SSH DEBUG:  DEBUG: Parser: IN_PACKETBEFORE (expecting 8)
SSH DEBUG:  DEBUG: Parser: IN_PACKET
SSH DEBUG:  DEBUG: Parser: pktLen:444,padLen:4,remainLen:440
SSH DEBUG:  DEBUG: Parser: IN_PACKETDATA
SSH DEBUG:  DEBUG: Parser: IN_PACKETDATAAFTER, packet: KEXINIT
SSH DEBUG:  DEBUG: Comparing KEXINITs ...
SSH DEBUG:  DEBUG: (local) KEX algorithms: ecdh-sha2-nistp256,ecdh-sha2-nistp384,ecdh-sha2-nistp521,diffie-hellman-group-exchange-sha256,diffie-hellman-group14-sha1
SSH DEBUG:  DEBUG: (remote) KEX algorithms: curve25519-sha256@libssh.org,ecdh-sha2-nistp256,ecdh-sha2-nistp384,ecdh-sha2-nistp521
SSH DEBUG:  DEBUG: KEX algorithm: ecdh-sha2-nistp256
SSH DEBUG:  DEBUG: (local) Host key formats: ssh-rsa,ecdsa-sha2-nistp256,ecdsa-sha2-nistp384,ecdsa-sha2-nistp521
SSH DEBUG:  DEBUG: (remote) Host key formats: ssh-rsa-cert-v01@openssh.com
SSH DEBUG:  DEBUG: No matching host key format
events.js:174
      throw er; // Unhandled 'error' event
TimWolla commented 4 years ago

Above PR doesn't really solve connecting to SSH2 hosts that can only authenticate through ssh-rsa-cert-v01@openssh.com for example.

My PR is for certificates for client authentication. It's not for server / machine authentication like your log appears to require.

paulkre commented 4 years ago

Would love to use this feature too.

davidchappelle commented 2 years ago

What needs to be done here to take this across the finish line? Seems it has been kicked down the road for 5-ish years.

bbthekings commented 2 years ago

any proposals in this case? at least an implementation approach? thanks

lichwala commented 1 year ago

Any news or at least implementation plans in this issue after a next year? :-) It seems that this library in the only one in npm for SSH connections - all the rest are just wrappers (please drop a link here if I'm wrong). I've just faced this issue and have to use ssh-agent-based authentication (will try it and I hope it works fine - I guess it would not be easy/trivial to implement Nodejs-based server solution for multi-users/accounts with agent-based authentication), but would be nice to have native certificate-based method here in this library...

realByg commented 5 months ago

bruh this is a 7-year-old issue, any work around for it?