Friends,

Well, I've gotten everything up and working, so I thought that I would
write up what I did in the hopes that this saves somebody some time
and/or aggravation.  Naturally, the possibility that this just may be
my first step towards fame and fortune is also quite an incentive!
Ah!  The road to FAQ-dom!

        Thanks to Josh Rivel for some EXACT examples.

The specific application is this: I have about 1,100 machines behind a
firewall that I need to have tunnel out on to the rest of the world to
transfer some BIG SECRETS from time to time.  Corporate life being
what it is, I have to mess around with these machines as little as
possible.  Whatever *that* means is--of course--completely arbitrary
and bears no resemblance to life as we know it.  But, I digress..

I am not going to explain here how to set up ssh/sshd themselves as
that is fairly well documented, elsewhere.  This is about how to set
up inetd to automatically forward ports.

Note that there are more efficient ways to do this as having inetd
fire up sshd is slower than having sshd always running.  In fact, it's
a WHOLE LOT SLOWER when making connections.  I only did it this way
because I had to actually demonstrate that it was slower than that
more typical *faster* alternative.

I use as an example a very simple client/server application that I
wrote called 'halfchat'.  As its name implies, it is half of a chat
application.  What you type in one end (client mode) winds up being
typed out at the other end (server mode).  Server mode never reads
stdin and is output only.

There's nothing exciting about this except that I packetize the data
with checksums and sequence numbers and acknowledge each packet.  This
allows me to check for errors and thus prove to certain sceptics that
ssh doesn't go dumping or loosing data.  ... SIGH ...

This is slower than simply pumping data through a pipe, but it is
typical of the kind of transaction processing that we do around here.
Running flat out, the application gets over 70K bytes a second between
a couple of small Alphas.  That number could probably go up if I tweak
things (which I probably won't get around to doing).

To begin, I assume that ssh/sshd has been installed and that a user id
exists with a key pair that has been generated with ssh-keygen that
does NOT have pass phrases.  My sshd_config (the server) file contains
the following relevant lines:

        ForwardAgent                    yes
        PermitRootLogin                 yes
        PubkeyAuthentication            yes
        ForcePTTYAllocation             no
        PrintMotd                       No

I believe that the relevent lines from my ssh_config (client) file
are:
        PubkeyAuthentication            yes
        PrintMotd                       No

Between two systems, Client_Node and Server_Node, the above public key
files have also been copied around and the private ones are protected
appropriately as are the authorization and identification files.  Two
services are defined in /etc/services

halfchat   7900/tcp             # Halfchat Service
shalfchat  7901/tcp             # Secure Halfchat

The service number 7900 is arbitrary: I picked it because I had
originally been playing with this stuff via using the finger daemon
which uses port 79.  I just shifted the number left to decimal digits
and .. TA DA!

Assuming again that ssh/sshd has been installed and that the port is
named in /etc/services (sshd 22/tcp) and that the relevant binaries
are in /bin, the actual three lines in the inetd.conf file on
Client_Node are:

sshd stream tcp nowait root /bin/sshd sshd -i -q
halfchat  stream tcp nowait loot /bin/halfchat halfchat SERVER 0
shalfchat stream tcp nowait loot /bin/ssh ssh -q -x -l loot Server_Node /bin/socket -q 
localhost halfchat

On Server_Node, it looks almost the same:

sshd stream tcp nowait root /bin/sshd sshd -i -q
halfchat  stream tcp nowait loot /bin/halfchat halfchat SERVER 0
shalfchat stream tcp nowait loot /bin/ssh ssh -q -x -l loot Client_Node /bin/socket -q 
localhost halfchat

Note: loot is a toothless account that has the previously mentioned
passphrase-less public/private key pair generated and distributed.

Thus, if somebody is on Client_Node and wants to have half of a clear
chat to Server_Node, they would utter:

Client_Node$ halfchat Server_Node halfchat

Which instructs the halfchat application to get a socket and to do a
connect() call to Server_Node on port 'halfchat' (7900).  If the same
user wants to use a mutually authenticated, encrypted link for the
transport (notice that I haven't said SECURE here), then the command
line on Client_Node would be:

Client_Node$ halfchat localhost shalfchat

This causes inetd to fire up ssh with the above parameters.  It makes
a connection to Server_Node and signs on as 'loot' and then runs the
socket program which makes a connection to halfchat on the local (that
is, Server_Node) machine.

Socket takes what it finds on stdin and writes it to the requested
port and anything that comes back gets dumped to stdout.  The '-q' is
used to make it exit when it hits eof, otherwise the ssh connection
will never go away, even if the Client_Node halfchat application
shrivels up and dies.

All in all, it pops right up and I'm currently getting about half the
data rate that I quoted above.  In addition, this causes pointy haired
managers to clap their hands with joy thinking about how SECURE
everything is.

Well, maybe...  A problem with having inetd set up this way is that
the Client_Node will now accept INCOMING connections from *any* other
machine on the shalfchat port and it forward these over to the
Server_Node.  This could well be a SERIOUS security issue.  In this
case, we would probably want to restrict shalfchat to only recieve
connections from localhost.  This could be done via the use of tcpd,
for example.

Again, it is FAR faster to have sshd running and to make a connection
using ssh with the -L switch.  Leaving aside how sshd would be
configured and simply assuming that it IS running, if we remove
shalfchat line from inetd.conf and have the user type something like
this first:

Client_Node$ ssh -q -f -L shalfchat:Server_Node:halfchat Server_Node

Then they are going to connect REALLY fast when they utter the
previously mentioned 'halfchat localhost shalfchat' above.

Anyway, that's what I've come up with.  Now, does anybody know how to
do this (the inetd thing) WITHOUT using the socket program?  What I
want is something like -I REMOTE:HOST:PORT, which means use the open
socket that inetd gave you and ask the sshd on REMOTE to open a
connection to HOST on PORT and forward the data.

I didn't see any way to do this.  So, I tried simply having the remote
sshd fire up halfchat in SERVER mode.  This croaked because I was
doing some socket things.  So, I mean OTHER than not using recv and
send, is there anything I can do?  Otherwise, I'm content to live with
socket.

                That's all for now,

                                        --T

Ps: You all DID remember to HUP inetd, right?  ;-)

Reply via email to