# IPFW, ftpd, the ephemeral port range



## aquilinum (Oct 29, 2012)

I hope this isn't a mistake publishing all of this here, but sometimes it helps to talk/type these things out with someone else. I'm new to FreeBSD administration, I don't have a C.S. degree or anything, I'm just a guy who has been unable to get FTP connections working without allowing the ephemeral port range through IPFW. All that said...

I want to use the ftp daemon that comes with FreeBSD (enabled via /etc/inetd.conf) in conjunction with IPFW to create a very limited-access implementation of FTP. I want FTP to be limited in that I only want there to be room for a few users at a time and I do not want the entire ephemeral port range unblocked in order to allow FTP data transfers. This is to say, it makes sense to me to impose a limit on the number of ports available to this service to:


 tcp on 20 and 21 (the data and control ports)
 tcp on a small range (5, maybe 10 ports) opened at random for transmitting data (this should limit the number of simultaneous connections/transfers, I think...)

I currently have a inclusive firewall setup using IPFW and I'm stuck on this last hump of configuring ftpd connectivity. Presently, I can connect to my server on port 21 from my FTP client, but the process falls apart after the LIST command is sent, presumably because I am only allowing tcp traffic on port 20 and 21 right now (which is to say that I have not allowed the tens of thousands of ports that fall into the ephemeral port range).

The man page for ftpd indicates that ftpd will by default used the IP_PORTRANGE_HIGH ephemeral port ranges, which corresponds to sysctl variables:

```
net.inet.ip.portrange.hilast: 65535
net.inet.ip.portrange.hifirst: 49152
```
Right now ftpd and IPFW are not configured for ftp connections, but I have the following rules ready:

```
# add 10001 allow tcp from any to me 21 in via bge0 setup keep-state
# add 10002 allow tcp from me 20,21 to any out via bge0 setup keep-state
# add 10003 allow tcp from any to any 49152-65535 via bge0 setup keep-state
```
This configuration leaves a large range of ports open and I suspect this could be a cause for problems if someone were to try to open numerous ftp connections at the same time. Hence I want to restrict the number of available ports to fewer ports, for example 65530 to 65535, so that I can limit how 'overwhelmed' the system may become in the event of malicious activity. Unfortunately, this is not something that can be configured using ftpd arguments (-U allows me to use the IP_PORTRANGE_DEFAULT values, but this is still seems like an excessive and insecure number of ports to open up). I do not want to set custom ranges using the /etc/sysctl.conf file because I fear this will impact my ability to configure and use other services (presently or in the future).

While writing this post, it occurred to me that multiple users are going to be able to connect to the server using port 20 and 21, so what would stop someone from having multiple connections open on the same ports in the ephemeral range? I guess nothing and I now suspect two completely unrelated users could try to connect and could both use the same random port to transmit the data, be it an active or passive ftp connection.

So now I'm starting to think maybe I need to be looking into PF (packet filter) as a way to mitigate connection abuse for ftp connections, instead of relying only on IPFW.

Any thoughts?

Also, this is somewhat unimportant but since it's not documented in the man page... There are a number of different FTP software implementations, all of which have their own name, some cooler than others. In FreeBSD, the man page for ftpd simply lists 'Internet File Transfer Protocol server'. Is the FreeBSD ftpd daemon an implementation of the ftp daemon that has existed in UNIX since the Berkely/AT&T days? Does it have a name that I can use to differentiate it from the other 'flavors' of ftp daemons?


----------



## SirDice (Oct 29, 2012)

This might help to understand what's going on: http://slacksite.com/other/ftp.html

There are various other FTP implementations like ftp/proftpd and ftp/ncftpd.


----------



## qsecofr (Oct 31, 2012)

IPFW has a 
	
	



```
limit src-addr
```
 directive which can limit the number of connections from a source IP address.  That may or may not suffice for your needs.

Additionally, dummynet together with IPFW can limit the rate of data transmitted.

I no longer run an ftp server.  But when I did, the two options above seemed to do just exactly as I wanted: limit the number of connections from a single IP and limit the proportion of of my DSL uplink bandwidth given to ftp.


----------



## usdmatt (Nov 1, 2012)

You've pretty much covered everything. Also, like I've mentioned myself in other FTP threads, you're wary of limiting the high port range in case it affects other parts of the system that also use these sysctls.

I don't think it's possible for multiple client to use the same random port for data transfer. The main FTP code will accept connections on port 21, then fork off (or something similar) to handle that connection and the main process will go back to listening. There will not be any logic like this in the data connection code. It will wait for the client on the random port, process the connection, then close. I suspect you will find yourself limiting the max number of simultaneous transfers to the size of the range you allow, as FTPD will not be able to listen for the client on a port already is use by another FTP process. (*I could be wrong here though*)

Active, of course, is completely different. Active FTP has nothing to do with the high range as far as the server is concerned. Control connections will come in on port 21, and the server will create a connection out (with src-port 20) for the data transfer. Even with just rules for 21-in and 20-out, you should be able to handle any number of simultaneous active connections.

I don't see a massive security risk with opening this range as these ports are only used for random temporary use (it's not like any specific service listens permanently in this range that could be targeted) but I agree that in an ideal world you don't really want ~16000 ports open on the firewall that don't need to be.

I personally would just use one of the other FTP daemons from ports that allows the passive range to be configured if I wanted it restricted. Installing am FTPD port and modifying the standard config to restrict the passive range shouldn't be much of an problem. (Of course you'll need to check the web first to make sure your chosen FTP server has a config option for the passive range).


----------



## mix_room (Nov 2, 2012)

I don't know if you require FTP-protocol or not, so my suggestion might not be of any help. 

It is often substantially easier to use SFTP (http://en.wikipedia.org/wiki/SSH_File_Transfer_Protocol) than FTP. On top of that it is encrypted. This obviously requires that you customers are willing to adjust.


----------

