iFTPd, Independent FTP Daemon, is an open source FTP server written in Java. iFTPd features platform independence, system independence, ruggedness and a virtual file system. The target audience of the FTP server is for those admins that need to be able to share files without having to install several other programs and databases and without having to configure the rest of the system.




Since this is a daemon it doesn’t really have anything to look at, so I’ve included two screenshots of the StatusToHTML module which displays what’s going on.

First theme screenshotAlternate theme


Current features

  • Platform independence (Where do you want your JVM to go today?)
  • System independence
    • Does not require any users / groups on the host system.
    • Does not require an SQL database.
    • Does not does have weird and wonderful dependencies that must be downloaded from 500 different places.
  • Ruggedness
    • Once started, only the admin can stop iFTPd
  • Virtual file system
    • Create virtual file links, virtual directory links
    • Merge several directories into one virtual directory
    • Completely transparent to the user
  • Users and groups
    • Users can be members of several groups
    • Group files can contain other group files
  • SSL/TLS command and data channel encryption
    • AUTH TLS support
    • Encryption is available on the command and data channels
    • Encryption can be forced, locking out non-encrypted connections
  • Firewall friendly
    • Easily define which ports iFTPd runs on and which IP to report to clients
  • Shell scripts can be run before and after commands
  • Different PASV replies depending on the connected server IP
  • Text file-based configuration
  • Multithreading
  • Telnet-based status monitor
  • HTML status monitor
  • Reload functionality
  • ALLO support :)

Planned features

I think translation (I18N) support should probably be added – but only to be able to cloak the type of FTP server. Low priority anyways. I don’t even know if anyone uses iftpd except for me.

Features that will never see the light of day

  • Host system-based user dependence
  • SQL support
  • PORT support


  1. You do have a JVM installed, right?
    • Either make sure the $JAVA_HOME variable is set or edit the file conf/JAVA_HOME.
  2. Check that conf/iftpd.conf is to your liking.
    • You might also want to force SSL encryption of the command and data channels, (see conf/ssl/ssl.conf) but that might lock out users with primitive clients.Here is a list of free FTP clients that work with both channels encrypted (that I know of)
      • lftp
      • Filezilla
      • KFTPgrabber
  3. Make at least one user file in conf/users/.
  4. Make at least one group in conf/groups/.
      Make sure that at least one of the groups has a root directory.

      "/stash/ftp/" r+ "/"

  5. Start iFTPd.
      Linux users run: ./iftpd.sh start


The virtual file system (VFS)

The VFS maps physical files/directories to virtual equivalents that the user then sees. This mapping is completely transparent.

The VFS can, for example, map the directory "/stash/music/" to "/mp3". The end user will se only /mp3/ and all files directory that exist in "/stash/music/" will exist in "/mp3". If you use the same virtual target for several rules, the physical targets will all be merged into the same virtual target.

VFS rules are defined in two places: primarily in the group file(s) and secondarily in the user’s conf file.

"/stash/movies/divx/" r+ "/movies/"
"/stash/movies/divx/" The physical target (file/dir) as it exists on disk.
r+ Access mode. Possible modes are readable, writeable and resursive(+).
"/movies/" Virtual target (file/dir) as the user will see it.



The StatusToHTML module dumps the status information of the server and all online users to an HTML file. The file used is set in the conf/statustohtml.conf file.

StatusToHTML works by parsing several html files, found in conf/statustohtml/, into one resulting HTML file. It replaces specific keywords in the .html files with variables taken from the server and user statistics.

The keyword #ONLINECOUNT#, for example, is replaced with the number of users currently online.

There are four .html files the module parses, 1 and 4 are parsed only once while 2/3 are parsed as many times as there are users online.

  1. header.html is the header file. It is parsed once and placed at the top of the resulting .html file.
  2. normalentry.html is the html file used when the user is not transferring files. Typical non-transfer actions are “logging in” and “idle”.
  3. transferentry.html is the html file used when the user is transferring files. The transferentry has more keywords available than normalentry.
  4. footer.html is the footer file. It is parsed once and placed at the end of the resulting .html file.

The reason for having two types of entries is because the two types of entries relay different types of information and require a different presentations.


