Natizyskunk / vscode-sftp

Super fast sftp/ftp extension for VS Code
Other
373 stars 68 forks source link

SSH private key to OpenSSH 8.8 server #112

Open StevenSchoch opened 2 years ago

StevenSchoch commented 2 years ago

Our web server (pair.com) recently (a few months ago) upgraded their SSH server to OpenSSH 8.8. This caused private keys sent from older SSH clients to fail. When using a private key (via ssh-agent), vscode-sftp fails with "All configured authentication methods failed."

Connecting with the same private key to an OpenSSH 8.0 system works from vscode-sftp. Connecting with the same private key to the OpenSSH 8.8 system works from ssh on MacOS.

This same issue with vscode-sftp also occurs with Putty 0.74, but is fixed with Putty 0.76.

In summary, using an SSH private key to authenticate:

vscode-sftp -> OpenSSH 8.0 works. vscode-sftp -> OpenSSH 8.8 fails. MacOS command-line ssh -> OpenSSL 8.8 (and 8.0) works. Putty 0.74 -> OpenSSH 8.0 works. Putty 0.74 -> OpenSSH 8.8 fails. Putty 0.76 -> OpenSSHl 8.8 (and 8.0) works.

The reason I mention Putty is that the problem was fixed in the protocol change they made from 0.74 to 0.75. In order to fix the problem with vscode-sftp, the same change may be required.

Using VSCode version 1.63.2 OS: MacOS High Sierra version 10.13.6 vscode-sftp version: 1.15.10

Logs:

