- Professional FTP Daemon -


Configuration - Frequently Asked Questions
ProFTPD doesn't seem to work, I start it but it doesn't show up in a `ps'. What's wrong?
It could be many things, possibly something like not running proftpd as root (it needs to be run as root initially, but will switch to a non-privileged user). Regardless, proftpd logs all errors via the standard syslog mechanism. You need to check your system logs in order to determine what the problem is.
   
My syslog has errors in it such as "inet_create_connection() failed: Operation not permitted".
I use the shadow password suite. Users cannot login to ProFTPD.
You aren't starting proftpd as root, or you have inetd configured to run proftpd as a user other than root. The proftpd daemon must be started as root in order to bind to tcp ports lower than 1024, or to open your shadow password file when authenticating users. The daemon switches uid/gids to the user and group specified by the User/Group directives during normal operation, so a `ps' will show it running as the user you specified.
   
What should I add or remove from my /etc/inetd.conf in order to run proftpd from the inetd super-server?
Find the line in /etc/inetd.conf that looks something like this:
ftp stream tcp nowait root in.ftpd in.ftpd

Replace it with:
ftp stream tcp nowait root in.proftpd in.proftpd

Then, find your inetd process in the process listing and send it the SIGHUP signal so that it will rehash and reconfigure itself. Example (do not type the following literally, as pid 189 will most likely NOT be your inetd process):
kill -1 189
   
Can I use tcp-wrappers with proftpd?
Sure. Although ProFTPD has built-in IP access control (see the Deny and Allow directives), many admins choose to consolidate IP access control in one place via in.tcpd. Just configure proftpd to run from inetd as any other tcp-wrapper wrapped daemon does:
ftp stream tcp nowait root in.tcpd in.proftpd
   
How do I add another anonymous login or guest account?
You should look in the sample-configurations/ directory from your distribution tarball. Basically, you'll need to create another user on your system for the guest/anonymous ftp login. For security reasons, it's very important that you make sure the user account either has a password or has an "unmatchable" password. The root directory of the guest/anonymous account doesn't have to be the user's directory, but it makes sense to do so. After you have created the account, put something like the following in your /etc/proftpd.conf file (assuming the new user/group name is private/private):

<Anonymous ~private>
AnonRequirePassword off
User private
Group private
RequireValidShell off
<Directory *>
<Limit WRITE>
DenyAll
</Limit>
</Directory>
</Anonymous>


This will allow ftp clients to login to your site with the username 'private' and their e-mail address as a password. You can change the AnonRequirePassword directive to "on" if you want clients to be forced to transmit the correct password for the 'private' account. This sample configuration allows clients to change into, list and read all directories, but denies write access of any kind.
   
How do I allow uploads to a specific directory in a secure fashion? I don't want users downloading or creating sub-directories in it.
The following snippet from a sample configuration file illustrates how to protect an "upload" directory in such a fashion (which is a very good idea if you don't want people using your site for "warez"):

<Anonymous /home/ftp>
User ftp
Group ftp
UserAlias anonymous ftp
<Directory *>
<Limit WRITE>
DenyAll
</Limit>
</Directory>
<Directory incoming>
<Limit STOR>
AllowAll
</Limit>
<Limit READ>
DenyAll
</Limit>
</Directory>
</Anonymous>

This denies all write operations to the anonymous root directory and sub-directories, except "incoming/" where the permissions are reversed and the client can store but not read. If you used <Limit WRITE> instead of <Limit STOR> on <Directory incoming>, ftp clients would be allowed to perform all write operations to the sub-dir, including deleting, renaming and creating directories.
   
How can I hide a directory from anonymous clients. I only want clients getting in to it if they know the exact name.
Use the HideUser or HideGroup directive in combination with the proper user/group ownership on the directive. For example, if you have the follow directory in your anonymous ftp directory tree:

drwxrwxr-x 3 ftp staff 6144 Apr 21 16:40 private

You can use a directive such as "HideGroup staff" to hide the private directory from a directory listing. Example:

<Anonymous ~ftp>
...
<Directory Private>
HideGroup staff
</Directory>
...
</Anonymous>
   
File/Directory hiding isn't working for me! I can still see the file or directory when performing an anonymous FTP?
You need to make sure that the group you are hiding isn't the anonymous ftp user's primary group, or HideGroup won't apply.
   
I have a hidden directory, but I want to prevent users from accessing it altogether. How can I do this?
You can either change the permissions on the directory to prevent the anonymous FTP user from accessing it, or if you want to make it appear completely invisible (as though there is no such directory), use the IgnoreHidden directive inside a <Limit> block for one or more commands that you want to completely ignore the hidden directory entries (ignore = act as if the directory entry does not exist).
   
How do I setup a virtual FTP server?
First off, have you read the documentation that came with the server? If not, do so now. If you still have questions, read on:

You'll need to configure your host to be able to handle multiple IP addresses. This is often called "aliasing", and can generally be configured through an IP alias or dummy interface. You need to read your operating system documentation to figure out how to do this. Once your have the host configured to accept the additional IP address that you wish to offer a virtual FTP server on, use the <VirtualHost> configuration directive to create the virtual server:

<VirtualHost 10.0.0.1>
ServerName "My virtual FTP server"
</VirtualHost>


You can add additional directive blocks into the <VirtualHost> block in order to create anonymous/guest logins and the like which are only available on the virtual host.
   
I don't want to let my normal FTP users into my virtual FTP servers using their usernames/passwords. I only want anonymous FTP to work for a virtual server. How can I do this?
Use a <Limit LOGIN> block to deny access at the top-level of the virtual host, then use <Limit LOGIN> again in your <Anonymous> block to allow access to the anonymous login. This permits logins to a virtual anonymous server, but denies to everything else. Example:

...
<VirtualHost 10.0.0.1>
ServerName "My virtual FTP server"
<Limit LOGIN>
DenyAll
</Limit>
<Anonymous /usr/local/private>
User private
Group private
<Limit LOGIN>
AllowAll
</Limit>
...
</Anonymous>
</VirtualHost>
   
Can I run an FTP server on another port besides the standard ftp port (21) without running a separate copy of ProFTPD?
Yes. Use a <VirtualHost> block with your machine's FQDN (Fully Qualified Domain Name) or IP address, and a Port directive inside the <VirtualHost> block. For example, if your host is named "myhost.mydomain.com" and you want to run an additional FTP server on port 2001, you would:

...
<VirtualHost myhost.mydomain.com>
Port 2001
...
</VirtualHost>
   
How does <Limit LOGIN> work, and where should I use it?
The <Limit 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 snippit 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
</Limit>
...


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>
DenyAll
</Limit>
<Anonymous ~ftp>
...
<Limit LOGIN>
AllowAll
</Limit>
...
   
How can I limit one or more user sessions to a particular directory tree? (chroot jail)
You can use an <Anonymous> directive context block, possibly in combination with a UserPassword/AnonRequirePassword directive. If you wish to jail an entire group (or groups) of users, you can use the DefaultRoot directive (available only in 0.99.0pl7 and above). 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:

...
<VirtualHost myhost.mynet.foo>
DefaultRoot ~
...
</VirtualHost>


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

...
<VirtualHost myhost.mynet.foo>
DefaultRoot /u2/public users,!staff
...
</VirtualHost>


In this sample, 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).