New SFTP API implementation

Hello! I was looking at the API docs, and noticed that a new SFTP endpoint was added, but I can’t seem to get it to work. It always sends the protocol upgrade response, but I don’t know what to do from there. Can anyone help me out with this?

Thanks - Joseph :slight_smile:

It’s currently just in master, it will be included in LXD 4.24 which is due out later this week.

GET /1.0/instances/NAME/sftp can indeed be upgraded using Upgrade: sftp and Connection: Upgrade. This then turns the connection into a raw bi-directional connection to a sftp server.

In our case, we use Go’s native SFTP client to access it or you can pass that as stdin/stdout to sshfs -o slave (or -o passive in newer releases).

I’ve been trying it out with the latest/edge channel, trying to figure out a way to maybe use it in JS. So if I just use an sshfs library I should be good to go?

If there is a library that lets you connect to the sftp server/protocol without establishing an ssh connection, then yes.

sftp package - github.com/pkg/sftp - pkg.go.dev is the Go version of such a client.

Looks like if your trying to use this in node.js it will fail silently because node.js doesn’t know how to handle the SFTP protocol upgrade. Of course that’s probably out of scope for them but my plan was to provide the underlying Net.Socket to the SSH2 package but that wont be possible if node.js just kills the socket because it doesn’t understand it.

Hopefully im wrong and someone can correct me on this but in the mean time ive opened an issue here.

Its technically not a websocket, but an upgraded HTTPS connection passing the raw unencrypted SFTP protocol (not inside an SSH connection because its already encrypted by the HTTPS outer layer).

So really node.js just needs to support upgrading an HTTP connection to a raw stream and then providing a connection handle to that stream.

I don’t know very much about node.js, but keep in mind that the raw SFTP stream from LXD’s API is not an SSH stream, it is just an SFTP stream.

This is how we handle both passing stdout/stdin to sshfs and providing a local SSH SFTP listener in the lxc command using the SFTP stream from the LXD API:

The blurb for a Net.Socket is;

" This class is an abstraction of a TCP socket or a streaming IPC endpoint (uses named pipes on Windows, and Unix domain sockets otherwise). It is also an EventEmitter."

Thats whats needed here right…?

Yes sounds reasonable, but passing it to the SSH2 package (if its expecting an SSH stream) may be problematic.

One step at a time, if the language wont give me a socket cant hack at the next part :wink:

1 Like

I’ve already gotten it working in node by spawning a go child process then using a unix socket to communicate node <—> go. Works flawlessly.

Nice!

We also have a fix that should make node.js happier:

Nice!

Not a fan of the socket approach so im waiting on the above!