Global (available for all four types of html files)
SERVERNAME The name of the server, found in conf/iftpd.conf.
ONLINECOUNT Number of users currently online.
CONNECTIONCOUNT How many users have connected to the server in this session.
SERVERSTARTEDDATE Date server was started as YYYY-MM-DD
SERVERSTARTEDTIME Date server was started as HH:MM:SS
SERVERONLINE Time in HH:MM:SS the server has been on.
AUTOBYTESUPLOADEDTOTAL The amount of giga/mega/kilo/bytes the users have uploaded this session.
AUTOBYTESDOWNLOADEDTOTAL The amount of giga/mega/kilo/bytes the users have downloaded this session.
FILESUPLOADEDTOTAL The number of files the users have uploaded this session.
FILESDOWNLOADEDTOTAL The number of files the users have downloaded this session.
NormalEntry and TransferEntry
USERNAME The name of the user.
TIMEONLINE How long the user has been online as HH:MM:SS
LOGONDATE The time the user logged on as YYYY-MM-DD.
LOGONTIME The time the user logged on as HH:MM:SS.
IP The IP of the user (
FQDN The fully qualified domain name of the user (www.googleisasellout.com).
ACTIONVERB A word, preferrably only one, describing the action of the user.
ACTIONDETAILS A detailed description of what the user is doing.
FILESUPLOADED How many files the user has uploaded.
FILESDOWNLOADED How many files the user has downloaded.
AUTOBYTESUPLOADED The amount of giga/mega/kilo/bytes the user had uploaded.
AUTOBYTESDOWNLOADED The amount of giga/mega/kilo/bytes the user had downloaded.
ABORTS How many times the user has aborted transfers.
TransferEntry only
FILENAME The complete name of the file being transferred.
AUTOFILESIZE The size of the file in giga/mega/kilo/bytes.
DIRECTION The direction of the transfer, either UPLOADING or DOWNLOADING.
AUTOBYTESTRANSFERRED How many giga/mega/kilo/bytes have been transferred.
PERCENTCOMPLETE The percentage of completion of the file transfer, without the percent sign.


Q: Why is the PORT command neither supported nor planned?

A: The PORT command, a.k.a. “active FTP”, instructs the server to connect to a specific port on the client machine and use that port for data transfers. Now this was a great idea about 20 years ago (when FTP was invented) but with the arrival of NAT and firewalls the server can no longer be guaranteed a direct connection to the client.

Instead, the PASV (“passive”) command is used. The difference being that the client connects to the server and therefore the server is given a data connection to the client. PASV, together with port forwarding of known ports (specified in iftpd.conf) enables one to put the server behind several firewalls and still be able to serve files.

Also, PORT is a security risk. See “PASV security and PORT security”.


iFTPd behind a firewall

If you have a hardware firewall, check what ports iFTPd uses in iftpd.conf and open those ports.

If you have an iptables firewall, issue the following commands:

iptables -A INPUT -p tcp --dport 21 -j ACCEPT
iptables -A INPUT -p tcp --dport 20001:20100 -j ACCEPT

iFTPd behind a NAT (port forwarding help)

You have a linux-based firewall machine and iFTPd is running on another machine in the network. You need to forward iFTPd commands to the iFTPd machine (say

  1. Using iptables, issue the following commands:
    iptables -t nat -A PREROUTING -d $EXTERNAL_IP -p tcp --dport 21 -j DNAT --to
    iptables -t nat -A PREROUTING -d $EXTERNAL_IP -p tcp --dport 20001:20100 -j DNAT --to
  2. Edit iftpd.conf and change the “pasvip” setting to the IP or hostname of the iptables machine.

If this doesn’t work, you might want to check that iptables -t nat -P PREROUTING ACCEPT is issued.

iFTPd displays question marks in the file names

export LC_CTYPE=en_US

Why does the file conf/JAVA_HOME exist?

The author’s Gentoo system has a terrible time accepting changes to the /etc/profile file, and adding Java releases to the system is a pain in the ass, so he figured that instead of trying to make Gentoo do as he says, he can just put the JAVA_HOME variable somewhere, but because he hates changing system-wide variables at all, why not makt the variable local?

Local as in “a file which contain the path to the Java JRE which isn’t overwritten all the time”. So he put the path in a file in the conf directory, which can easily be transferred between iFTPd upgrades and installations.

What is the state of SSL?

Since v1.5 iFTPd supports SSL/TLS encryption of both the command and data channels. It is enabled per default, but not enforced. The reason is that clients need to be told to use another FTP protocol (FTPS/explicit TLS) and this could confuse existing users.

For maximum security, force the command and channels to be encrypted. See the conf/ssl/ssl.conf file.

Per-user X509 certification will probably be added in the future sometime, but as of right now SSL/TLS should be enough to keep prying eyes out of your FTP sessions.


2010-09-11 v1.9
2010-08-10 OPTS UTF8 ON support added. The directory listing was always UTF8, though. Filezilla should now be happy.
2010-07-24 v1.8
2010-07-24 PASV can reply with different IPs depending on which IP address request was received on.
2010-06-04 Multiple scripts can be run. Scripts are read from the user file and the groups directory (groupname.scripts)
2010-06-01 Scripts can be run before and after FTP commands.
2010-05-29 v1.7
2010-05-29 Timezone is correctly handled via MDTM and MFTM.
2010-05-29 LIST can list older (>1 year old) files also.
2010-05-29 FEAT now answers correctly, which enables MFMT et al work properly.
2010-05-29 File times are now in 24h time.
2010-05-29 v1.6
2010-05-28 REST is now a long.
2010-05-28 Existing files are deleted before being transferred.


The author can be contacted at edward@edwardh.se.