[02-01 18:55:50] [debug] register command "Cancel All Transfer" from "./commandCancelAllTransfer.ts"
[02-01 18:55:50] [debug] register command "Config" from "./commandConfig.ts"
[02-01 18:55:50] [debug] register command "List Active Folder" from "./commandListActiveFolder.ts"
[02-01 18:55:50] [debug] register command "Open Ssh Connection" from "./commandOpenSshConnection.ts"
[02-01 18:55:50] [debug] register command "Set Profile" from "./commandSetProfile.ts"
[02-01 18:55:50] [debug] register command "Toggle Output Panel" from "./commandToggleOutputPanel.ts"
[02-01 18:55:50] [debug] register command "Upload Changed Files" from "./commandUploadChangedFiles.ts"
[02-01 18:55:50] [debug] register command "Create File" from "./fileCommandCreateFile.ts"
[02-01 18:55:50] [debug] register command "Create Folder" from "./fileCommandCreateFolder.ts"
[02-01 18:55:50] [debug] register command "Delete Remote" from "./fileCommandDeleteRemote.ts"
[02-01 18:55:50] [debug] register command "Diff" from "./fileCommandDiff.ts"
[02-01 18:55:50] [debug] register command "Diff Active File" from "./fileCommandDiffActiveFile.ts"
[02-01 18:55:50] [debug] register command "Download" from "./fileCommandDownload.ts"
[02-01 18:55:50] [debug] register command "Download Active File" from "./fileCommandDownloadActiveFile.ts"
[02-01 18:55:50] [debug] register command "Download Active Folder" from "./fileCommandDownloadActiveFolder.ts"
[02-01 18:55:50] [debug] register command "Download File" from "./fileCommandDownloadFile.ts"
[02-01 18:55:50] [debug] register command "Download Folder" from "./fileCommandDownloadFolder.ts"
[02-01 18:55:50] [debug] register command "Download Force" from "./fileCommandDownloadForce.ts"
[02-01 18:55:50] [debug] register command "Download Project" from "./fileCommandDownloadProject.ts"
[02-01 18:55:50] [debug] register command "Edit In Local" from "./fileCommandEditInLocal.ts"
[02-01 18:55:50] [debug] register command "List" from "./fileCommandList.ts"
[02-01 18:55:50] [debug] register command "List All" from "./fileCommandListAll.ts"
[02-01 18:55:50] [debug] register command "Reveal In Explorer" from "./fileCommandRevealInExplorer.ts"
[02-01 18:55:50] [debug] register command "Reveal In Remote Explorer" from "./fileCommandRevealInRemoteExplorer.ts"
[02-01 18:55:50] [debug] register command "Sync Both Directions" from "./fileCommandSyncBothDirections.ts"
[02-01 18:55:50] [debug] register command "Sync Local To Remote" from "./fileCommandSyncLocalToRemote.ts"
[02-01 18:55:50] [debug] register command "Sync Remote To Local" from "./fileCommandSyncRemoteToLocal.ts"
[02-01 18:55:50] [debug] register command "Upload" from "./fileCommandUpload.ts"
[02-01 18:55:50] [debug] register command "Upload Active File" from "./fileCommandUploadActiveFile.ts"
[02-01 18:55:50] [debug] register command "Upload Active Folder" from "./fileCommandUploadActiveFolder.ts"
[02-01 18:55:50] [debug] register command "Upload File" from "./fileCommandUploadFile.ts"
[02-01 18:55:50] [debug] register command "Upload Folder" from "./fileCommandUploadFolder.ts"
[02-01 18:55:50] [debug] register command "Upload Force" from "./fileCommandUploadForce.ts"
[02-01 18:55:50] [debug] register command "Upload Project" from "./fileCommandUploadProject.ts"
[02-01 18:55:51] [info] config at /Users/steven/Documents/XXXXXXXX {"remotePath":"public_html/XXX","uploadOnSave":false,"useTempFile":false,"openSsh":false,"downloadOnOpen":false,"ignore":[],"concurrency":4,"protocol":"sftp","connectTimeout":10000,"interactiveAuth":false,"secure":false,"remoteTimeOffsetInHours":0,"name":"Pair","host":"XXX.pairserver.com","port":22,"username":"******","agent":"$SSH_AUTH_SOCK"}
[02-01 18:55:53] [trace] run command 'Upload File'
[02-01 18:55:53] [trace] handle upload file for /Users/steven/Documents/XXXXXXXX/download/index.php
[02-01 18:55:53] [debug] Custom crypto binding not available
[02-01 18:55:53] [debug] Local ident: 'SSH-2.0-ssh2js1.5.0'
[02-01 18:55:53] [debug] Client: Trying XXX.pairserver.com on port 22 ...
[02-01 18:55:53] [debug] Socket connected
[02-01 18:55:53] [debug] Remote ident: 'SSH-2.0-OpenSSH_8.8'
[02-01 18:55:53] [debug] Outbound: Sending KEXINIT
[02-01 18:55:53] [debug] Inbound: Handshake in progress
[02-01 18:55:53] [debug] 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
[02-01 18:55:53] [debug] Handshake: (remote) KEX method: curve25519-sha256,curve25519-sha256@libssh.org,ecdh-sha2-nistp256,ecdh-sha2-nistp384,ecdh-sha2-nistp521,diffie-hellman-group-exchange-sha256,diffie-hellman-group16-sha512,diffie-hellman-group18-sha512,diffie-hellman-group14-sha256,diffie-hellman-group1-sha1
[02-01 18:55:53] [debug] Handshake: KEX algorithm: curve25519-sha256@libssh.org
[02-01 18:55:53] [debug] Handshake: (local) Host key format: ssh-ed25519,ecdsa-sha2-nistp256,ecdsa-sha2-nistp384,ecdsa-sha2-nistp521,rsa-sha2-512,rsa-sha2-256,ssh-rsa
[02-01 18:55:53] [debug] Handshake: (remote) Host key format: rsa-sha2-512,rsa-sha2-256,ssh-rsa,ecdsa-sha2-nistp256,ssh-ed25519
[02-01 18:55:53] [debug] Handshake: Host key format: ssh-ed25519
[02-01 18:55:53] [debug] Handshake: (local) C->S cipher: aes128-gcm@openssh.com,aes256-gcm@openssh.com,aes128-ctr,aes192-ctr,aes256-ctr,chacha20-poly1305@openssh.com
[02-01 18:55:53] [debug] Handshake: (remote) C->S cipher: chacha20-poly1305@openssh.com,aes128-ctr,aes192-ctr,aes256-ctr,aes128-gcm@openssh.com,aes256-gcm@openssh.com,aes128-cbc,3des-cbc,aes192-cbc,aes256-cbc
[02-01 18:55:53] [debug] Handshake: C->S Cipher: aes128-gcm@openssh.com
[02-01 18:55:53] [debug] Handshake: (local) S->C cipher: aes128-gcm@openssh.com,aes256-gcm@openssh.com,aes128-ctr,aes192-ctr,aes256-ctr,chacha20-poly1305@openssh.com
[02-01 18:55:53] [debug] Handshake: (remote) S->C cipher: chacha20-poly1305@openssh.com,aes128-ctr,aes192-ctr,aes256-ctr,aes128-gcm@openssh.com,aes256-gcm@openssh.com,aes128-cbc,3des-cbc,aes192-cbc,aes256-cbc
[02-01 18:55:53] [debug] Handshake: S->C cipher: aes128-gcm@openssh.com
[02-01 18:55:53] [debug] 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
[02-01 18:55:53] [debug] Handshake: (remote) C->S MAC: umac-64-etm@openssh.com,umac-128-etm@openssh.com,hmac-sha2-256-etm@openssh.com,hmac-sha2-512-etm@openssh.com,hmac-sha1-etm@openssh.com,umac-64@openssh.com,umac-128@openssh.com,hmac-sha2-256,hmac-sha2-512,hmac-sha1,hmac-md5-etm@openssh.com,hmac-sha1-96-etm@openssh.com,hmac-md5-96-etm@openssh.com,hmac-md5,hmac-sha1-96,hmac-md5-96
[02-01 18:55:53] [debug] Handshake: C->S MAC: <implicit>
[02-01 18:55:53] [debug] 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
[02-01 18:55:53] [debug] Handshake: (remote) S->C MAC: umac-64-etm@openssh.com,umac-128-etm@openssh.com,hmac-sha2-256-etm@openssh.com,hmac-sha2-512-etm@openssh.com,hmac-sha1-etm@openssh.com,umac-64@openssh.com,umac-128@openssh.com,hmac-sha2-256,hmac-sha2-512,hmac-sha1,hmac-md5-etm@openssh.com,hmac-sha1-96-etm@openssh.com,hmac-md5-96-etm@openssh.com,hmac-md5,hmac-sha1-96,hmac-md5-96
[02-01 18:55:53] [debug] Handshake: S->C MAC: <implicit>
[02-01 18:55:53] [debug] Handshake: (local) C->S compression: none,zlib@openssh.com,zlib
[02-01 18:55:53] [debug] Handshake: (remote) C->S compression: none,zlib@openssh.com
[02-01 18:55:53] [debug] Handshake: C->S compression: none
[02-01 18:55:53] [debug] Handshake: (local) S->C compression: none,zlib@openssh.com,zlib
[02-01 18:55:53] [debug] Handshake: (remote) S->C compression: none,zlib@openssh.com
[02-01 18:55:53] [debug] Handshake: S->C compression: none
[02-01 18:55:53] [debug] Outbound: Sending KEXECDH_INIT
[02-01 18:55:53] [debug] Received DH Reply
[02-01 18:55:53] [debug] Host accepted by default (no verification)
[02-01 18:55:53] [debug] Host accepted (verified)
[02-01 18:55:53] [debug] Outbound: Sending NEWKEYS
[02-01 18:55:53] [debug] Inbound: NEWKEYS
[02-01 18:55:53] [debug] Verifying signature ...
[02-01 18:55:53] [debug] Verified signature
[02-01 18:55:53] [debug] Handshake completed
[02-01 18:55:53] [debug] Outbound: Sending SERVICE_REQUEST (ssh-userauth)
[02-01 18:55:53] [debug] Inbound: Received SERVICE_ACCEPT (ssh-userauth)
[02-01 18:55:53] [debug] Outbound: Sending USERAUTH_REQUEST (none)
[02-01 18:55:54] [debug] Inbound: Received USERAUTH_FAILURE (publickey,password,keyboard-interactive)
[02-01 18:55:54] [debug] Client: none auth failed
[02-01 18:55:54] [debug] Agent: Trying key #1
[02-01 18:55:54] [debug] Outbound: Sending USERAUTH_REQUEST (publickey -- check)
[02-01 18:55:54] [debug] Inbound: Received USERAUTH_FAILURE (publickey,password,keyboard-interactive)
[02-01 18:55:54] [debug] Client: Agent key #1 failed
[02-01 18:55:54] [debug] Agent: No more keys left to try
[02-01 18:55:54] [debug] Client: agent auth failed
[02-01 18:55:54] [debug] Outbound: Sending DISCONNECT (11)
[02-01 18:55:54] [error] Error: [XXX.pairserver.com]: All configured authentication methods failed
    at Client.<anonymous> (/Users/steven/.vscode/extensions/natizyskunk.sftp-1.15.10/dist/extension.js:2:242540)
    at Client.emit (events.js:327:22)
    at doNextAuth (/Users/steven/.vscode/extensions/natizyskunk.sftp-1.15.10/node_modules/ssh2/lib/client.js:805:14)
    at tryNextAuth (/Users/steven/.vscode/extensions/natizyskunk.sftp-1.15.10/node_modules/ssh2/lib/client.js:993:7)
    at tryNextAgentKey (/Users/steven/.vscode/extensions/natizyskunk.sftp-1.15.10/node_modules/ssh2/lib/client.js:1002:11)
    at USERAUTH_FAILURE (/Users/steven/.vscode/extensions/natizyskunk.sftp-1.15.10/node_modules/ssh2/lib/client.js:366:20)
    at 51 (/Users/steven/.vscode/extensions/natizyskunk.sftp-1.15.10/node_modules/ssh2/lib/protocol/handlers.misc.js:337:16)
    at Protocol.onPayload (/Users/steven/.vscode/extensions/natizyskunk.sftp-1.15.10/node_modules/ssh2/lib/protocol/Protocol.js:2025:10)
    at AESGCMDecipherNative.decrypt (/Users/steven/.vscode/extensions/natizyskunk.sftp-1.15.10/node_modules/ssh2/lib/protocol/crypto.js:987:26)
    at Protocol.parsePacket [as _parse] (/Users/steven/.vscode/extensions/natizyskunk.sftp-1.15.10/node_modules/ssh2/lib/protocol/Protocol.js:1994:25)
    at Protocol.parse (/Users/steven/.vscode/extensions/natizyskunk.sftp-1.15.10/node_modules/ssh2/lib/protocol/Protocol.js:293:16)
    at Socket.<anonymous> (/Users/steven/.vscode/extensions/natizyskunk.sftp-1.15.10/node_modules/ssh2/lib/client.js:713:21)
    at Socket.emit (events.js:315:20)
    at addChunk (internal/streams/readable.js:309:12)
    at readableAddChunk (internal/streams/readable.js:284:9)
    at Socket.Readable.push (internal/streams/readable.js:223:10)
    at TCP.onStreamRead (internal/stream_base_commons.js:188:23) 
