It’s possible to control not only the way in which the client invokes ssh, but also the behavior of sshd on your server machine. In this section, we’ll show how to control the exact svnserve command executed by sshd, as well as how to have multiple users share a single system account.
To begin, locate the home directory of the account you’ll be using to launch svnserve. Make sure that the account has an SSH public/private keypair installed and that the user can log in via public-key authentication. Password authentication will not work, since all of the following SSH tricks revolve around using the SSH authorized_keys file.
If it doesn’t already exist, create the authorized_keys file (on Unix, typically ~/.ssh/authorized_keys). Each line in this file describes a public key that is allowed to connect. The lines are typically of the form:
ssh-dsa AAAABtce9euch... [email protected]
The first field describes the type of key, the second field is
the base64-encoded key itself, and the third field is a comment.
However, it’s a lesser known fact that the entire line can be preceded
by a command
field:
command="program" ssh-dsa AAAABtce9euch... [email protected]
When the command
field is
set, the SSH daemon will run the named program instead of the typical
tunnel-mode svnserve invocation
that the Subversion client asks for. This opens the door to a number
of server-side tricks. In the following examples, we abbreviate the
lines of the file as:
command="program" TYPE KEY COMMENT
Because we can specify the executed server-side command, it’s easy to name a specific svnserve binary to run and to pass it extra arguments:
command="/path/to/svnserve -t -r /virtual/root" TYPE KEY COMMENT
In this example, /path/to/svnserve might be a custom wrapper
script around svnserve that sets
the umask (see Supporting Multiple Repository Access Methods). It
also shows how to anchor svnserve
in a virtual root directory, just as one often does when running
svnserve as a daemon process. This
might be done either to restrict access to parts of the system, or
simply to relieve the user of having to type an absolute path in the
svn+ssh://
URL.
It’s also possible to have multiple users share a single
account. Instead of creating a separate system account for each user,
generate a public/private key pair for each person. Then place each
public key into the authorized_users file, one per line, and
use the --tunnel-user
option:
command="svnserve -t --tunnel-user=harry" TYPE1 KEY1 [email protected] command="svnserve -t --tunnel-user=sally" TYPE2 KEY2 [email protected]
This example allows both Harry and Sally to connect to the same
account via public key authentication. Each of them has a custom
command that will be executed; the --tunnel-user
option tells svnserve to assume that the named argument
is the authenticated user. Without --tunnel-user
, it
would appear as though all commits were coming from the one shared
system account.
A final word of caution: giving a user access to the server via
a public key in a shared account might still allow other forms of SSH
access, even if you’ve set the command
value in authorized_keys. For example, the user may
still get shell access through SSH or be able to perform X11 or
general port forwarding through your server. To give the user as
little permission as possible, you may want to specify a number of
restrictive options immediately after the command
:
command="svnserve -t --tunnel-user=harry",no-port-forwarding,no-agent-forw arding,no-X11-forwarding,no-pty TYPE1 KEY1 [email protected]
Note that this all must be on one line—truly on one line—since
SSH authorized_keys files do not
even allow the conventional backslash character () for line continuation. The only reason
we’ve shown it with a line break is to fit it on the physical page of
a book.