From owner-freebsd-pf@FreeBSD.ORG Tue Mar 4 01:02:17 2008 Return-Path: Delivered-To: freebsd-pf@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id 76AA61065672 for ; Tue, 4 Mar 2008 01:02:17 +0000 (UTC) (envelope-from jdc@parodius.com) Received: from mx01.sc1.parodius.com (mx01.sc1.parodius.com [72.20.106.3]) by mx1.freebsd.org (Postfix) with ESMTP id 6A43B8FC1E for ; Tue, 4 Mar 2008 01:02:16 +0000 (UTC) (envelope-from jdc@parodius.com) Received: by mx01.sc1.parodius.com (Postfix, from userid 1000) id CFA331CC033; Mon, 3 Mar 2008 17:02:16 -0800 (PST) Date: Mon, 3 Mar 2008 17:02:16 -0800 From: Jeremy Chadwick To: "Michael K. Smith - Adhost" Message-ID: <20080304010216.GA57085@eos.sc1.parodius.com> References: <17838240D9A5544AAA5FF95F8D520316036997D3@ad-exh01.adhost.lan> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <17838240D9A5544AAA5FF95F8D520316036997D3@ad-exh01.adhost.lan> User-Agent: Mutt/1.5.16 (2007-06-09) Cc: freebsd-pf@freebsd.org Subject: Re: Confusion about FTP through PF X-BeenThere: freebsd-pf@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: "Technical discussion and general questions about packet filter \(pf\)" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Tue, 04 Mar 2008 01:02:17 -0000 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 |