This manual documents fsh version 1.2.
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.
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 sally.lysator.liu.se fshd -r lsh biffen.cendio.se fshd -l root biffen.cendio.se
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
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
-b
--background
fsh
when it auto-starts an
fshd
. If this option is not given fshd
will print some
messages as connections are established.
-T timeout
--timeout=timeout
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.
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 sally.lysator.liu.se echo hej fsh -r lsh biffen.cendio.se head -43 /etc/termcap fsh -l root -r lsh biffen.cendio.se head -43 /etc/termcap
The basic invocation syntax is:
fsh [ options ] server command args...
-r method
method
argument should be an rsh
-compatible program.
The default value is ssh
.
-l login
login
argument specifies the user name that should be used on
the remote system.
-T timeout
--timeout=timeout
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.
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.
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.
fsh
on the server and client. Make sure it exists in
your default path.
bash$ ssh server.domain echo it is working it is working bash$
You may have to enter a password or passphrase. That is OK.
in.fshd
is found when you log in to the server.
bash$ ssh server.domain in.fshd fsh 1
You may have to enter a password or passphrase. That is OK.
Once you receive the line fsh 1
you can press end-of-file to end
the session.
bash$ fshd server.domain Connection established
This step is not really necessary, but since your are reading this you
probably have a problem with your connection. Running fshd
manually may help troubleshooting any problem you have.
You may have to enter a password or passphrase. That is OK.
CVS_RSH
to the value
fsh:
bash$ export CVS_RSH=fsh
bash$ cvs -d server.domain:/path/to/cvs/repository co module-name
bash$ cd module-name bash$ cvs log foo.c bash$ cvs status bar.c
If you switch back to the screen running fshd
, you will notice
that a few lines of texts was written each time a remote command was
executed.
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).
Bugs should preferably be reported using the Bugzilla installation at
<http://bugzilla.lysator.liu.se/
>. You can also query Bugzilla
for known bugs.
Bugs can also be reported to fsh-bugs@lists.lysator.liu.se, if for some reason you cannot use Bugzilla. If you don't want the bug report to be public you can try ceder@lysator.liu.se 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
<http://www.lysator.liu.se/fsh/
>. You can find info about the fsh
mailing lists there as well.
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
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:
H
, and the data. The data may contain
any character, including NULs and newlines.
Some commands require the data chunk, while others don't allow it. There is no command that only uses a data chunk sometimes.
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
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
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.
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.
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.