Using Secure Shell to Create a Team File Drop

Steven J Zeil

Last modified: Jul 26, 2016
Contents:

A file drop is an area where members of a team can easily deposit files elated to their work.

Of course, there are numerous file sharing services available, such a Google Drive or DropBox, but these limit the uses that can be made of the shared files. For example, you can store HTML pages in a file sharing service, but you cannot serve those as a website from such a service.

In fact, the case that I want to talk about in this document is specifically creating a shared website to which only the team members can contribute but that can be served for public viewing to all.

1 Special-Purpose SSH Keys

We will be exploiting the power of SSH keys, so make sure you know how to create an authorize them.

1.1 Creating Special-Purpose Key Pairs

Suppose that you wanted to allow someone else to try out a program that you had written and that is sitting somewhere in your account area. Let’s also suppose that you don’t want to make this program available to the entire world. For example, perhaps you are working on a programming assignment in one of my courses and you want me to take a look at your running program.

But we can actually adapt that second approach by limiting the key pair to running only a specific command or program when anyone uses it to log in.

  1. Edit the public key that you created in the earlier steps.

    The key is typically written as a single long line ending in yourLoginName@_machineName_, reflecting where you created the key. To the front of that line, add command="/usr/bin/env",no-port-forwarding and a blank space, right in front of the “ssh-rsa”.

    (If you aren’t familiar with te env command in Linux, run it to see what it does.)

  2. Add that edited public key to your authorized keys list on the server as you did earlier.

  3. You should still have a key agent running on your client. If not, restart it and add your private key.

    Now try logging in via that key by giving the following commands on the client:

    ssh yourCSLogin@atria.cs.odu.edu
    ssh yourCSLogin@atria.cs.odu.edu pwd
    

    Notice that, whether you give a specific command for ssh to execute on the remote server or omit it, trying for a normal login session, what actually happens is that you are logged in to your account, the env command is run, and then you are logged out.

So, to return to our earlier example, if you were working on a programming assignment in one of my courses and you want me to take a look at your running program, you could create a special-purpose key pair to run that program (and do nothing else), and then give me the private key and passphrase, knowing that I would be limited to using your account for that single purpose.

1.2 Playing with Fire: Password-Free Key Pairs

Now we are going to do something a bit dangerous.

  1. Shut down the key agent on your client machine with the command

    ssh-agent -k

  2. Create a new key pair, giving them a different name from the ones you set up earlier.

    This time, however, when prompted for a pass phrase, just hit Enter to create a key pair without a pass phrase.

  3. Now, adding that key to your authorized key list would be risky, because anyone who got a copy of the private key would be able to log into your account using no passphrase at all.

    So, to keep this safe, immediately edit that public key. This time add

    command="pwd",no-port-forwarding
    

    to the beginning of the public key.

  4. Add that edited public key to your authorized key list on the server.

  5. On the client, give the command

    ssh -l yourCSLoginName -i path/To/Your/New/Private/Key atria.cs.odu.edu

    You should see that the command is executed without your being prompted for a password or pass phrase.

When you have succeeded in completing these steps, you can remove the keys you have added to your ~/.ssh/authorized_keys file on the server.

2 Background – Serving Web Pages

Anyone with a CS account can publish web pages on the CS web server. the mechanism for doing this is very straightforward:

Any file stored on the Linux file system at

~_loginName_/public_html/_whatever_

will appear on the web server at the URL

http://www.cs.odu.edu/~_loginName_/_whatever_

To see this in action (if you have not previously taken advantage of this service), create the directory ~/public_html if you do not already have one.

Inside there, create a file named firstPage.html containing

<html>
  <head>
      <title>First page</title>
  </head>
  <body>
    <p>
	   This is page 1.  There is
	   no page 2.
	</p>
  </body>
</html>

Then direct a web browser to http://www.cs.odu.edu/~_yourLoginName_/firstPage.html and you should see your page.

If not, look at your permissions. The web server does not run under your account. But it needs to be able to access your public_html directory. That means that you need to carefully open up the correct path to your web content without leaving your entire account wide open.

3 Copying (synchronizing) files

Web sites generally consist of multiple files, including HTML, graphics and style sheets. These are often arranged into a hierarchy of directories.

If you and a group of team mates want to copy files from each of your own work areas into a shared directory within your public_html directory, how are you going to do it.

3.1 rsync

A better tool for this sort of copying is the program rsynch, a powerful utility for copying and synchronizing complicated directory structures.

rsynch can be used for local copies on a machine or to copy things across the network. It’s smart enough to recognize when a destination machine already has an up-to-date copy of a file, and will skip over any files that don’t really need to be transferred. In fact, when looking at large files in which only a few bytes may been changed, rsync is capable of saving transfer time by splitting the file into changed and unchanged pieces, transferring only the parts that have changed, and then reassembling the whole file afterwards.

