The way .ssh/authorized_keys is typically used is not secure. Because
using it securely is hard, and dumping in passwordless ssh keys is easy. I
spent about 5 hours today locking down my authorized_keys.
rsync
The only easy case is a rsync of a single directory. Follow these good instructions.
If you need to rsync multiple separate directories, it's easy to find
several
documents involving a
validate-rsync.sh. Do not use, it is insecure -- it allows rsync to be
run with any parameters. Including parameters that allow the remote system
to rsync in a new ~/.ssh/authorized_keys. Oops. (You can probably also
trick validate-rsync.sh into running other arbitrary commands.) To be
secure, you have to check the rsync parameters against some form of
whitelist.
git
Locking down git should be easy. Use git-shell.
Unless you also want to be able to log in to an interactive shell on the
same account. To do that, you'll need to generate a separate ssh key for
git. Both git servers I use are named git.*, so I set it up like this in
~/.ssh/config on the client:
Host git.*
IdentityFile ~/.ssh/id_rsa.git
Then on the server, I added the key to authorized_keys, prefixed with this:
command="perl -e 'exec qw(git-shell -c), $ENV{SSH_ORIGINAL_COMMAND}'"
(I also tried the simpler command="git-shell -c $SSH_ORIGINAL_COMMAND"; but
it didn't work with alioth's old version of openssh, and I didn't want
to worry about exposing SSH_ORIGINAL_COMMAND to the shell.)
Before arriving at that, I took a detour to using gitosis. It can make it impressively easy to manage locked down git over ssh, but you have to fit how it does things. Including repository layout, and a dedicated account. So I spent several hours changing my git repo layout. In the end, I decided gitosis was too complicated and limiting for what I needed, but I do recommend checking it out.
svn
Like git, this is fairly easy, since svn provides svnserve. The svnbook
documents how to use it in .authroized_keys. Basically, just use
command="svnserve -t"
A similar approach as used for git can be used here if you want to have a dedicated ssh key that causes svnserve to be run.
d-i daily builds
d-i has a d-i-unpack-helper that can be put in authorized_keys.
unison
Can probably be locked down similarly to rsync, but I haven't tried yet.
duplicity
The only way seems to not use duplicity over ssh at all, and instead use a different transport.
too hard
What if you want to allow locked down git, and a rsync, and maybe unison too, all to the same account? You'll end up with some nasty mismash of all of the above, and there are plenty more things using ssh as a transport that need other techniques to lock them down.
Until this becomes easier, a majority will just dump passwordless ssh keys
in ~/.ssh/authorized_keys, creating exploitable trust paths that don't
need to exist.
I found that
command="git shell -c \"$SSH_ORIGINAL_COMMAND\""works.command="git shell -c $SSH_ORIGINAL_COMMAND"doesn't work because$SSH_ORIGINAL_COMMANDwill contain spaces and git-shell will see too many arguments and throw the error: "fatal: What do you think I am? A shell?".