Opened 10 years ago

Closed 10 years ago

Last modified 5 years ago

#4806 closed Feature request (rejected)

Add FTP over SSH (tunneling using a proxy server)

Reported by: db8200 Owned by:
Priority: normal Component: FileZilla Client
Keywords: FTP over SSH tunneling proxy Cc: dboirayon@…
Component version: Operating system type: Linux
Operating system version: Mandriva 2009.1

Description

It's a common problem to have a restricted Internet connection. Sometimes it's not possible to access FTP servers, or other times the FTP server can be located on a private network.
In these cases, when an SSH connection is possible, it can be useful to have some type of SSH proxy act as a gateway to the FTP server.

SSH tunneling allows to encapsulate the FTP control connection:
ssh -L 2121:ftp.someplace.net:21 myuser@… -N
ftp localhost 2121

But there is still a problem with the data connection.
In active mode, it requires a connection from server to client, which is impossible in most cases.
In passive mode, Filezilla accesses the server using the IP specified in response to the PASV command, if it is routable, or the IP address used for the control connection, if the other one is not routable. The port number is specified by the server. With both IP addresses, it will be impossible to connect (myproxyserver.fr is not directly accessible, and localhost does not have an SSH tunnel on the specified port).

So, to solve the problem in passive mode, just after the answer to the PASV command, and before the RETR or directory listing command, the FTP client should create an SSH tunnel from localhost to ftp.someplace.net with the same port number on both sides (as specified by the server after PASV).

I tried to do that with Filezilla (trunk) on Linux. Since I don't know how to use Putty code for SSH port forwarding, I did it the dirty way, using the ssh command as in the shell.
SSH authentication is handled by ssh using a public key in my case, so Filezilla does not care about it.

I don't send this code as a patch submission, because I know that it cannot be integrated in this way in FileZilla.

In CFtpControlSocket::ParsePasvResponse(CRawTransferOpData* pData) (src/engine/ftpcontrolsocket.cpp:3809):

// Create an SSH tunnel on the port specified by the server for the passive data connection
int error = 0;
static int tunnelPID = 0;
if( m_pSocket->GetRemotePort(error) == 2121 ) // I use this port only for SSH tunneling
{
        if ( tunnelPID )
        {       
                kill( tunnelPID, 15 ); // SIGTERM (include signal.h)
                waitpid( tunnelPID, &error, 0 ); // (include sys/wait.h)
        }       
        wxString portFw = wxString::Format("%d:%s:%d", pData->port, pData->host.c_str(), pData->port);
        if ( !( tunnelPID = fork() ) )
                execlp("ssh", "ssh", "-L", portFw.c_str(), "myuser@myproxyserver.fr", "-N", "-n", NULL);
        pData->host = peerIP; // Connect to localhost (SSH tunnel), not to the specified IP
        sleep(4); // myproxyserver is somewhat slow to create the tunnel
}

I use tunneling only on port 2121 (I want Filezilla to work as usual for port 21). Old SSH processes are killed because I assume that they are not used anymore (data transfer is terminated, and there is only one connection at a time).
I fork filezilla to execute ssh, then the original filezilla process freezes ;-) during 4 seconds to be sure that the tunnel is created, because I don't have another way to know that.
When the function returns, FileZilla connects to localhost:pData->port to create the data connexion.
This process is repeated for each transfer.

All these things will necessarily be slower than a direct FTP connection, and since I did it badly, it's VERY slow (waiting 4 seconds for each transfer), but it does actually work, and allows me to access my FTP servers almost "as usual" with a connection that does not allow FTP.

I hope you will find this useful. It would be nice to have such option in a future version of FileZilla.

Attachments (1)

SSH-tunneling.patch (1.2 KB) - added by db8200 10 years ago.
Same code as in the description, patch created with svn diff.

Download all attachments as: .zip

Change History (3)

Changed 10 years ago by db8200

Attachment: SSH-tunneling.patch added

Same code as in the description, patch created with svn diff.

comment:1 Changed 10 years ago by db8200

Cc: dboirayon@… added

comment:2 Changed 10 years ago by Tim Kosse

Resolution: rejected
Status: newclosed

Sadly your patch isn't portable.

There however is a simple solution that works on all operating systems. Simply use PuTTY to create dynamic port forwarding. That way PuTTY acts like a SOCKS proxy and FileZilla already supports SOCKS.

Note: See TracTickets for help on using tickets.