[02-01 18:55:54] [debug] Socket ended
[02-01 18:55:54] [debug] Socket closed
Christoph142 commented 2 years ago

I'm seeing the same issue.

StevenSchoch commented 2 years ago

This article about ssh-rsa deprecation helps explain this issue. In the context of SSH public key signature, the algorithm "ssh-rsa" uses RSA and SHA-1. Because the SHA-1 algorithm was broken in 2017, it is no longer accepted as a way to send SSH public key signatures as of OpenSSH 8.8.

Instead, the more secure algorithms, which use SHA-2, are used instead. These include rsa-ssh2-256 and rsa-ssh2-512.

Newer SSH clients, such as Putty 0.76, have support for these algorithms. Older SSH clients, such as Putty 0.74 and vscode-sftp, do not support these. This can be seen from the debug output:

[02-04 12:10:49] [debug] Handshake: (local) Host key format: ssh-rsa,ecdsa-sha2-nistp256,ecdsa-sha2-nistp384,ecdsa-sha2-nistp521
[02-04 12:10:49] [debug] Handshake: (remote) Host key format: rsa-sha2-512,rsa-sha2-256,ssh-rsa,ecdsa-sha2-nistp256,ssh-ed25519
[02-04 12:10:49] [debug] Handshake: Host key format: ssh-rsa

