Open 0x7f opened 7 months ago
Out of curiosity can you post debug output on the ssh2
side (setting debug: console.log
in the server config object)?
Also have you tried different key types to try to isolate the problem?
Below you can find the output of the debug log. I will try other authentication types (password and different key types) and let you know.
SSH server successfully started on ssh://127.0.0.1:8022
[516174.643760916] Custom crypto binding available
[516174.643760916] Local ident: 'SSH-2.0-ssh2js1.15.0'
[516174.643760916] Remote ident: 'SSH-2.0-Go'
SSH Client connected
[516174.643760916] Outbound: Sending KEXINIT
[516174.643760916] Inbound: Handshake in progress
[516174.643760916] Handshake: (local) KEX method: curve25519-sha256@libssh.org,curve25519-sha256,ecdh-sha2-nistp256,ecdh-sha2-nistp384,ecdh-sha2-nistp521,diffie-hellman-group-exchange-sha256,diffie-hellman-group14-sha256,diffie-hellman-group15-sha512,diffie-hellman-group16-sha512,diffie-hellman-group17-sha512,diffie-hellman-group18-sha512,kex-strict-s-v00@openssh.com
[516174.643760916] Handshake: (remote) KEX method: curve25519-sha256,curve25519-sha256@libssh.org,ecdh-sha2-nistp256,ecdh-sha2-nistp384,ecdh-sha2-nistp521,diffie-hellman-group14-sha256,diffie-hellman-group14-sha1,ext-info-c,kex-strict-c-v00@openssh.com
[516174.643760916] Handshake: strict KEX mode enabled
[516174.643760916] Handshake: KEX algorithm: curve25519-sha256
[516174.643760916] Handshake: (local) Host key format: rsa-sha2-512,rsa-sha2-256,ssh-rsa
[516174.643760916] Handshake: (remote) Host key format: rsa-sha2-256-cert-v01@openssh.com,rsa-sha2-512-cert-v01@openssh.com,ssh-rsa-cert-v01@openssh.com,ssh-dss-cert-v01@openssh.com,ecdsa-sha2-nistp256-cert-v01@openssh.com,ecdsa-sha2-nistp384-cert-v01@openssh.com,ecdsa-sha2-nistp521-cert-v01@openssh.com,ssh-ed25519-cert-v01@openssh.com,ecdsa-sha2-nistp256,ecdsa-sha2-nistp384,ecdsa-sha2-nistp521,rsa-sha2-256,rsa-sha2-512,ssh-rsa,ssh-dss,ssh-ed25519
[516174.643760916] Handshake: Host key format: rsa-sha2-256
[516174.643760916] Handshake: (local) C->S cipher: aes128-gcm@openssh.com,aes256-gcm@openssh.com,aes128-ctr,aes192-ctr,aes256-ctr,chacha20-poly1305@openssh.com
[516174.643760916] Handshake: (remote) C->S cipher: aes128-gcm@openssh.com,aes256-gcm@openssh.com,chacha20-poly1305@openssh.com,aes128-ctr,aes192-ctr,aes256-ctr
[516174.643760916] Handshake: C->S Cipher: aes128-gcm@openssh.com
[516174.643760916] Handshake: (local) S->C cipher: aes128-gcm@openssh.com,aes256-gcm@openssh.com,aes128-ctr,aes192-ctr,aes256-ctr,chacha20-poly1305@openssh.com
[516174.643760916] Handshake: (remote) S->C cipher: aes128-gcm@openssh.com,aes256-gcm@openssh.com,chacha20-poly1305@openssh.com,aes128-ctr,aes192-ctr,aes256-ctr
[516174.643760916] Handshake: S->C cipher: aes128-gcm@openssh.com
[516174.643760916] Handshake: (local) C->S MAC: hmac-sha2-256-etm@openssh.com,hmac-sha2-512-etm@openssh.com,hmac-sha1-etm@openssh.com,hmac-sha2-256,hmac-sha2-512,hmac-sha1
[516174.643760916] Handshake: (remote) C->S MAC: hmac-sha2-256-etm@openssh.com,hmac-sha2-512-etm@openssh.com,hmac-sha2-256,hmac-sha2-512,hmac-sha1,hmac-sha1-96
[516174.643760916] Handshake: C->S MAC: <implicit>
[516174.643760916] Handshake: (local) S->C MAC: hmac-sha2-256-etm@openssh.com,hmac-sha2-512-etm@openssh.com,hmac-sha1-etm@openssh.com,hmac-sha2-256,hmac-sha2-512,hmac-sha1
[516174.643760916] Handshake: (remote) S->C MAC: hmac-sha2-256-etm@openssh.com,hmac-sha2-512-etm@openssh.com,hmac-sha2-256,hmac-sha2-512,hmac-sha1,hmac-sha1-96
[516174.643760916] Handshake: S->C MAC: <implicit>
[516174.643760916] Handshake: (local) C->S compression: none,zlib@openssh.com,zlib
[516174.643760916] Handshake: (remote) C->S compression: none
[516174.643760916] Handshake: C->S compression: none
[516174.643760916] Handshake: (local) S->C compression: none,zlib@openssh.com,zlib
[516174.643760916] Handshake: (remote) S->C compression: none
[516174.643760916] Handshake: S->C compression: none
[516174.643760916] Received DH Init
[516174.643760916] Generating signature ...
[516174.643760916] Outbound: Sending KEXECDH_REPLY
[516174.643760916] Outbound: Sending NEWKEYS
[516174.643760916] Inbound: NEWKEYS
[516174.643760916] Handshake completed
[516174.643760916] Outbound: Sending EXT_INFO
[516174.643760916] Inbound: Received SERVICE_REQUEST (ssh-userauth)
[516174.643760916] Outbound: Sending SERVICE_ACCEPT (ssh-userauth)
[516174.643760916] Inbound: Received USERAUTH_REQUEST (none)
authentication none test
Auth request with method none
[516174.643760916] Outbound: Sending USERAUTH_FAILURE
[516174.643760916] Inbound: Received USERAUTH_REQUEST (publickey -- check)
authentication publickey test
User test successfully authenticated with public key
[516174.643760916] Outbound: Sending USERAUTH_PK_OK
[516174.643760916] Socket ended
Client disconnected
[516174.643760916] Socket closed
It looks like it is working as expected when using a key of type ed25519
. I created a branch in the other repo to show the client code changes: https://github.com/0x7f/ssh-authentication-bug/pull/1 The client prints this:
2024/03/21 14:55:22 Connected to SSH server
And these are the debug logs of the server:
SSH server successfully started on ssh://127.0.0.1:8022
[518853.545241708] Custom crypto binding available
[518853.545241708] Local ident: 'SSH-2.0-ssh2js1.15.0'
[518853.545241708] Remote ident: 'SSH-2.0-Go'
SSH Client connected
[518853.545241708] Outbound: Sending KEXINIT
[518853.545241708] Inbound: Handshake in progress
[518853.545241708] Handshake: (local) KEX method: curve25519-sha256@libssh.org,curve25519-sha256,ecdh-sha2-nistp256,ecdh-sha2-nistp384,ecdh-sha2-nistp521,diffie-hellman-group-exchange-sha256,diffie-hellman-group14-sha256,diffie-hellman-group15-sha512,diffie-hellman-group16-sha512,diffie-hellman-group17-sha512,diffie-hellman-group18-sha512,kex-strict-s-v00@openssh.com
[518853.545241708] Handshake: (remote) KEX method: curve25519-sha256,curve25519-sha256@libssh.org,ecdh-sha2-nistp256,ecdh-sha2-nistp384,ecdh-sha2-nistp521,diffie-hellman-group14-sha256,diffie-hellman-group14-sha1,ext-info-c,kex-strict-c-v00@openssh.com
[518853.545241708] Handshake: strict KEX mode enabled
[518853.545241708] Handshake: KEX algorithm: curve25519-sha256
[518853.545241708] Handshake: (local) Host key format: rsa-sha2-512,rsa-sha2-256,ssh-rsa
[518853.545241708] Handshake: (remote) Host key format: rsa-sha2-256-cert-v01@openssh.com,rsa-sha2-512-cert-v01@openssh.com,ssh-rsa-cert-v01@openssh.com,ssh-dss-cert-v01@openssh.com,ecdsa-sha2-nistp256-cert-v01@openssh.com,ecdsa-sha2-nistp384-cert-v01@openssh.com,ecdsa-sha2-nistp521-cert-v01@openssh.com,ssh-ed25519-cert-v01@openssh.com,ecdsa-sha2-nistp256,ecdsa-sha2-nistp384,ecdsa-sha2-nistp521,rsa-sha2-256,rsa-sha2-512,ssh-rsa,ssh-dss,ssh-ed25519
[518853.545241708] Handshake: Host key format: rsa-sha2-256
[518853.545241708] Handshake: (local) C->S cipher: aes128-gcm@openssh.com,aes256-gcm@openssh.com,aes128-ctr,aes192-ctr,aes256-ctr,chacha20-poly1305@openssh.com
[518853.545241708] Handshake: (remote) C->S cipher: aes128-gcm@openssh.com,aes256-gcm@openssh.com,chacha20-poly1305@openssh.com,aes128-ctr,aes192-ctr,aes256-ctr
[518853.545241708] Handshake: C->S Cipher: aes128-gcm@openssh.com
[518853.545241708] Handshake: (local) S->C cipher: aes128-gcm@openssh.com,aes256-gcm@openssh.com,aes128-ctr,aes192-ctr,aes256-ctr,chacha20-poly1305@openssh.com
[518853.545241708] Handshake: (remote) S->C cipher: aes128-gcm@openssh.com,aes256-gcm@openssh.com,chacha20-poly1305@openssh.com,aes128-ctr,aes192-ctr,aes256-ctr
[518853.545241708] Handshake: S->C cipher: aes128-gcm@openssh.com
[518853.545241708] Handshake: (local) C->S MAC: hmac-sha2-256-etm@openssh.com,hmac-sha2-512-etm@openssh.com,hmac-sha1-etm@openssh.com,hmac-sha2-256,hmac-sha2-512,hmac-sha1
[518853.545241708] Handshake: (remote) C->S MAC: hmac-sha2-256-etm@openssh.com,hmac-sha2-512-etm@openssh.com,hmac-sha2-256,hmac-sha2-512,hmac-sha1,hmac-sha1-96
[518853.545241708] Handshake: C->S MAC: <implicit>
[518853.545241708] Handshake: (local) S->C MAC: hmac-sha2-256-etm@openssh.com,hmac-sha2-512-etm@openssh.com,hmac-sha1-etm@openssh.com,hmac-sha2-256,hmac-sha2-512,hmac-sha1
[518853.545241708] Handshake: (remote) S->C MAC: hmac-sha2-256-etm@openssh.com,hmac-sha2-512-etm@openssh.com,hmac-sha2-256,hmac-sha2-512,hmac-sha1,hmac-sha1-96
[518853.545241708] Handshake: S->C MAC: <implicit>
[518853.545241708] Handshake: (local) C->S compression: none,zlib@openssh.com,zlib
[518853.545241708] Handshake: (remote) C->S compression: none
[518853.545241708] Handshake: C->S compression: none
[518853.545241708] Handshake: (local) S->C compression: none,zlib@openssh.com,zlib
[518853.545241708] Handshake: (remote) S->C compression: none
[518853.545241708] Handshake: S->C compression: none
[518853.545241708] Received DH Init
[518853.545241708] Generating signature ...
[518853.545241708] Outbound: Sending KEXECDH_REPLY
[518853.545241708] Outbound: Sending NEWKEYS
[518853.545241708] Inbound: NEWKEYS
[518853.545241708] Handshake completed
[518853.545241708] Outbound: Sending EXT_INFO
[518853.545241708] Inbound: Received SERVICE_REQUEST (ssh-userauth)
[518853.545241708] Outbound: Sending SERVICE_ACCEPT (ssh-userauth)
[518853.545241708] Inbound: Received USERAUTH_REQUEST (none)
authentication none test
Auth request with method none
[518853.545241708] Outbound: Sending USERAUTH_FAILURE
[518853.545241708] Inbound: Received USERAUTH_REQUEST (publickey -- check)
authentication publickey test
User test successfully authenticated with public key
[518853.545241708] Outbound: Sending USERAUTH_PK_OK
[518853.545241708] Inbound: Received USERAUTH_REQUEST (publickey)
authentication publickey test
User test successfully authenticated with public key
[518853.545241708] Outbound: Sending USERAUTH_SUCCESS
Client authenticated!
[518853.545241708] Socket ended
Client disconnected
[518853.545241708] Socket closed
@mscdex as far as o understand the latest comment in the other issue (https://github.com/golang/go/issues/66438#issuecomment-2016458723) the ssh2 library is doing something non-standard which is handled by OpenSSL client, but not by the go client. The go folks want to add this to their client as well. But maybe it is worth changing the ssh2 server component to be compatible with other clients still? For example, I have clients out in the wild which are compiled with the old version of the go library and are not able to connect.
I did some more testing. I can confirm that my issue is fixed when using the proposed patch for the golang SSH client which accepts the algo returned by the ssh2 server. That's great.
But as mentioned above, I'd love to have the server compatible with old versions of the golang client as well. So I did the following local change to the PKAuthContext class:
@@ -144,11 +144,24 @@
accept() {
if (!this.signature) {
this._initialResponse = true;
- this._protocol.authPKOK(this.key.algo, this.key.data);
+ this._protocol.authPKOK(this.getResponseAlgo(), this.key.data);
} else {
AuthContext.prototype.accept.call(this);
}
}
+
+ getResponseAlgo() {
+ if (this.key.algo === 'ssh-rsa') {
+ switch (this.hashAlgo) {
+ case 'sha256':
+ return 'rsa-sha2-256';
+ case 'sha512':
+ return 'rsa-sha2-512';
+ }
+ }
+
+ return this.key.algo;
+ }
}
class HostbasedAuthContext extends AuthContext {
It is not beautiful and most probably the mapping belongs somewhere else (either Protocol.js
or kex.js
), but it works. With this change, the old golang client can connect as well. The openssh client can connect to this version of the server as well.
I'm not sure though whether this is really what the RFC requires (see this comment).
see According to RFC 4252 Section 7 the algorithm in SSH_MSG_USERAUTH_REQUEST should match that of the request, so our code was correct, but some server send the key type instead.
@mscdex can you please have a look at this? Happy to provide a PR if needed.
@mscdex let me know if I can help in any way to get this fixed.
Using MacOS Terminal.app I get the same. RSA keys don't work. ED25519 keys work.
Also experiencing this. In my case, RSA keys don't work when connecting to Fedora Linux, but other key types work fine. All key types seem to work when connecting to Debian Linux. I'm using ssh2 version 1.16.0
It turns out my issue was solved by changing the key bit length from 1024 to 2048. I used a small key since my use-case is just in a VM sandbox for testing purposes, but I guess some default configurations block RSA keys of small bit lengths
I'm building a SSH server using your Node.js library and I'm building the SSH client using the x/crypto/ssh Golang library. The client aborts the SSH handshake when using the publickey authentication method.
I built an example project including server and client here: https://github.com/0x7f/ssh-authentication-bug
Even though the server offers [publickey] authentication methods when initiating the handshake with authentication method none, the client fails to connect. The client uses the publickey method and offers the key, and the server accepts the key, but the client still prints the error:
I'm trying to figure out whether this is a bug in the server library or the client library. I already posted a bug in the Golang project: https://github.com/golang/go/issues/66438. Either the Node.js server library is doing something non-standard during the handshake, or the client has some issue, or I'm stupid and did something wrong in the code. The OpenSSH client works though.
Let me know when you need more information.