Super User is a question and answer site for computer enthusiasts and power users. Join them; it only takes a minute:

Sign up
Here's how it works:
  1. Anybody can ask a question
  2. Anybody can answer
  3. The best answers are voted up and rise to the top

In OpenSSH one can declare a subsystem in the configuration file (/etc/ssh/sshd_config) or force a command such as svnserve to be executed by including this in the authorized_keys line for a particular key like this:

command="svnserve -t --tunnel-user=alice" ssh-dss AAAA...
command="svnserve -t --tunnel-user=bob" ssh-dss AAAA...

thus allowing the same system user to be reused for different "identities" within the Subversion (svnserve) context.

How would I go about to write a service like svnserve myself, allowing to specify the use of the tunnel and how exactly is the data transmitted in these cases? In particular how does the svnserve instance "know" by which means to output the data or read input? Does this all happen via stdout and stdin in such a case and if so, will there be a way to distinguish stderr as well?

I imagine the subsystem and the command= are using the same mechanism, but please correct me if I'm wrong.

(I left no-port-forwarding,no-agent-forwarding,no-X11-forwarding,no-pty out for brevity, but I am aware of them and their use for the scenario.)

share|improve this question
up vote 4 down vote accepted

First, note that command= does not invoke a SSH subsystem. It merely runs the command as if it were given on the SSH client's command line; e.g.

ssh yourhost "svnserve -t --tunnel-user=alice"

ssh yourhost "git upload-pack /pub/git/myproject.git"

ssh yourhost "ls -la"

The above examples should make it clearer that communication with svnserve or git or ls happens over the same stdio (stdin/stdout/stderr) as any other SSH interaction. For SVN and Git, the ssh client merely serves as a tool to invoke commands remotely.

"Real" subsystems, as configured using the Subsystem option in sshd_config, aren't that much different. The only major difference is that they can be invoked by a static, well-known name, instead of relying on the remote login shell (bash, zsh, &c) to find the correct executable. For example, the SFTP server can be /usr/lib/ssh/sftp-server in one machine, MULTINET_COMMON_ROOT:[MULTINET]SFTP-SERVER2.EXE in another, built into sshd in third (Subsystem sftp internal-sftp), but in all cases clients can still find it using the name sftp.

At least in OpenSSH, subsystems can be written just like normal programs that communicate with the client via stdin/stdout/stderr. It seems that passing arbitrary command-line arguments is not allowed, however, so you cannot just configure a single svnserve subsystem for all users.

share|improve this answer
Nice answer. Thanks. I'm aware the subsystems are different, but they're akin to the command= method, so I reckoned the communication method is the same. – 0xC0000022L May 16 '12 at 21:08

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .