Proftpd PassivePorts Requirements (or Not Working)

After an exhaustive research session attempting to enabled Passive FTP on a Proftpd server I found and am now documenting this issue.

PassivePorts is a directive in Proftpd.conf to configure proftpd to use a specific set of ports for Passive FTP –   You would the allow these ports through your firewall to your server.

The documentation on the full configuration and reason that you would use Passive vs Active FTP,  and how to set it up on your server and firewall are beyond the scope of this document but I a couple of links that might get you there are here.

  • http://proftpd.org/docs/directives/linked/config_ref_PassivePorts.html
  • https://ubuntuforums.org/showthread.php?t=39566
  • http://matrafox.info/proftpd-passive-port-not-working.html
  • http://slacksite.com/other/ftp.html

In my first attempts I was attempting to use the port range between 60000 and 65535,  the firewall ports were forwarded,  and things did not work

  • PassivePorts 60000 65535

So I had to dig in and find the details of why not,   I enabled debugging on filezilla and ran at the command line in order to try and see what was happening

  • proftpd -n -d30

I found a post somewhere that explained how I could read the response to the PASV  command,

  • Entering Passive Mode (172,31,10,46,148,107)

These last two octets in the response are the port number that is to be used  here is how you calculate it (148*256 +107)=37995.    Even though I had the server setup to use PassivePorts 60000 – 65535 it was still attempting to use 37995.    Once I figured out how to confirm which port was being sent,  I realized that the issue was not a firewall or other problem, but rather something in the system.

I happened across a Slacksite article which helped me find this in the Proftpd Document

PassivePorts restricts the range of ports from which the server will select when sent the PASV command from a client. The server will randomly choose a number from within the specified range until an open port is found. Should no open ports be found within the given range, the server will default to a normal kernel-assigned port, and a message logged.

In my research I was unable to find a message logged so I dont believe that a message shows anywhere,  however this article helped me realize that there may be some issue on my system which was preventing ports 60000 to 65535 to be available and I started playing with the system

  • 60000-61000 and 59000-60000 had no effect the system was still assigning ports within the 30000 to 40000 range.
  • 50000 to 51000 had the same effect

So I tried some entries within the 30000 and 40000 and I found I could consistently control the ports if I used any range between 30000 and 40000

  • PassivePorts 30000 32000 – gave me 31456, 31245, 30511,  etc
  • PassivePorts 32000 34000 – gave me 33098, 32734, 33516,  etc
  • etc

From this I figured out that I can only control the ports on this system in a range lower than the ones I was originally attempting

I did more research and found that there is a sysctl variable that shows the local anonymous port range

  • sysctl -a|grep ip_local_port_range

On my system for some reason this was set to

  • net.ipv4.ip_local_port_range = 32768 48000

I attempted setting this to a higher number

  • sysctl -w net.ipv4.ip_local_port_range=”32768 65535″

However this did not change the way the proftpd allocated the ports   only the lower range was available.   Perhaps I could have set the variabl in sysctl.conf and restarted,  but I stopped my investigation here.  Instead I changed the firewall rules to allow port 32000 to 34000 through and I stuck with the configuration

  • PassivePorts 32000 34000

What I learned from this was

PassivePorts only suggests that your system use range of ports you specify,   If that range is not available the system quietly selects a port outside the range you specified,  If you have problems with your FTP hanging at MLSD check your logs to verify which PORT has been assigned. using the calculation (5th octet *256 + 6th octet).