Node:Top, Next:, Up:(dir)


This manual documents fsh version 1.2.

Node:Introduction, Next:, Previous:Top, Up:Top

Introduction to fsh

Remote command execution via a cryptographically strong method such as lsh or ssh is often painfully slow, especially if either of the involved computers is slow. The biggest problem is that the client and the server perform a lot of complex calculations during connection establishment.

fsh uses lsh or ssh to establish a secure tunnel to the remote system. This takes as long as a normal connection establishment, but once the tunnel is established, fsh can reuse it to start new sessions on the remote system almost instantaneously. You get the security of ssh and the speed of rsh.

There are three programs at work. fshd establish a tunnel to the remote system. It can use lsh, ssh or even rsh to establish it. It will start in.fshd on the remote system. You can start fshd manually, or allow fsh to do it automatically on an as-needed basis.

in.fshd receives commands such as "create a new session running the command gcc foo.c, and call it session 3" or "send the following data to standard input of session 5" via the tunnel. You would normally not interact directly with in.fshd.

fsh is a drop-in replacement for rsh. It connects to the local fshd using a unix domain socket that is protected so that only the user that started fshd can connect to it. It uses fshd to forward a request to in.fshd, which will in turn start the requested program.

Node:Invoking fshd, Next:, Previous:Introduction, Up:Top

Invoking fshd

There is normally no need to invoke fshd manually, but it may be useful for debugging purposes. A typical invocation may look like one of these:

fshd -r lsh
fshd -l root

The in.fshd binary must be present in your path on the remote system once you log in.

If the connection is successful the message Connection established will be displayed (unless the option -b was given). This typically takes a few seconds. The tunnel is closed if you kill fshd, or if no session has used the tunnel for so long that a timeout is reached.

The basic invocation syntax is:

fshd [ options ] server

fshd understands the following options:

-r method
The method argument should be an rsh-compatible program. The default value is ssh.

The method argument will be unquoted using the quoted-printable encoding, so if it contains an equal sign (=) you have to write it as =3D.

-l login
Specify the user name that should be used on the remote system.
Tell fshd to detach from the controlling terminal and run in the background as soon as a connection to the remote system has been established. This option is used by fsh when it auto-starts an fshd. If this option is not given fshd will print some messages as connections are established.
-T timeout
If this instance of fshd has been unused for more than timeout seconds, fshd will terminate. The default timeout can be set at configure time, but is normally ten hours.

Use --timeout=0 to disable the timeout.

Node:Invoking fsh, Next:, Previous:Invoking fshd, Up:Top

Invoking fsh

You can use fsh to connect to a remote system via a tunnel. If no fshd with the approriate options is running one will be started by fsh. The exit value of fsh will be the exit value of the command that is executed remotely.

The remote command will be executed via whatever $SHELL is set to when the user logs in to the remote system. It might be instructive to run fsh sally env to see what the remote environment really looks like. If you do not like it, you should consult the documentation for the underlying transport (such as ssh)-fsh does not alter the environment.

Here are a few examples of how fsh can be used:

fsh echo hej
fsh -r lsh head -43 /etc/termcap
fsh -l root -r lsh head -43 /etc/termcap

The basic invocation syntax is:

fsh [ options ] server command args...
-r method
The method argument should be an rsh-compatible program. The default value is ssh.
-l login
The login argument specifies the user name that should be used on the remote system.
-T timeout
If there is no tunnel fsh will automatically start fshd, and pass this option to fshd. Once that fshd has been unused for more than timeout seconds, it will terminate. The default timeout can be set at configure time, but is normally ten hours.

Use --timeout=0 to disable the timeout.

This option is ignored if fshd is already running.

Node:Invoking fcp, Next:, Previous:Invoking fsh, Up:Top

Invoking fcp

You can use fcp to copy files to a remote system via a tunnel.

fcp [scp-options] f1 f2
fcp [scp-options] f1 f2... dir

fcp is a very simple wrapper that starts scp with the -S path-to-ssh argument, telling it to use fshwrap, which is another simple wrapper that gets rid of all flags that ssh accepts but fsh doesn't implement, and then calls fsh.

The net result is that you can use fcp as you use scp, for most uses, but sometimes all these wrappers might get in the way. See the scp documentation for information about the flags that scp accepts.

Node:Using with CVS, Next:, Previous:Invoking fcp, Up:Top

Sample application: CVS

The reason why fsh was written was to make it possible to use remote CVS fast and securely. This chapter outlines all necessary steps towards that end. It is assumed that you already have a working CVS repository on a server, and that CVS is installed on the client as well.

If you are using a modem or a slow internet connection to connect to the remote server, you probably want to use Compression in .ssh/config. See ssh(1).

Node:Bugs, Next:, Previous:Using with CVS, Up:Top

