Professional FTP Daemon FAQ

Mark Lowes

Table of Contents
1. Introduction to ProFTPD
2. Compilation and installing
3. Compatibility and Integration
4. Common Running problems
5. Configuration problems
6. Security
7. User Authentication
8. FAQ Notes


Chapter 1. Introduction to ProFTPD

1. What is ProFTPD?
2. What is the current version?
3. Version numbering scheme
4. Website & documentation
5. Bug reporting
6. I've found a security hole
7. Downloading
8. Mailing lists
9. Copyright Issues

Bug reports should be made via which uses the bugzilla tracking system. Patches should be mailed to the ProFTPD-Devel mailing list or MacGyver directly.

Please report all security problems with the code to before releasing the information into the public domain. It would be appreciated if you give the core team a few days to put together a patch and/or new release to address the issue.

Please adhere to the proceedures and timescales given in the RF Policy document, this will give the core development team a chance to get a fix or workaround in place before the problem becomes fully public domain.

There are a number of mailing lists for ProFTPD


This is a very low traffic list where only ProFTPD announcements/changes will be announced. Subscribe by sending a message to with "subscribe" in the subject.

Web interface:


This is intended to the the user support channel for the software, in most likelihood this is going to be a high traffic list and slightly chatty. Please read the FAQ, the documentation and the list archives before posting a question.

Subscribe by sending a message to with "subscribe" in the subject.

Web interface:


This list is intended for discussion of development-related issues of ProFTPD, and feature design. It is NOT intended to be a "user help" group.

Subscribe by sending a message to with "subscribe" in the subject.

Web interface:


The mailing list archives can be found at:


Before posting to any of the lists or mailing the list admins please try and remove yourself first. Either by emailing <listname> with the subject "unsubscribe" or visiting the web interface and unsubscribing from there.

I've (lost / never had) a password to the interface. Easy, enter the address you are subscribed to the list as into the form and hit the "email me my password" button.

Chapter 2. Compilation and installing

1. What platforms will it compile on?
2. Why not libc5 on Linux?
3. CVS
4. How do I get debug output
5. Patches
6. Using non-default modules
7. Plans for next version (1.3.x)
8. NT Support
9. New features/modules

Chapter 3. Compatibility and Integration

1. SQL
2. SSH
3. sendfile()
4. IPv6
5. Filename case sensitivity
6. FXP

There is a mini-HOWTO at detailing how to tunnel ftp connections over ssh.

Chapter 4. Common Running problems

1. ProFTPD doesn't seem to work.
2. "inet_create_connection() failed: Operation not permitted".
3. Unable to bind to port/Address already in use
4. "Fatal: Socket operation on non-socket"
5. "Fatal: unable to determine IP address of "hostname:
6. I'm having problems with FTP clients behind firewalls
7. Can I run more that one VirtualHost on a single IP?
8. How do I run ProFTPD from inetd?
9. Can I use tcp-wrappers with ProFTPD?
10. Can I run an FTP server on a non-standard port?
11. Can control upload/download ratios?
12. Slow logins
13. Lots of "FTP session closed" messages
14. How do I see who is connected?
15. Can I force ProFTPD to listen on only one IP?
16. "FTP server shut down ... please try again later."
17. How do I shutdown the server without killing proftpd?
18. Is is possible to shutdown a single VirtualHost?
19. Error 421
20. proftpd doesn't show in the processlist
21. How do I restart/reload the server?
22. 503 No PORT command issued
23. Fatal: unable to determine IP address of
24. 451 append/restart not permitted, try again
25. 501 REST not compatible with server configuration
26. The time being displayed is wrong
27. Authentication is taking too long
28. Corrupted files
29. Can I upgrade ProFTPD without terminating the current sessions?
30. No such group "nogroup"
31. Why do I see "unable to set groups: Invalid argument"?
32. Why do I see error messages like these when I logout?

The setting of the group privileges for a process uses the setgroups(2) system call. This call will fail with the above error message for one of two reasons: there is a negative GID value for one of the groups, or the maximum number of groups for a single user has been exceeded.

Ideally, all IDs, both UID and GID, will be positive. Unfortunately, it is common on many systems to use -1 or -2, especially for such users as 'nobody', or group 'nogroup'. Use of these values uses C's treatment of data types to make the actual numeric value very high; some functions, like setgroups(), do not like this, though. In general, always use positive ID numbers.

