ssh

A 1-post collection

SSH on Windows 7 continued: charade, ssh, rsync, Unison

16 May 2011 Updated and polished.

In the previous article we established an SSH session with KiTTY. However to take full advantage of Cygwin and SSH it's equally important that your Windows client can connect with Cygwin's ssh.

As Pageant handles authentication for KiTTY, so ssh-agent authenticates for ssh.exe.
But we're on Windows! We like KiTTY, and Pageant has a nice interface, it should be all we need.

Charade is an ssh-agent in Cygwin that proxies requests to Pageant.

Client instructions (Windows-centric variation on keychain)

  1. Install Cygwin and hstart and configure environment variables on the client as done previously on the server.
  2. Compile Download charade.exe
  3. Drop it in C:\cygwin\bin
  4. Add another program start action to our Pageant entry in Task Scheduler.

    Program:

    hstart
    

    Arguments:

    /noconsole "bash -c "charade > ~/.ssh-agent""
    

    Move this entry up, before Pageant's start action.

  5. Append source ~/.ssh-agent to the end of C:\cygwin\home\<user>\.bash_profile
  6. Run task, launch local Cygwin shell, connect to your server: ssh <hostname>. Hooray!

With charade operational, we can use rsync and Unison over SSH. Awesome!
Remember when we exported our private key in OpenSSH format (no file extension)? That's the one ssh.exe requires.

Here's an example bash script for pushing changes over a LAN with rsync that handles spaces in filenames.

#!/bin/bash
receiver=$1

# escape spaces in file paths
# (the escapes won't be visible if you echo... you'd need to triple escape... which we don't want)
src=`cygpath $2`
src="echo $src | sed 's/ /\\ /g'"
src=`eval $src`

if [ $# = 2 ]
then
    dest=$src
    #src=$src/
else
    dest=`cygpath $3`
    dest="echo $dest | sed 's/ /\\ /g'"
    dest=`eval $dest`
fi

source ~/.ssh-agent

# rsync
# -a, archival mode, does:
# -r (recursive)
# -l (copy symlinks as symlinks)
# -p (preserve permissions)
# -t (preserve modification times)
# -g (preserve group)
# -o (preserve owner)
# -D (preserve device & special files)
# -v, verbose
# --delete, delete extraneous files from destination dirs (DANGEROUS)
# --rsh, the remote shell to use
# -z, compress file data during the transfer

# ssh
# -a, disables agent forwarding
# -x, disables x11 forwarding
# -c, set the cipher specification (blowfish being the quickest)

#LAN rsync:
rsync -s -av --delete --rsh="ssh -ax -c blowfish" "$src" $receiver:"$dest"
#WAN rsync:
#rsync -s -avz --delete --rsh="ssh -ax" "$src" $receiver:"$dest"

I call the script from within my text editor like this:

cmd /c bash ~/push.sh Chris-Laptop 'C:\abc\some_source_dir' 'C:\some_dest_dir'

(Or 'C:\abc\source_dir\' 'C:\abc\dest_dir\', or just a single 'C:\abc\source_dest\' if the path is equivalent at the destination.)

It's important to understand the distinction of a trailing slash on the source folder with rsync (especially with --delete). Back up your data before experimenting.

Discussion