Reporting bugs

Bugs should preferably be reported using the Bugzilla installation at <>. You can also query Bugzilla for known bugs.

Bugs can also be reported to, if for some reason you cannot use Bugzilla. If you don't want the bug report to be public you can try instead. Expect a response time of at least one to two weeks. I have been known to reply to mail after a couple of years in the past.

Before you report a bug, please check if there is a new release available first. The home page of fsh is <>. You can find info about the fsh mailing lists there as well.

Node:Remote protocol, Next:, Previous:Bugs, Up:Top

The remote protocol

This chapter documents the protocol between fshd and in.fshd. This protocol is normally only of interest to the developer of fsh, and may be a little out of date.

In the description below, fshd is the client and in.fshd is the server. You can try out the protocol manually if you like by starting in.fshd interactively. In the example, the text that is output by in.fshd appears after the print symbol -|.

bash$ in.fshd
 -| fsh 1
new 2 8Hcat -vet
stdin 2 4Hfoo

 -| stdout 2 5Hfoo$
eof-stdin 2
 -| eof-stdout 2
 -| eof-stderr 2
 -| exit 2 1H0
 -| eos 2

Basic syntax

The protocol assumes an 8-bit-clean connection. All commands (except the initial greeting) have the same overall structure. This protocol uses ASCII, but it is capable of transmitting any byte-stream. This is the overall structure:

Some commands require the data chunk, while others don't allow it. There is no command that only uses a data chunk sometimes.

Connection establishment

The server starts by sending a greeting to the client. This is the only thing that doesn't adhere to the basic syntax. It contains the word fsh followed by the version number of the protocol, which is 1. The client does not respond.

fsh 1

Session management

Each remote command that should be executed is contained in a session. There can be several simultaneous sessions. The client associates each session with a unique session id, which is an integer.

A new session is created by sending a new command to the server.

new session-id command

The command is a string, suitable to pass to whatever $SHELL is set to on the remote system.

Once a session is established data can be sent by either the client or the server. The client uses stdin to send data. The server uses stdout or stderr. The format of these three commands is the same:

stdin session-id strlenHdata
stdout session-id strlenHdata
stderr session-id strlenHdata

strlen is a decimal string, that specifies how long data is. The data can contain any byte, including NUL, newline and carriage return.

The client can send signals to the session:

signal session-id signal-name

The following values are defined for signal-name:

End-of-file can be specified for each of the three data channels separately:

eof-stdin session-id
eof-stdout session-id
eof-stderr session-id

When the child dies the server will send the exit status to the client.

exit session-id exit-status
signal-exit session-id signal-name

Session termination

The server always sends an end-of-session to the client when it discards a session.

eos session-id

The eos will be generated spontaneously by the server when it has sent eof-stdout, eof-stderr and one of exit or signal-exit. The client should never reuse a session id until it has seen an eos from the server.

The client can also request that the session is terminated by sending an eos to the server. This should only be used in abnormal situations, such as if the fsh program responsible for this session unexpectedly died (indicating that there is nobody awaiting the result of the program). When the server receives an eos it will kill the program (with something similar to kill -KILL pid) if it is alive, close all ptys to the program (without trying to drain them), and send back an eos response to the client as confirmation.

Flow control

To avoid pileup of unprocessed data in the endpoints (stdin data in in.fshd and stdout/stderr data in fsh) a strict flow control protocol must be adhered to.

When a session is created it is initially allowed to send 128 KB (that is, 131072 bytes) to the stdin of the remote system. When it receives an stdin-flow statement the limit is increased to the value sent in it. The fsh process is responsible for counting the bytes and pause if it doesn't receive an stdin-flow statement in time. The in.fshd process is responsible for sending stdin-flow statements. They should ideally be sent in advance, so that in.fshd always maintains a buffer of pending input to the process.

Similarly, in.fshd may only send 128 KB of stdout data and 128 KB of stderr data, until it receives stdout-flow and stderr-flow commands from fsh.

stdin-flow session-no new-limit
stdout-flow session-no new-limit
stderr-flow session-no new-limit

Please note that fshd is not directly involved in the flow control protocol. It only relays messages between all the fsh processes an the in.fshd process.

These limits exists so that both in.fshd and all fsh processes always should be able to read anything that fshd wants to send to them. The initially allowed window of 128 KB is included so that a new session can start sending data at once, without a need for any round-trip delay.

Node:Local protocol, Previous:Remote protocol, Up:Top

The local protocol

The protocol used between fsh and fshd is identicaly to the remote protocol, with one exception: there is no session number.

fshd creates an AF_UNIX socket in /tmp/fshd-UID/server.method.login (with funny characters encoded with a QP-like encoding). The protection of /tmp/fshd-UID is set so that it is only accessible by the user with the proper uid.

Table of Contents