get back!    get down!   

     So you want to forward ports?


SSH is too radical. Sending passwords in clear text over the internet is becoming a thing of the past. Many emacs users love to use ange-ftp to browse and edit files on a remote host just as if those files were right on their desktop, but getting a machine cracked is no fun, so ...

Why not send the password over encrypted instead? We can use ssh to create an encrypted TCP/IP tunnel between the desktop machine and the remote host. ftp uses two TCP/IP connections, and we're interested in encrypting the control channel on port 21.

(I hear it's hard to encrypt the other ftp channel, but I don't care, since the sniffers I've seen concentrate on passwords.)

An encrypted tunnel or channel works like this when you set up forwarding:

The ssh client (yes, client) on your machine that is set up to forward accepts TCP packets on a given port. It's usually a high port -- say 1234 -- so that you don't have to be root to mess with it.

That ssh client sends the packets to the port you've already specified on the remote server by first sending the packet to the remote host's ssh daemon.

(Pause for the reader to reflect.) That means that to the user, the ftp or whatever is on localhost's port 1234. Weirder, the ftp server on the remote host sees an incoming ftp request from its localhost, i.e. the same machine that the remote ftp daemon is running on.

How to set it up from the command line

	kooky$ cat > /dev/null

	We are on the machine "kooky" and we are going to forward
	kooky's port 1234 to the ftp port on "staid.pro.com", the
	remote host.

	kooky$ ssh -f -C -L 1234:staid.pro.com:21 staid.pro.com \
		 "perl -e 'while(getppid > 1){sleep 30}'"
	kooky$ echo "I've got RSA all set up instead of using passwords!"
	I've got RSA all set up instead of using passwords!
	kooky$ # now use a passive ftp client
	kooky$ pftp 127.0.0.1 1250
        Connected to 127.0.0.1.
        220 staid.pro.com FTP server (Version wu-2.4.2-academ[BETA-12](1) Thu Apr 10 11:25:49 EDT 1997) ready.
        Name (127.0.0.1:imauser): anonymous
        331 Guest login ok, send your complete e-mail address as password.
        Password:
        230-     ------------------------------------------------------------
        230-          You are connected to the FTP site for the
        230-		Staid Professionals of New Amsterdam
        230-     ------------------------------------------------------------
        230 Guest login ok, access restrictions apply.
        Remote system type is UNIX.
        Using binary mode to transfer files.
        ftp> rock and roll!!!

That ssh command sets up a (-f) forked-into-the-background process that sends kooky's port 1250 to staid's 21, the ftp port. The perl command is a kludge and gives the most stability that I've seen. It requires that staid have perl, but all it needs to do is wait so that the connection stays open. You can read the ssh man pages to find out how to use RSA keys instead of passwords. (It rox.)

If anyone knows how to get around this kludge, please let me know.

NOTE:
The current versions of wu-ftpd have implemented a new security feature that makes the ftp server refuse passive data connections to hosts other than the one that is doing the control session.

It makes sense because it's possible that one host could steal another host's ftp data session. However, it takes special attention on our part to get our funky kind of ftp going.

Read the manpage for ftpaccess(5) to learn about the new configuration directives. Here's a summary of the general strategy on the hypothetical ftp server, "boast", which has the IP, 123.123.123.4:

class   local   real,guest,anonymous 127.0.0.1
class   local   real,guest,anonymous boast.roast.toast.com
class   local   real,guest,anonymous boast
class   local   real,guest,anonymous localhost
class   remote  real,guest,anonymous *

# allow local users to port forward to roast subdomain machines
pasv-allow local 123.123.123.*
port-allow local 123.123.123.*


How to set it up in the One True Editor

You can use sshfwd.el (which is alpha software) or write your own elisp to start asyncronous ssh tunnel processes from within emacs. Then you can put something handy in your .emacs file so that you can easily set up any channels you need.

By now you are frustrated, because you have tried to use dired and ange-ftp over these forwarding channels. That is because I haven't told you the special secret yet. Here is the special secret:

Use this syntax to access your home directory on staid:

	/127.0.0.1 1250:.
... or:
	/username@127.0.0.1 1250:.

Now you may be tearing out your hair, your eyes sore from the flashing of the visual bell, and screaming about that space character. Scream no longer -- use "C-q" to quote the space character!

Now you are a forwarding guru! Flaunt it!!! Impress your mom!!

Note on TCP_wrappers

TCP_wrappers are too radical too. But if you are lucky enough to use them in a mostly-closed configuration, you'll need to make some accomodations for the port forwarding in your /etc/hosts.allow  file like this:
        # kooky /etc/hosts.allow
        sshdfwd-1250: 127.0.0.1 123.456.78.9
... where 123.456.78.9 is the IP of staid.pro.com, the remote host with the ftp server you're interested in.

If staid.pro.com has TCP_wrappers, it will need an entry in its hosts.allow to let ftp connections in from localhost or the loopback or whatever. Just look in the logs if it refuses you: it will clearly say "ftpd refused connection from foo.bar", where foo.bar is exactly what you need to put in the hosts.allow file.

help out

Please contact me if you have any corrections or additions on the material presented here.

alternatives

stunnel is a tool specifically designed for encrypted forwarding of TCP sessions. It uses ssl. You could likely do the same thing I describe here using stunnel.

This page describes ssh version one. I hear that version two has better forwarding support.

TOP O THE PAGE to ya!