Wednesday, August 30, 2006

Setting up a passive ftp server behind a firewall or NAT router

It's hard to find a decent FTP server application that will allow you to specify whether it runs in ACTIVE or PASSIVE mode and as a Windows system service let alone specify the ports it uses. Even the IIS package that comes with most versions of Windows isn't quite up to my task.

I won't get into the specifics of setting up an FTP server in either Active or Passive mode, that's what Google is for. Here is a good link that breaks it down into simple terms. Active vs. Passive FTP


In my situation I had the following problems and requirements.

1) My FTP server is behind a Westell 327w DSL modem with Verizon Internet service. The modem/router supports IP pass through to a single machine, however, I prefer the extra layer of protection it offers in NAT mode. I will want to use the router's port forwarding abilities in my case.

2) I want to be able to connect to my FTP server from behind another "NAT'd" computer. My company's corporate firewall blocks all unsolicited incoming network traffic. Luckily they don't block outgoing ports.

3) I can't use the standard 21 or 20 port (Verizon blocks it)

4) I want my FTP server running whether or not someone is logged on to the machine. There are a lot of basic freeware FTP servers out there, but the majority of them will only run if a user is logged in to the machine. To preserve system resources I'd rather not have a user session running on the machine. Therefore, it needs to run as a Windows system service.

5) I need to connect to the FTP server from both inside my "Nat'd" network, as well as, from outside of it. Verizon does not allow loopback packets (other than ICMP ping requests AFAIK). So, if I try to connect to my FTP server from within my network using my "Internet IP" the packets will go out to Verizon's servers but never get looped back to my Westell router.

6) I don't want to pay for the FTP server software. I'm a big open source/free kind of guy.



I decided the best course of action would be to use an FTP server setup in PASSIVE mode. I can't use active since my company's firewall will just drop/ignore/laugh at the icoming packets from the FTP server rather than forward them to my FTP client. Since I control the port forwarding on my Westell 327w I can recieve unsolicited requests from an FTP client. So, using ACTIVE mode is my only real course of action.

In my Westell I configured it to forward the ports 20,000 - 20,500 my FTP server. Having 500 incoming ports to the ftp server is probably overkill in my case. From what I've read you only need one port per client connection. So, right now I would assume I can support about 500 clients logged in at the same time. I also decided to run my FTP server's main port on 5000 instead of the standard 21. This gets me around Verizon's restrictive nature of blocking incoming port 21 connections. It also aids slightly in avoiding all the little script kiddies out there scanning for open FTP ports.

When it came to choosing an FTP server it became more difficult. I started out with Microsoft Windows IIS 5.1 since it was built into my OS. After doing some research I learned that you can change the passive ports it uses by adding a string value named "PassivePortRange" to the registry under HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\Msftpsvc\ParametersYou can read the details of it here Microsoft KB 555022

For some reason I could NOT get it working from outside my local area network. I would get prompted for a username and password but could not retrieve a directory listing. I've since discovered why. In PASSIVE mode after the client has authenticated and requests a directory listing or file, the FTP server sends a command to the client with what IP address and port it should connect on. However, IIS does not resolve your externally visible IP address. Instead, it sends it the FTP server's local area network IP address. For example, 10.1.1.50 or 192.168.0.50. Neither one of these are accessible to your FTP client so the connection fails right after login. But inside your local area network this would work fine since 10.1.1.50 or 192.168.0.50 would be perfectly normally. What the server needs to do is send the client your "Internet IP" address, such as, 71.245.32.76 along with the port to connect on for data transfer when they are located "outside" your local area network. When a client connects from inside your local area network they need to recieve an ip address, such, as 10.1.1.50.

I was only able to find two FTP clients that had the ability to send different IP addresses to their clients in passive mode depending on where they were connecting from. One of them was edtFTPD which was ported over from the Linux version of proFTPD using the .Net framework. proFTPD is able to perform this tricky task by changing its default config file to use VirtualHost and MasqueradeAddress. I didn't have any luck getting it working and found edtFTPD incredibly difficult to manage users with. You can read more about this program here


Then I tried War Daemon 1.80 by jgga. It took a little while to find the documentation I needed but there is a nat.conf file which can be used to overcome all of my connection problems both from inside the network and outside of it.

Here is the instruction text included in the file. Lines starting with # are ignored by the application.

