Confusion about FTP through PF

Jeremy Chadwick koitsu at freebsd.org
Tue Mar 4 01:02:17 UTC 2008


On Mon, Mar 03, 2008 at 09:03:11AM -0800, Michael K. Smith - Adhost wrote:
> Hello All:

First, is there a reason you sent your message twice, 6 hours apart,
with different subject lines?  Sorry if I sound crass, but I'm not sure
why you did this.  :-)

> I am confused about using FTP through PF.  We have been running with a working ftp-proxy setup that allows our internal servers to ftp out with no trouble.  I am now interested in putting an FTP server behind my PF configuration and I've not been too successful.
> 
> If I am running an FTP server, is it necessary to proxy the connections through the PF boxes or can I just allow the FTP connections through PF to those servers?  If it's necessary, does anyone have a configuration that will work for an FTP server servicing inbound FTP connections from the Internet to a server behind PF?

You need to understand the FTP protocol's modes of operation when it
comes to data transfers to properly fix your rules.

An FTP server listens on TCP port 21 for incoming connections which can
be referred to as "control" connections (e.g. commands the FTP client is
submitting to the server).

However, for directory listings and file transfers, FTP has two modes of
operation: active and passive.  The mode used can be selected by the FTP
client.  Passive is pretty much the standard mode of operation now in
all FTP clients, but supporting both modes is important.

Active mode causes the FTP client to use the PORT command, while passive
mode causes the FTP client to use the PASV command.

In active mode, the FTP client will open a listening TCP port (on the
clients' side), and then send the PORT command to the FTP server, which
includes the clients' IP and listening port #.  The FTP server, using
TCP port 20 (e.g. source = public:20, dest = ftpclient:someport) as its
source port, connects to the TCP port specified by the FTP client, and
the data transfer begins.

This is a problem for FTP clients behind firewalls, as I'm sure you can
imagine -- which is what passive is for.

In passive mode, the FTP client will send a PASV command to the FTP
server.  The FTP server will then open a listening TCP port (on the FTP
servers' side), and will respond to the clients' PASV command with the
IP address and port # the client should connect to.  The TCP port # used
is *dynamic*, which makes it very difficult to properly siphon through a
firewall.

There's a couple workarounds for this.  ftp-proxy is one, but the one I
prefer to use is based on this: FreeBSD's ftpd(8) allows to specify a
range of TCP ports the FTP server will use when opening a listening
port on PASV.  See the -U option in the ftpd(8) manpage.  The default
range is 49152 to 65535.

With this in mind, you can poke holes in your firewall for those ports,
redirecting any connections to 49152:65535 to the FTP server's internal
IP address.

This is taken from our pf.conf on our production FTP server.  The FTP
server has a public IP address 72.20.106.8, but uses pf(4) to deny all
incoming packets and permit all outgoing packets:

# Punch holes for FTP.  The rule looks complex, so here it is explained:
#
# - Make sure pass rule only applies to 72.20.106.8 (ftp.sc1.parodius.com)
# - Permit incoming connections to port 21 (main FTP service)
# - Permit incoming connections to ports 49152-65535 (FTP passive mode)
# - TCP port 20 is actually for **outbound** connections in FTP active mode,
#   and since we allow all outbound traffic, we don't need a rule for it.
# - TCP ports 49152-65535 come from ftpd(8) and ip(4) manpages; there are
#   sysctl(8) knobs for theses, but we shouldn't mess with those.
#
pass in quick on $ext_if inet proto tcp from any to 72.20.106.8 port { ftp, 49152:65535 } modulate state flags S/SA

Understanding how the protocol works is key to understanding how to
properly administrate a firewall that has to deal with FTP.  So I hope
this helps clear up some of the confusion.

-- 
| Jeremy Chadwick                                    jdc at parodius.com |
| Parodius Networking                           http://www.parodius.com/ |
| UNIX Systems Administrator                      Mountain View, CA, USA |
| Making life hard for others since 1977.                  PGP: 4BD6C0CB |



More information about the freebsd-pf mailing list