121 lines
5.1 KiB
HTML
121 lines
5.1 KiB
HTML
<!DOCTYPE html>
|
|
<html>
|
|
<head>
|
|
<title>ProFTPD: Configuring FTP over SSH</title>
|
|
</head>
|
|
|
|
<body bgcolor=white>
|
|
|
|
<hr>
|
|
<center><h2><b><i>ProFTPD: Configuring FTP over SSH</i></b></h2></center>
|
|
<hr>
|
|
<i><b>IMPORTANT NOTICE</b>: the original instructions listed on this page,
|
|
based on <a href="http://www.proftpd.org/proftpd-l-archive/98-11/msg00066.html">http://www.proftpd.org/proftpd-l-archive/98-11/msg00066.html</a> were
|
|
incorrect, and did <b>not</b> lead to the proper encryption of the FTP control
|
|
channel. Many, many thanks to Michael Jochimsen for pointing out the
|
|
incorrect use of ssh port forwarding!</i><br>
|
|
<hr>
|
|
|
|
<p>
|
|
<b>Premise</b><br>
|
|
The File Transfer Protocol is an old protocol, and like many of the older
|
|
protocols it was developed in a time when security was not of such a paramount
|
|
concern. One aspect of FTP that reflects this is the transmission of
|
|
passwords, used to prove to the server that the client is who they say they
|
|
are, "in the clear", unencrypted, visible to any packet sniffer.
|
|
Protocols like SSH, and its <code>scp</code> program, are replacing FTP
|
|
as a means to securely transfer files among hosts.
|
|
|
|
<p>
|
|
However, many people still prefer to use their standard FTP clients. What
|
|
would be easiest would be a way to allow such clients to function while
|
|
transparently providing the encryption necessary for today's networks. Can
|
|
this be done? Yes - after a fashion. This document aims to describe how
|
|
to tunnel FTP over an SSH channel, providing for secure transmission of
|
|
the user's password.
|
|
|
|
<p>
|
|
<b>Client Configuration</b><br>
|
|
The trick to encrypting the password is to make use of ssh's local port
|
|
forwarding capability. It works by creating a sort of proxy on the local host
|
|
that listens to some high-numbered port. Any traffic sent to that port
|
|
is encrypted, and forwarded to the configured remote address and port.
|
|
(<b>Note</b>: the prior instructions' flaw was that the local port forwarding
|
|
request was sent to localhost, rather than to the remote server, which
|
|
effectively set up the encrypted channel between localhost and itself).
|
|
Here's how to set up a local port forward:
|
|
<pre>
|
|
$ ssh -L<i>local-port</i>:<i>remote-addr</i>:<i>remote-port</i> <i>user</i>@<i>host</i>
|
|
</pre>
|
|
This says to listen on port <i>local-port</i> on localhost, and to send that
|
|
encrypted traffic to <i>host</i>'s <i>remote-addr</i> at port
|
|
<i>remote-port</i>. To use this trick to secure an FTP session (to be
|
|
specific, the control channel, through which passwords are transmitted, will
|
|
be encrypted; the data channel will not), it would look like:
|
|
<pre>
|
|
$ ssh -f -L3000:ftpserver:21 ftpserver 'exec sleep 10' && ftp localhost 3000
|
|
</pre>
|
|
Note that the choice of <i>local-port</i> is arbitrary. Using port
|
|
<code>3000</code> is not a requirement. This trick also requires that
|
|
the ftp client use passive mode data transfers, so make sure to use a client
|
|
that understands FTP passive mode.
|
|
|
|
<p>
|
|
<b>Remember that only the control connection is encrypted, not the data
|
|
connection: any data you transfer (<i>e.g.</i> directory listings, files
|
|
uploaded or downloaded) are still sent "in the clear".</b> Your
|
|
password (and the other FTP commands sent by the client) is not.
|
|
|
|
<p>
|
|
<b>Server Configuration</b><br>
|
|
The server side of the connection needs some configuration to make the ssh
|
|
tunneling work as well. First, the client need a valid account on the remote
|
|
host is necessary in order to support the ssh tunnel. A valid shell is not
|
|
strictly necessary for these ssh tunnels, though; something like:
|
|
<pre>
|
|
#!/bin/sh
|
|
sleep 10
|
|
</pre>
|
|
would suffice. This would prevent the FTP users from logging in, yet give them
|
|
enough time to establish a port forwarded ssh connection. With this sort
|
|
of quasi-shell (although, strictly speaking, there are better, more restrictive
|
|
shells than this example, as it could be escaped from), one can ssh over any
|
|
command:
|
|
<pre>
|
|
$ ssh -l test -f -L3000:ftpserver:21 ftpserver true && ftp localhost 3000
|
|
</pre>
|
|
You'll also need to use the
|
|
<a href="../modules/mod_core.html#AllowForeignAddress"><code>AllowForeignAddress</code></a> configuration directive in your
|
|
configuration file:
|
|
<pre>
|
|
AllowForeignAddress on
|
|
</pre>
|
|
or <code>proftpd</code> will reject the passive transfer connections and log:
|
|
<pre>
|
|
SECURITY VIOLATION: Passive connection from {host} rejected
|
|
</pre>
|
|
|
|
<p>
|
|
Note that the use of the server host's DNS name, or its IP address, in the
|
|
setting up of the ssh tunnel assumes that the routing of traffic to the
|
|
host's own IP address will be short-circuited in the kernel and thus not
|
|
actually be transmitted on the wire. On modern kernels this is a fair
|
|
assumption, but may not always be the case. For the truly paranoid, use
|
|
of <code>localhost</code> or <code>127.0.0.1</code> as the <i>remote-addr</i>
|
|
parameter in the ssh tunnel command would cause traffic on <i>host</i> to
|
|
be sent over its loopback address, and not over the network. However, this
|
|
will prevent data transfers from working altogether. The author has a
|
|
patch for scenarios like this; if interested, please contact him directly via
|
|
email.<br>
|
|
|
|
<p>
|
|
<hr>
|
|
<font size=2><b><i>
|
|
© Copyright 2017 The ProFTPD Project<br>
|
|
All Rights Reserved<br>
|
|
</i></b></font>
|
|
<hr>
|
|
|
|
</body>
|
|
</html>
|