Sunday, November 24, 2013

Undocumented scp

Recently I had need to set up some ssh keys and restrict their use to
only work with scp, not ssh in general.

After some fumbling around, I conducted some tests with no restrictions on the key
at the target remote host, with verbosity maximized with the local invocation of scp.
Scanning the output, there was mention of running 'scp -v -t ...' on the remote
system, which provided the key on how to do this.
With a bit of further testing, I found placing

command="/usr/bin/scp -v -t .../target/directory/"

in the options of the key involved in the ~/.ssh/aurthorized_keys
produced the desired effect.

Thinking I was probably not the only person to notice this, I googled
for "scp undocumented" and found references to '-d' and '-f' keys as well.

In the task of restricting ssh keys to only scp functionality there
seemed to be what I percieved as a lot of murkiness, with references
to a special 'scponly' shell etc., where an understanding of the
'-f' and '-t' keys would seem to be good for a lot of mileage.
Introducing other programs seems to introduce the possibility for
more bugs and confusion.
There is some mention of the '-f' and '-t' switches in O'Reilly's
SSH book, but not the man page.
("SSH, The Secure Shell: The Definitive Guide",
ISBN: 0-596-00011-1
Daniel J. Barrett and Richard E. Silverman
chapter 3.8.1, first edition 2001)

After some experiments, these are the guidelines I found for using
the '-t' and '-f' switches with cp in ~/.ssh/authorized_keys command="..." options.

1) Locally, everything after the ':', the user@host#port command line description of the remote
host, or ~/.ssh/config defined host parameters, is ignored.
This means you must specify the target directory or
file name in the remote hosts 'command=' option.
This may seem inflexible, but that is actually the goal of 'command=' options, to
reduce flexibility, and restrict the key to only desired effects.
Unless explicit, fully qualified directory paths are used,
directories are relative the home directory of the receiving user account.

2) '-t' ("To:")seems to closely parrallel the '-t' option in Gnu implimentations of 'cp' and
'mv' commands, but with scp you use it only in the remote 'command=' option.
It is used when the remote host is to recieve files.
If a file name is specified after '-t', it will be used literaly, so patterns
in this name are useless - they will only result in awkward file names that
use file matching metacharacters.
This also means that if a file name is specified, it will be overwritten each time
scp using the key is used, unless other actions have been taken
between invocations. Example:

command="/usr/bin/scp -v -t some/dir/".......

3) '-f' ("From:") is used when the remote host is sending files.
A pattern for a file name must be
appended to the directory specification. This pattern can be an explicit, particular file name.
To copy and entire directory, you would use '*', so:

command="/usr/bin/scp -v -f some/dir/*".....

4) If the desired effect is to recursively send a directory tree,
the '-r' switch must be used at both ends of the network connection, the simple invocation of
scp, and the 'command=' forced command.
When the remote host is recursively sending the tree, some pattern matching files
and directories must be part of the path specified in the 'command=' option.
This would most likely be '*' (dir/path/*).
When the remote host is receiving a recursively send directory tree, no file name
can be included 'command=' option, or on metacharacter garbage will result.
If you are sending directory trees recursively, it is likely you really want to
use rsync, but there may be obscure uses for this feature of scp.

5) I've yet to determine anything about the '-d' switch.

Dallas Legan,
2013 Nov. 24