The other limitation is the number of supplemental groups for a user (eg non-primary groups, the ones configured in /etc/group). The maximum number of supplemental groups to which a user may belong is defined by the operating system constant NGROUPS_MAX. On some operating systems, such as Solaris, this limitation may be tunable.

Some other applications may not encounter this error if they use the initgroups(3) function, which reads the /etc/group file for a user's supplemental group memberships, and sets those groups. This function, however, silently ignores any supplemental groups for user greater than NGROUPS_MAX, unlike setgroups(2), which complains.

If this is the cause of your error message, any solution will most likely involve reducing the number of groups your users are members of, or tuning the NGROUPS_MAX value, if your operating system allows it.

Chapter 5. Configuration problems

1. How do I add another anonymous login or guest account?
2. How do I ftp as root?
3. How do I provide a secure upload facility?
4. How can I stop my users from using their space as a warez repository
5. Can I rotate files out of an upload directory after upload?
6. How can I hide a directory from anonymous clients.
7. File/Directory hiding isn't working for me!
8. I want to prevent users from accessing a hidden directory
9. How do I setup a virtual FTP server?
10. I only want to allow anonymous access to a virtual server.
11. How does <Limit LOGIN> work, and where should I use it?
12. How can I limit users to a particular directory tree?
13. How do I create individual anonymous FTP sites for my users?
14. I want to support normal login and Anonymous under a particular user
15. Why doesn't Anonymous ftp work (550 login incorrect)?
16. Bandwidth control
17. CHMOD isn't working
18. How can I limit the size of uploaded files?
19. Can I disable Anonymous logins?
20. Limiting the connections per loginID
21. How do I configure proftpd to allow transfer resumption (for downloads and uploads)?
22. When should the Bind directive be used?

Problems encountered in trying to make the server behave exactly as required after compilation and installation are complete and the server is running.

The <LOGIN> directive is used to control connection or login access to a particular context (the directive block which contains it). When a client initially connects to ProFTPD, the daemon searches the configuration tree for <Limit LOGIN> directives, and attached parameters (such as Allow, Deny, etc). If it determines that there is no possible way for the client to ever be allowed to login, such as a "Deny from" matching the client's source address, without an overriding "Allow from" at a lower level, the client is disconnected without being offered the opportunity to transmit a user and password.

However, if it is possible for the client to be allowed a login, ProFTPD continues as per normal, allowing the client to login only if the proper <Limit LOGIN> applies. Normally, <Limit> directive blocks are allowed in the server config, <VirtualHost>, <Anonymous> and <Directory> contexts. However, <Limit LOGIN> should not be used in a <Directory> context, as clients do not connect/login to a directory (and thus it is meaningless).

By way of example, the following configuration snippet illustrates a <Limit LOGIN> deny which will cause any incoming connections from the 10.1.1.x subnet to be immediately disconnected, without a welcome message:

<Limit LOGIN>
Order deny,allow
Deny from 10.1.1.
Allow from all

Next, an example of a configuration using <Limit LOGIN> that will not immediately disconnect an incoming client, but will return "Login invalid" for all login attempts except anonymous.

<Limit LOGIN>
<Anonymous ~ftp>
<Limit LOGIN>

For general open access you can use an <Anonymous> directive context block, possibly in combination with a UserPassword/AnonRequirePassword directive.

