ProFTP is an FTP server. ProFTP had already been installed on my system (as a part of Plesk), and it turned out to be easily configurable.

Installing ProFTP

On another system, I had to install ProFTP myself. Using apt-get (on Debian, or any Debian derived Linux distribution), it's very easy:

apt-get install proftpd

But when the system tries to start proftpd, an error message pops up:

ProFTPd warning: cannot start neither in standalone nor in inetd/xinetd mode. Check your configuration.

This too is easily fixed. Edit your /etc/proftpd.conf file. If there is a line:

ServerType			inetd

Change it into:

ServerType			standalone

Configuring ProFTP

I have made a few minor changes to /etc/proftpd.conf, which is where most of the configuration seems to take place. DefaultRoot can also be set through the Webmin module for ProFTP. This directive specifies where ftp users can go in the directory tree.

The ~ sign means that ftp users are restricted to their home directory, so applying the directive:

DefaultRoot ~/public_html

- means: you can only move around in (for instance) /home/campinglachassagne/public_html.

[root@1038 /]# cat /etc/proftpd.conf
# To have more informations about Proftpd configuration
# look at :
# This is a basic ProFTPD configuration file (rename it to
# 'proftpd.conf' for actual use.  It establishes a single server
# and a single anonymous login.  It assumes that you have a user/group
# "nobody" and "ftp" for normal operation and anon.
ServerName                      "FTPServer"
ServerType      inetd
ServerType      inetd
DefaultServer                   on
DefaultRoot ~/public_html
AllowOverwrite          on
TransferLog NONE
DefaultTransferMode     binary
UseFtpUsers                     on
# Port 21 is the standard FTP port.
Port                            21
# Umask 022 is a good standard umask to prevent new dirs and files
# from being group and world writable.
Umask                           022
# To prevent DoS attacks, set the maximum number of child processes
# to 30.  If you need to allow more than 30 concurrent connections
# at once, simply increase this value.  Note that this ONLY works
# in standalone mode, in inetd mode you should use an inetd server
# that allows you to limit maximum number of processes per service
# (such as xinetd)
MaxInstances                    30
#Include directive should point to place where FTP Virtual Hosts configurations
ScoreboardFile /var/run/proftpd/scoreboard
# Primary log file must be outside of system logrotate province
# 20050110 Changed (O.S.), and directory chowned to nobody
TransferLog /usr/local/proftp
#Change default group for new files and directories in vhosts dir to psacln
#20050110 Changed to default None (O.S.)
<Directory /home/httpd/vhosts>
        GroupOwner      None
Include /etc/proftpd.include

I have also added an A-record to the remote nameserver (hostbasket's) for my experimental website,

Testing ProFTPD

To test the ftp server, just add a new user and give him a /bin/sh shell. Now try to log in with this new user through ftp. See if there are any errors in var/log/messages, but don't be put off by a message such as this:

PAM(theuser): Authentication failure.

If you can still log in, then ignore this message. If you cannot log in, try to take a look at the authentication method being used by your system. ProFTPD just piggybacks on this system. See the chapter User Authentication of the ProFTPD documentation.

Adding a new FTP user (20050406)

Usually, everybody uses the same supersecret FTP-account for their website. But sometimes you need a special place for exchanging special files. This is when you add a new FTP user. The easiest thing to do is to add the user to an existing webdomain.

  1. Use Virtualmin > mail users to add a user. Set the radio button
FTP login enabled?
  • to “yes”.

Now, if you take a look at the current ProFTPD configuration (/etc/proftpd.conf), you'll see:

Limit users to directories:  ~/public_html

This line may appear within the context of a virtual host, but also anywhere else in the configuration file.

As stated above, it means that users cannot fool around in any other directory (except of course child directories). Unfortunately, our new user does not have a public_html directory inside his home directory. So:

  • Make a public_html directory inside the new user's home directory (and set the access rights with chown and chmod).

Finally, please make sure that your new user has the right shell (usually /bin/false), or set proftpd to: RequireValidShell off. If you set the shell to bin/false, be sure to add the shell to the /etc/shells file:

# cat >> /etc/shells

(End line input with ctrl-d)

Securing ftp access to a domain by limiting access to certain ip addresses only

You do this by using the <Limit LOGIN> directive inside the <VirtualHost> directive. Example:

<Limit LOGIN>
	Order Allow,Deny
	Deny from all

Do not use <Limit LOGIN> inside a <Directory> directive, as this does NOT work!

You can also specify an ip range:

Allow from 128.44.26.,128.44.26.,,

Providing access to the web directory (web root) for an FTP user

The problem

Normally, you have one ftp-user for each domain. This user is the administrator for the domain (so, has a Unix user called 'dopperdude', who is also the ftp-user for this domain).

Fine, but what if you have subdomains and you want to provide access to the web root of each subdomain to different users?

Of course, you start by adding a new user, as described above. But now you have a user who can access his home directory, which is definitely not the same directory as the web root of his subdomain. So, you say, I just create a symlink (symbolic link) in the user's home directory, pointing to the correct web root.

Well, ProFTP does not allow you to use symlinks. From the documentation:

“when chroot(2) is used (which is what the DefaultRoot directive does), symlinks that point outside the new root (the user's home directory in this case) will not work.” Oops.

The solution

Again from the documentation: “To get around this apparent limitation, it is possible on modern operating systems to mount directories at several locations in the filesystem.”

“To have an exact duplicate of the /var/ftp/incoming directory available in /home/bob/incoming and /home/dave/incoming, use these commands:”

mount --bind /var/ftp/incoming /home/bob/incoming
mount --bind /var/ftp/incoming /home/dave/incoming

Here is my own example (which I have really used):

mount --bind /home/solin/domains/ /home/solin/domains/

These bindings will not survive a system reboot, however, so go to the “Bootup and Shutdown” section of Webmin, and create a new bootup action. The name of the action must not contain any spaces. The contents of the action are of course the mount command.

Also, do not forget to give the user proper access to the public_html directory. Example:

chown -R nobody:solin public_html

Support Passive Mode to Prevent Timeouts 20060415

The FTP server has never been running smoothly. From time to time, users have been complaining about lags and timeouts.

I decided it was time to finally lend an ear to the FTP users. What was it that slowed down their FTP client's connection to the FTP server?

Eliminating Time Consuming Factors

I first came across a number of time consuming actions that were performed during the initialization of each ftp session. See:


I have now turned these off in /etc/proftpd.conf:

tcpNoDelay off
IdentLookups off
UseReverseDNS off 

This did not seem to solve the slow connection problems, however.

Firewall issues for passive mode clients

Most modern FTP clients try to initiate an ftp session in passive mode. This did not go well with my ProFTP configuration. In fact, when I explicitly told my ftp client (SmartFTP) to start in Active mode, all connection problems disappeared.

But of course, you want your users to be able to use passive mode. To support this on the Server side, you need to configure not only ProFTP, but also the firewall. This is documented here:

and here:

In my case, I want to allow for fifty simultaneous ftp connections. So on the firewall, I have set (through Webmin) the following port range:

Accept If protocol is TCP and destination port is 8000:8050

Then ProFTP:

PassivePorts 8000 8050

This was enough to make SmartFTP happily start in passive mode, without any connection problems.

Personal Tools