A basic rsync command looks like

rsync options source_file_directory destination_file_directory

For example, the options -auvz (or -a -u -v -z) cause rsync to try to maintain a “mirror” of the source directory, transferring only newer files and preserving modification dates. If we give the source and destination directories as ordinary file paths, e.g.

rsync -auvz ~/myWorkArea/ ~/public_html/website/

then all files (including directories and files within those directories, recursively) in ~/myWorkArea/ that are newer than their counterparts in ~/public_html/website/ would be copied into the website. (BTW, those slashes on the ends of the paths are important.)

Now, we could do more or less the same with an ordinary copy command:

cp -ar ~/myWorkArea/* ~/public_html/website/

But we can make things more interesting by adding a -e ssh instruction, telling rsynch to use ssh for across-the-network transfers, and then adding loginName@_machineName_: to the source or destination directory (or to both) to indicate rewources that exist on another machine or in someone else’s account. For example, from my home Linux box, I might update a web site on the CS Dept server like this:

rsync -auvz -e "ssh" ~/myWorkArea/ zeil@atria.cs.odu.edu/home/zeil/public_html/website/

Normally, if I do this, I will be prompted for a password to log into atria. If I have set up ssh keys for access to atria and if I am running a key agent, though, I will be able to do the transfer without entering a password.

If I want to use a specific ssh key set, I can modify the ssh command that rsync will use:

rsync -auvz -e "ssh -i $HOME/.ssh/myPrivateKey" ~/myWorkArea/ zeil@atria.cs.odu.edu:/home/zeil/public_html/website/

Could I set this up to use a passphrase-free key? Well, I would only want to do that if I could limit the key to accepting rsync connections and only to portions of my website.

3.2 rrsync

And, in fact, rsync provides a special script/command just for that purpose.

  1. Copy the file /usr/share/doc/rsync/scripts/rrsync.gz into a convenient directory to which only you have access. (I have a directory ~/bin for these sorts of personal commands and scripts.)

    cd to that directory and unpack the file, then make it executable.

    gunzip rrsync.gz
    chmod +x rrsync
    
  2. You can look at the file with any editor. the opening comments explain a bit about how to use it. But, in essence, you can list this command in an ssh key, together with a directory name, and anyone logging in with that key will be limited to making rsync transfers to that directory or to subdirectories within it.

    For example, if I placed my copy of rrsync in /home/zeil/bin. then I might add, to my ssh key

    command="/home/zeil/bin/rrsync /home/zeil/public_html/webSite/",no-port-forwarding,no-agent-forwarding
    
  3. You can then give an rsync command to copy files from your local client to your remote website directory. The one difference from normal rsync commands is that you give the remote directory as a relative path within the starting directory you placed in the rrsync entry:

    rsync -auvz -e "ssh -i $HOME/.ssh/myPrivateKey" ~/myWorkArea/ zeil@atria.cs.odu.edu:./
    

    i.e., starting from /home/zeil/public_html/webSite/ in the rrsync entry, go to ./ (/home/zeil/public_html/webSite/./ being the same as /home/zeil/public_html/webSite/).

#

4 Setting Up a Tream Website

  1. Set up a website directory for the team. For the same of this example, I’m going to set up a site that would be accessed as http://www.cs.odu.edu/~zeil/projectReports/.

    The web pages at URLs http://www.cs.odu.edu/~zeil/… are located in directory /home/zeil/public_html/…. Of course, you would need to replace my login name zeil by your own to set up your own website.

    So, in the directory /home/zeil/public_html, I would create a directory projectReports/. I would set the permissions to 711, so that I have full access (7) and the webserver can navigate to specified directories (1).

    • Even though I’m setting this up for my team, they don’t need write access to the directory because we’re going to set things up so that when depositing files, they are logged in as me.
  2. In that directory, add a web page titled “index.html” that displays simply the phrase “Project Reports”.

    (An index.html file displays by default if someone browses to the directory without naming a specific file. By providing an index.html file, you not only set up a convenient starting point for a website, you also prevent people from using their web browser to simply list all of the files in your directory.)

  3. Set up a passphrase-free pair of ssh keys. Add the command=rrsync… limitation to the front of the public key:

command="/home/zeil/bin/rrsync /home/zeil/public_html/projectReports/",no-port-forwarding,no-agent-forwarding…rest of public key…

Add that restricted public key to your `authorized_keys` file.
  1. You can now distribute the private half of that key to your teammates, knowing that the only use they can make of it is to add and update files in the website.