However if you wish to jail an entire group (or groups) of users, you can use the DefaultRoot directive. DefaultRoot lets you specify a root jailed directory (or "~" for the user's home directory), and an optional group-expression argument which can be used to control which groups of users the jail will be applied to. For example:

DefaultRoot ~

This creates a configuration where all users who log into are jailed into their home directories (cannot chdir into a higher level directory). Alternatively, you could:

DefaultRoot /u2/public users,!staff

In this example, all users who are members of group "users", but not members of group "staff" are jailed into /u2/public. If a user does not meet the group-expression requirements, they login as per normal (not jailed, default directory is their home). You can use multiple DefaultRoot directives to create multiple jails inside the same directive context. If two DefaultRoot directives apply to the same user, ProFTPD arbitrarily chooses one (based on how the configuration file was parsed).

Security Implications

The DefaultRoot directive is implemented using the chroot(2) system call. This moves the "/" (or root) directory to a specified point within the file system and jails the user into this sub-tree. However this is not the holy grail of security, a chroot jail can be broken, it is not a trivial matter but it's nowhere near impossible. DefaultRoot should be used as part of a general system of security not the only security measure.

A more detailed on this subject and on the breaking of chroot jails has been written by Simon Burr

Non-root server issues

The chroot() system call will not work under a non-root ftp server process, the call requires root privaliges. Without them it simply doesn't work, there doesn't appear to be any checking in the code of the uid/gid before calling chroot so using DefaultRoot in such a setup will cause the server to fail.


Symlinks will not work from within a chrooted area. The reason should be clear from a casual inspection of the nature of the chroot command. It is not possible to have a symbolic link to a directory which can"t be reached beacuse it's outside of the current chroot. Work arounds to allow access to other parts of the file system include exporting the part of the filesystem to be accessed from inside the chroot and mounting via NFS, using hard file links or (on Solaris) using lofs to mount the directory via the loopback.

mount -Flofs /home/data1 /ftp/data1
mount -Flofs /home/data2 /ftp/data2

As of the 2.4.x Linux kernel tree it is possible to mount filesystems multiple times and to mount subdirectories of filesystems elsewhere on the filesystem.

There are two methods of accomplishing this (possibly more). First, you can create a directory structure inside your anonymous FTP root directory, creating a single directory for each user and setting ownership/permissions as appropriate. Then, either create a symlink from each user's home directory into the FTP site, or instruct your users on how to access their directory.

The alternate method (and more versatile) of accomplishing per-user anonymous FTP is to use AnonymousGroup in combination with the DefaultRoot directory. You'll probably want to do this inside a <VirtualHost>, otherwise none of your users will be able to access your system without being stuck inside their per-user FTP site. Additionally, you'll want to use a deferred <Directory> block to carefully limit outside access to each user's site.

  1. Create a new unix group on your system named `anonftp". Please each user who will have per-user anonymous FTP in this group.

  2. Create an `anon-ftp" and `anon-ftp/incoming" directory in each user's home directory.

  3. Modify your /etc/proftpd.conf file to look something like this (you'll probably want to customize this to your needs):

     # the next line limits all logins to this virtual host, so that only
     anonftp users can connect
     <Limit LOGIN>
     DenyGroup !anonftp
     # limit access to each user's anon-ftp directory, we want read-only
     except on incoming
     <Directory ~/anon-ftp>
     <Limit WRITE>
     # permit stor access to each user's anon-ftp/incoming directory,
     but deny everything else
     <Directory ~/anon-ftp/incoming>
     <Limit STOR>
     <Limit READ WRITE>
     # provide a default root for all logins to this virtual host.
     DefaultRoot ~/anon-ftp
     # Finally, force all logins to be anonymous for the anonftp group
     AnonymousGroup anonftp

Chapter 6. Security

1. General
2. Surely running ProFTPD as non-root will help?
3. How can I control what commands the server accepts?
4. How can I prevent the server version from being displayed?
5. I want to show a message prior to login
6. I want to display a message after login
7. Can I have a custom welcome response?
8. External Programs
9. Why do I see "No certificates found!"?

As with all software there have been a number of security issues during the life of the project. The most recent information can always be found on

Versions 1.2.0 and above should be considered to be production code and few if any new features will be added to this code branch to maintain stability.

What about using Stackguard?

Stackguard ( is a gcc variant which can protect programs from stack-smashing attacks, programs compiled using Stackguard dies without executing the stack code. While this approach is a good first line of defense against future problems it"s not a complete cure-all. Some of the buffer overflows were found on static variables, which are not protected by stack protection mechanisms.

Chapter 7. User Authentication

1. Why is PAM the default authentication system?
2. Authentication methods supported
3. Problems with non-PAM authentication
4. AuthPAMAuthorative is an unknown directive!
5. Configuring PAM
6. pam_sm_open_session errors
7. Normal users can't login, only anon.
8. AuthPAMAuthoritative
10. Encrypted passwords
11. SecureID
12. One time passwords
14. Anonymous password checking
15. Why do I see "PAM(name): Authentication failure", but I can login anyway?

This section is being re-written due to major structural changes to the SQL module prior to 1.2.0

mod_ldap is currently stable; there were a couple bugs that were squashed after release 1.0 of the module. it is still udner development , check the for more information. There is an example config fragment on the author's site which gives a reasonable idea on how to use this module.

Chapter 8. FAQ Notes