# Network Adress Translation (NAT) configuration file for
# the War FTP Daemon 1.81
#
# (Lines starting with '#' in this configuration file are treated
# as comments.)
#
# Remote IP range:
# Network address and mask to identify the network
# or interface to set options to.
# The network mask can be in dotted or simple notaion
# i.e. /255.255.255.0 = /24.
#
# Port:
# The port the FTP server binds active (PORT command)
# data connections to. Use 20 for RFC959 compliance,
# -1 for one below the FTP control connection port,
# an exact number or 0 for random numbers.
#
# Host Address:
# The IP address the server reports in the reply to
# the PASV command. If the server is behind a dumb
# NAT router, it can report the IP number to the
# routers external interface, if the router is
# configured to forward TCP/IP traffic on some ports
# to the FTP server.
# The Host address can be one of tree:
#
# 1) An IP number
#
# 2) A host-name. If you specify a host-name, the name
# will be looked up when the server starts, and
# each time nat.conf is reloaded. You can also
# specify that the server should resolve the host-name
# automatically each n minutes, where n can be specified
# by adding a column after the hostname.
#
# Example: ftp.jgaa.com:10
# This will make warftpd resolve ftp.jgaa.com each 10
# minutes in the background, without slowing down the
# server.
#
# 3) A "dynip" declaration. Dynip stands for "Dynamic IP".
# This mode makes warftpd contact a server at
# dynip.jgaa.com each 5 minutes. This sever updates
# your FTP sites IP in DNS (example: yoursite.dynip.jgaa.com)
# and return the actual IP address as it is seen on the
# Internet to warftpd. You can specify another refresh interval,
# by adding a column after the dynip specification.
# The dynip specification consists of an alpha-character,
# a dynip handle ID, a column and a secret password.
# Before you can use this mode, you must register your
# site at http://dynip.jgaa.com. When you register your
# site, it will be assigned a site ID, and you will be
# asked to provide a secret password. The password is
# required to prevent anyone else from "hijacking" your
# site. Please note that the password cannot contain spaces
# or column characters due to the syntax of the nat.conf file.
#
# Example: @1:secret
# This example specifies that you own dynip Site ID 1,
# and that it uses the password "secret".
#
# Example: @1:secret:10
# This example also specify that warftpd should exchange
# updated information with the server at dynip.jgaa.com
# each 10 minutes. The refresh rate should be 60 minutes
# max. If the delay is too long, the DNS information will
# be disabled at dynip.jgaa.com.
#
# Port-range:
# A range (from-to) of port numbers the server can bind
# to during passive (PASV) data transfers. This is
# typically a range the router will forward to the FTP
# server, or a range the firewall is aware of as data-
# ports to the FTP server. A value of 0 means that the
# server will pick random ports.
#
# The rules are matched from top to bottom.
# If a network-number/mask pair match the clients TP address,
# the options are applied. If no rule matches, the default
# options for the server (ftpd_BINDDATA) is applied.
#
# This configuration file is read when the server is started,
# and when changes in the machines IP numbers are detected.
#


# The following sample is meant for a server on the private IP
# address 192.168.0.2, behind a router that forwards IP
# adresses from Internet to the server without changing the
# source address or port number.
#
# Line 1: Use default values for localhost
# Line 2: Use default values for the local network (LAN)
# Line 3: Set options for all other hosts
#
# Remote IP range # Port # Host Address # Port range
#---------------------- ------- --------------- ------------

To the bottom of this file I appended the following


127.0.0.1 2001 0 25000-25500
server/255.255.255.0 2001 server 25000-25500
0/0 -1 ftpserver.no-ip.org 25000-25500


Now I'll explain how this works... to the best of my knowledge.
The line below is used to handle connections made from the FTP server machine itself. I'm not sure if it is needed but someone else added it so I left it alone.

127.0.0.1 2001 0 25000-25500



The line below is used to handle connections that are made from within the local area network or subnet. War FTP Daemon will see the 192.168.1.50/255.255.255.0 part and interpert that it applies to connections coming in on the machine's direct IP.

I'm not sure what the 2001 really does. I believe it specifies the active port, but I don't use it.

The 192.168.1.50 is the IP address that will be sent to the client with the PASV command instructing it to connect back on that IP. The 25000-25500 range is a range of ports the FTP server will use to send along with the IP when issuing the PASV command.

192.168.1.50/255.255.255.0 2001 192.168.1.50 25000-25500


The line below is used for all connections coming in from outside the local area network. When the connection comes in War FTP Daemon will resolve the ftpserver.no-ip.org to it's ip address and send that back to the client. An IP address can also be specified here. However, I'm using the no-ip.org service so this is similiar to what mine looks like.
0/0 -1 ftpserver.no-ip.org 25000-25500


*NOTE* I think these rules are interperted from the top down, if a rule is encountered that matches the criteria it will use that rule and disregard the others. I haven't been able to find any documentation stating this though. If you set it up in the order I have shown above you shouldn't have any problems.

So, there you have it. I hope this helps someone as I know there are a lot of people struggling with this problem.

1 comment:

  1. hello, i was having alot of problem when i am setting up my ftp server. i am also on dsl with Verz and on westell 327w modem/router/wireless. can u please explain to me in reg. english step by step on how to configure my modem inorder for ftp to work? i am not that good with technical stuff. thanks alot!

    ReplyDelete