August 8, 2008

ssh-xfer: Quickly grabbing files over an existing SSH connection

Author: Ben Martin

The Secure Shell (SSH) and Secure Copy (SCP) make remotely performing system administration and copying files across secure links a painless operation. SSH and SCP use the same SSH protocol to protect network communications, but they rely on users knowing if they want a shell or to copy a file beforehand. You cannot easily use an existing SSH shell connection to a remote machine and just grab one or two files; if you want the files, you'll have to make another SSH connection for the file copy using SCP -- unless you have ssh-xfer.

The ssh-xfer project uses the local SSH agent to allow you to easily grab files using an existing SSH shell connection. You do not have to modify either the SSH client or server programs to use ssh-xfer -- but you will need to patch your ssh-agent. Although having to patch the ssh-agent is not ideal, you do gain one major advantage by doing this: you can send a file through more than one SSH connection. So if you first connect to the firewall and then you connected to a remote server from there, and from that remote server to a remote desktop machine, and from the shell on the remote desktop machine you decide to grab /etc/foo.conf, you don't have to think about how you to got there from your desktop, or how to SCP the file back via all the intermediate hosts. Simply run ssh-xfer /etc/foo.conf from the shell on the remote machine and the file will appear on your local machine's ~/Desktop -- or you can change the XFER_DEST_DIR definition in the ssh-xfer patch to specify a different default directory for transfers. Of course you'll need the ssh-xfer program to be available on the remote machine, but you don't need to change the SSH installation on any of the servers at all.

ssh-xfer is not packaged for Fedora, Ubuntu, or openSUSE. In this article I'll use a 64-bit Fedora 9 machine and build from source using ssh-xfer version 0.15 built against OpenSSH version 5.0p1-3.fc9 from the Fedora 9 updates repository.

The rpmbuild --recompile command below prepares and builds OpenSSH, including all the patches that Fedora adds to OpenSSH. Because we intend to patch the SSH agent, it is a good idea to recreate its source as the distribution uses it before applying the ssh-xfer patch. I found that a few parts of the patch did not apply cleanly to the current source, but these mainly related to slightly different return values (returning zero instead of nothing) and other things that are a fairly easy fix for a human but which deter the patch from working cleanly. I have uploaded an updated patch generated using OpenSSH version 5.0p1-3.fc9 from Fedora 9 updates to save others the time of performing these fixes.

$ rpmbuild --recompile /FromWeb/openssh-5.0p1-3.fc9.src.rpm
$ cd ~/rpmbuild/BUILD/openssh-5.0p1/
$ patch -p0 use my patch above or fix these issues by hand.

Once you have the sources patched, the below commands reconfigure the source tree and rebuild the ssh-agent and the new ssh-xfer program. Then you need to run the modified ssh-agent on your local desktop machine and have the ssh-xfer binary available on the remote machines that you might want to grab files from. If you are running the same distribution on remote machines as the one you built the ssh-agent and ssh-xfer, using SCP is probably the easiest way to get ssh-xfer onto the remote hosts.

$ ./config.status
$ make all ssh-xfer
$ su -l

# chown root:root ssh-xfer
# chmod 755 ssh-xfer
# scp -pv ssh-xfer myserver:/usr/local/bin
# install --mode 755 ssh-agent /usr/local/bin/ssh-agent-xfer

To use ssh-xfer you need to be running the modified SSH agent and have authentication agent connection forwarding enabled. There is a potential security issue with using agent forwarding, so it is not enabled by default. Basically, if there is a means to bypass file permissions on the machine you connect to with agent forwarding, then someone who can bypass the security on the remote machine can access your local SSH agent. This security issue makes sense if you consider that you are enabling a feature that forwards connections to the agent on the remote machine to the agent on your local machine.

With the commands shown below, I first create a new local bash shell using the patched ssh-agent that has ssh-xfer support, then I SSH into a remote machine, create a new file there, and then ssh-xfer it back to my desktop machine.

ben@desktop ~$ ssh-agent-xfer bash
ben@desktop ~$ ssh -A ben@myserver
ben@myserver ~$ date > myserver-testfile.txt
ben@myserver ~$ ssh-xfer myserver-testfile.txt
Sending file
. done.
ben@myserver ~$ exit
ben@myserver ~$ cd ~/Desktop
ben@desktop Desktop$ ls -lh
-rw------- 1 ben ben 29 2008-07-21 21:11 myserver-testfile.txt
ben@desktop Desktop$ cat myserver-testfile.txt
Mon Jul 21 21:19:14 EST 2008

The use of SSH agent forwarding might make some avoid using ssh-xfer. The ssh-xfer homepage even describes it has hackish and states that the protocol used to transfer file bytes is not very sophisticated. Because ssh-xfer is agent-based, you can directly download a file through SSH connections that have been chained together (connect to host b, then from b to c to d). This keeps you from needing to remember exactly which connections you used to get to the host you are currently looking at in order to download a file.

In bygone days when one connected to a Unix machine using a dial-up connection and a terminal program, you could issue commands and initiate a download directly from the console. The idea of extending the SSH agent to allow for file transfers brings some of the power that was available in the old days to modern SSH connections by allowing file transfer to be initiated directly from a remote terminal.

Categories:

  • Networking
  • Tools & Utilities