OpenBSD Journal

Using Active FTP Clients Through an OpenBSD 3.0 Firewall

Contributed by Dengue on from the howto dept.

F. William Lynch was kind enough to submit a well written howto describing the configuration of OpenBSD 3.0's new ftp-proxy daemon. Read on for the answers to those pressing questions...

Using Active FTP Clients Through an OpenBSD 3.0 Firewall
By F. William Lynch

With release 3.0 the OpenBSD project replaced Darren Reed's ipf software with the more license friendly pf filtering software. While pf and ipf are very similar in overall design, there are many subtle differences bewteen the two. This paper will focus on one particular difference between the two, how to allow outbound active FTP access from clients protected by an OpenBSD 3.0 firewall.

Review of the FTP Protocol
Before we go into detail about how to configure OpenBSD 3.0, let's briefly review how the FTP protocol works (and doesn't work). FTP is a very venerable protocol that was definately not designed with security in mind. While it was being developed, the concept of a firewall didn't even exist. Since then, improvements have been made to the FTP protocol to make it easier to secure. Unfortunately, client software packages (at least on the Windows platform) have been slow to adapt to these changes, forcing firewall administrators to develop some sort of workaround.

Anatomy of an Active FTP Session
During a standard active FTP transfer, the client initiates an FTP control session from a random unprivileged port (N > 1024) to the server's FTP control port (21). Then when data is transmitted, such as a file listing or file transfer the FTP server initates an FTP data session from it's FTP data port (20) to a random unprivileged port on the client. This process is detailed in Figure 1.

Figure 1

Anatomy of a Passive FTP Session
As you can see, Active FTP becomes a very difficult protocol to secure, because the firewall must allow incoming connections to hosts behind the firewall to all unprivileged ports. Clearly, this is not an option for most sites. So, the IETF took the FTP protocol back to the drawing board and designed the passive (PASV) FTP transfer session. During a passive FTP transfer session, the client initiates an FTP control connection to the server's FTP control port (21). The server then allocates a random unprivileged port of it's own for the FTP client to connect to for data transfer. Then, the client connects from an incremented port of its own (N > 1024 + 1) to the port allocated by the server and begins data transfer. This process is detailed in Figure 2. You should note that in a passive FTP connection, port 20 on the server is never in use.

Figure 2

Anatomy of a Proxy FTP Session
To allow active FTP access to its protected clients, OpenBSD includes its own active FTP proxy, aptly called "ftp-proxy" which acts as an intermediary during an active FTP connection. During the client connection, pf notices that a client is attempting an FTP connection and redirects the session to the internal FTP proxy on port 8081 (default). The firewall itself then establishes the FTP connection from its external interface to the FTP server. Connections originating from the FTP server as an FTP data connection (port 20) are then allowed back into a specified range of unprivileged ports on the firewall's external interface. This data is then passed back to the client by the firewall, as detailed in Figure 3. The astute reader will note that the ftp-proxy method is not as secure as passive FTP transfers. However, it exists because some types of clients, notably certain types of web browsers do not support passive FTP. Thus, ftp-proxy is required if these clients are to use FTP at all. Also, ftp-proxy does not currently make state entries, although it may in future versions.

Figure 3

Configuring the ftp-proxy in OpenBSD 3.0
It's not really more difficult to configure active FTP pass through with pf than it was with ipf, it's just a bit different. You'll need to make changes to four different files total but we'll look at each of these changes.

You need to make sure that there is an ftp-proxy entry in /etc/services before going any further. Usually, this should point to the default port of 8081, unless you have some reason for changing it. Add the following line to /etc/services:

ftp-proxy       8081/tcp                # ftp-proxy

The ftp-proxy service is run from inetd, so you will need to add this service to the inetd configuration file and make sure that inetd is not disabled in /etc/rc.conf. Your entry should look like the following sample, adjusted for your site:

ftp-proxy stream tcp nowait root /usr/libexec/ftp-proxy \
ftp-proxy -n -V -D3 -u nobody -m 55000 -M 57000 -t 300
The options on ftp-proxy are as follows:

(Comments are closed)

  1. By Anonymous Coward () on

    My best regards to the guy who took the time to do this!

    Great work!

  2. By Ryan Cooley () on

    It's a nice tutorial no doubt, but of what use? It doesn't say anything that the ~3 applicable man pages don't, and doesn't make it much simplier either.

    If course, feel free to call me an idiot and say I missed the point.

  3. By Free Bird () on

    Why would you want to use Active FTP anyway? If your client doesn't support pasv, use another client.

  4. By webmaster () on file:/dev/null

    Because the graphics are quite large, some viewers may dislike the horizontal scrolling. You can view this howto at without all of the OpenBSD Journal "stuff" wrapped around it.

  5. By Anonymous Coward () on

    Using that stupid proxy requires me to open up holes for active ftp that I don't need to with the ipf proxy. Why doesn't someone "just fix it" (the proxy) ?

  6. By Anonymous Coward ( on

    Missing pictures?


Copyright © - Daniel Hartmeier. All rights reserved. Articles and comments are copyright their respective authors, submission implies license to publish on this web site. Contents of the archive prior to as well as images and HTML templates were copied from the fabulous original with Jose's and Jim's kind permission. This journal runs as CGI with httpd(8) on OpenBSD, the source code is BSD licensed. undeadly \Un*dead"ly\, a. Not subject to death; immortal. [Obs.]