The very confusing part is that these algorithms are used in both the SSH host key verification (which identifies the SSH server to which the client is connecting), and the public key signature, which is used for private key authentication. OpenSSH 8.8 disabled the use of ssh-rsa for public key signatures, but still have it available for host key verification, because otherwise many old SSH clients wouldn't be able to connect. Using the broken SHA-1 algorithm to verify the host key is not a big security issue, because it can't be used by an attacker against a SSH server. This means that the ssh-rsa algorithm is still offered as a host key format, but if the client offers a public key with that algorithm, the server declines it, as if that public key was not in the authorized_keys file.

The solution is to add the rsa-sha2-512 algorithm to vscode-sftp.

I suppose if I could create an ECDSA public key, then the ecdsa-sha2-nist256 algorithm could be used. I'll have to look into that.

StevenSchoch commented 2 years ago

Update: Using an ECDSA key worked.

Natizyskunk commented 2 years ago

@StevenSchoch, @Christoph142, This should be fixed in pull-request #119.

You can test it by downloading or updating to the latest version of the extension available here. 😉

Please tell me if it works fine now.

inorganik commented 1 year ago

Hi, I'm hitting the same issue, with a new server running OpenSSH 8.9.

I am able to connect using command line sftp, so it seems like it should work with the extension.

With the extension I just get the error: "Error: [ip address]: All configured authentication methods failed". I have checked and re-checked the config, it's correct. Is there anything else I can try?

