runfalk
runfalk

Reputation: 1996

Handle multiple simultaneous SFTP connections

I'm implementing a SFTP server, using https://github.com/rspivak/sftpserver as reference. The reason for rolling out my own solution is a custom authentication scheme and special chrooting and black/whitelisting criterias.

My problem now is handling multiple connections at once. My current loop looks like this:

# Wait for a connection
conn, addr = server_socket.accept()

# Open a transport for this connection
tr = Transport(conn)

# Load our private host key
key = RSAKey.from_private_key_file("sftp.key")
tr.add_server_key(key)

# Tell server to support SFTP
tr.set_subsystem_handler("sftp", SFTPServer, sftp.ChrootedSFTP)

# Start a SSH server for this connection and serv it
server = auth.ChrootedAuthServer(db_factory, "/path/to/chroot")
tr.start_server(server=server)

# Wait for client to establish SSH connection
ch = tr.accept()

My solution doesn't have to be blazing fast. Just able to handle about 10 simultaneous connections, each pushing data every once in a while. How do I accomplish this?

Upvotes: 1

Views: 3097

Answers (3)

Mr. Girgitt
Mr. Girgitt

Reputation: 2903

Just in case anyone may need simple, multithreaded sftp server in python: the paramiko-based sftpserver module mentioned in the question can be quite easily converted to a multi-threaded version. Here is an example: https://gist.github.com/Girgitt/2df036f9e26dba1baaddf4c5845a20a2

Upvotes: 3

lonetwin
lonetwin

Reputation: 991

I know this is an old thread and I came across this earlier when I was faced with a slightly similar requirement. Although, I didn't really want to implement an entire sftp server, I had started with paramiko to do just that.

What I wanted in effect was to provide sftp access to an abstraction of a filesystem which in reality was being fed by a well defined api.

I started rolling my own solution only to realize that this was easier done by simply refocusing on what I actually needed. So, although this doesn't answer the question directly, I thought it might be useful to add a reference to my solution here for anyone else that stumbles this way.

My solution was to use a mix of openssh and paramiko.

With this solution all the ^heavy lifting^ of setting up the socket connection, authentication/key exchange etc and my sftp server would just implement the protocol commands. Note that this distinction is possible because sftp is simply a 'Subsystem' that the ssh server process communicates to over the stdin/stdout of the command that 'implements' the subsystem (ref: http://docstore.mik.ua/orelly/networking_2ndEd/ssh/ch05_07.htm )

So, to answer the original question in a very round about manner -- if you are interested in simply providing an sftp like interface to something (a chroot'd filesystem, in this case), you needn't even have to worry about handling multiple simultaneous sftp connections -- let opensshd do that for you. Just extend the paramiko facilities to implement your custom sftp instance, independent of the transport and channel.

Just in case this is of interest, here is the gist of my approach: https://gist.github.com/lonetwin/3b5982cf88c598c0e169

Upvotes: 1

Michael Fryer
Michael Fryer

Reputation: 359

You could use the subprocessing or threading modules to spawn a separate process for each instance of a client connection, where your main loop is taking care of managing the threads.

You could do this by having a connection instantiated and kept waiting for a client to connect, when that happens you can open a subprocess, pass the handler for the connection in to the subprocess and then make a new one for new connections.

Upvotes: 0

Related Questions