SSH - a way to transfer files without opening a separate SFTP session?

You could set up such an inverted transfer connection w/

ssh -Rport:127.0.0.1:22 user@host

for scp back.

Use scp user@host:port to access it.


In researching this I found a program that works as a drop-in replacement for the openssh client, zssh.

sudo apt-get install zssh
zssh user@remote
sudo apt-get install zssh
sz file.name
<ctrl>+<space>
rz

Works like a charm.


Here is my preferred solution to this problem [as given on a duplicate question I asked]. Set up a reverse ssh tunnel upon creating the ssh session. This is made easy by two bash function: grabfrom() needs to be defined on the local host, while grab() should be defined on the remote host. You can add any other ssh variables you use (e.g. -X or -Y) as you see fit.

function grabfrom() { ssh -R 2202:127.0.0.1:22 ${@}; };
function grab() { scp -P 2202 $@ [email protected]:~; };

Usage:

localhost% grabfrom remoteuser@remotehost
password: <remote password goes here>
remotehost% grab somefile1 somefile2 *.txt
password: <local password goes here>

Positives:

  • It works without special software on either host beyond OpenSSH
  • It works when local host is behind a NAT router
  • It can be implemented as a pair of two one-line bash function

Negatives:

  • It uses a fixed port number so:
    • won't work with multiple connections to remote host
    • might conflict with a process using that port on the remote host
  • It requires localhost accept ssh connections
  • It requires a special command on initiation the session
  • It doesn't implicitly handle authentication to the localhost
  • It doesn't allow one to specify the destination directory on localhost
  • If you grab from multiple localhosts to the same remote host, ssh won't like the keys changing

Future work: This is still pretty kludgy. Obviously, it would be possible to handle the authentication issue by setting up ssh keys appropriately and it's even easier to allow the specification of a remote directory by adding a parameter to grab()

More difficult is addressing the other negatives. It would be nice to pick a dynamic port but as far as I can tell there is no elegant way to pass that port to the shell on the remote host; As best as I can tell, OpenSSH doesn't allow you to set arbitrary environment variables on the remote host and bash can't take environment variables from a command line argument. Even if you could pick a dynamic port, there is no way to ensure it isn't used on the remote host without connecting first.