Forgot to mention I'm running v1.15.14 of SFTP

Natizyskunk commented 1 year ago

please check that if you're using ssh private+public key combo that you've correctly added your local public key to your .ssh/authorized_keys file on your server.

inorganik commented 1 year ago

@Natizyskunk Yes, I regularly ssh into the server via public key, so I know that is set up correctly.

peter-vanpoucke commented 1 year ago

Doesn't seem to work for me either. Tried to add the algorithms mentioned in the fix, but that didn't seem to work. Using an ECDSA key pair did. The RSA key does work for putty though. Connecting to the ssh server for this project: https://github.com/hassio-addons/addon-ssh.

Natizyskunk commented 1 year ago

Please update your sftp extension to the latest version and try this config then let me know if it worked.

{
  "useTempFile": true,
  "openSsh": true, // <-- you can also try with false but keep in mind that if you set it to true, `useTempFile` must also be set to true.
  "algorithms": {
    "kex": [
      "ecdh-sha2-nistp256",
      "ecdh-sha2-nistp384",
      "ecdh-sha2-nistp521",
      "diffie-hellman-group-exchange-sha256" // <-- this can keep closing the connection for those who use more legacy/old systems problem so please also try without it !
    ],
    "cipher": [
      "aes128-gcm",
      "aes128-gcm@openssh.com",
      "aes256-gcm",
      "aes256-gcm@openssh.com",
      "aes128-cbc",
      "aes192-cbc",
      "aes256-cbc",
      "aes128-ctr",
      "aes192-ctr",
      "aes256-ctr"
    ],
    "serverHostKey": [
      "ssh-rsa",
      "ssh-dss",
      "ssh-ed25519",
      "ecdsa-sha2-nistp256",
      "ecdsa-sha2-nistp384",
      "ecdsa-sha2-nistp521",
      "rsa-sha2-256",
      "rsa-sha2-512"
    ],
    "hmac": [
      "hmac-sha2-256",
      "hmac-sha2-512"
    ]
  }
}

I'll try to take a further look when i've more time.

inorganik commented 1 year ago

When you say latest version, do you mean 1.15.19? That is the latest I can find... tried augmenting my config with what you have above, in various combinations with openSsh set to both true and false and diffie-hellman-group-exchange-sha256 included and excluded, but no luck.

Natizyskunk commented 1 year ago

@inorganik, I'm sorry to hear that. I'll keep an eye on this issue and I'll let everyone know if a fix is found.

inorganik commented 1 year ago

@Natizyskunk no worries. On the bright side, I've found using the sftp CLI is pretty painless.

laubsterboy commented 1 year ago

Similar to @peter-vanpoucke I was able to get this working by creating a new key pair using the EdDSA algorithm instead or RSA.