Jan 262000

installing an alternative ftp daemon – proftpd

I decided to install another ftp server.  Mainly because I was having a small problem with the default ftp server which I didn’t want to spend the time fixing.   The problem was with chroot.  If I placed a user in /etc/ftpchroot, they were unable to use the ls command.  I understand this is because the ls executable must be placed within the chroot tree.  That makes sense.  However, I didn’t want to do that.  I also liked the idea that proftpd does not depend upon any external executables.  It is entirely independent.

See also Creating a chroot ftpd.

Another selling point for me, with respect to proftpd, was the apache-like configuration.  If you are familiar with the httpd.conf, the proftp.conf file concepts will be easy for you to pick up.

home page   http://www.proftpd.org/ mailing list archives   http://www.proftpd.org/proftpd-l-archive/ FAQ   http://hamster.wibble.org/proftpd

The Install

And since I have the entire ports tree, all I needed to do was:
# cd /usr/ports/ftp/proftpd
su: cd: /usr/ports/ftp/proftpd: No such file or directory

Oh oh!  Why don’t I have that?  I checked the http://www.freebsd.org/ports/ page to see if proftpd was listed in the ftp section.  It was.  So my ports were out of date.   Time to fix that.  It was pretty easy.  I used the instructions found in Updating the ports collection.  When doing this, I could have modified my ports-supfile and commented out everything except the ftp section.  But I didn’t.  I wanted all my ports updated.

So I started again:

# cd /usr/ports/ftp/proftpd
# make

Again, I started getting errors.  This time it was complaining about not being able to get autoconf-2.12.tar.gz I think.  Hmmm, where does that live?  A quick:

# locate autoconf

shows it’s from /usr/ports/devel/.  A quick check again at http://www.freebsd.org/ports/ finds that the current version is 2.13. So my ports are out of date.  I had not been updating the devel directory.  So I uncommented that line from the ports-supfile and ran cvsup again.  After that, I started with the install again:

# make
# make install

Of note was this output from the install:

===>  Installing for proftpd-1.2.0p8
As of proftpd 1.2.0p5 and later, you need to edit /etc/pam.conf to add
support for ftp.  To do so, add the following two lines to this file:

ftp auth    required    pam_unix.so         try_first_pass
ftp account required    pam_unix.so         try_first_pass
===>   Generating temporary packing list
===>   Compressing manual pages for proftpd-1.2.0p8
===>   Registering installation for proftpd-1.2.0p8

I’m not sure if this will be relevant or not.  It turned out it was.


The main configuration file is /usr/local/etc/proftpd.conf.

I was running this daemon standalone.  That’s the default configuration.  So I commented out the line in /etc/inetd.conf for ftp.  Don’t forget to HUP inetd (like I did):

# killall -HUP inetd

After making changes to the config file so as to enable anonymous ftp (see config file and below), I started the server:

# /usr/local/libexec/proftpd

Then I checked to see if it was running:

# ps -auwx | grep ftp

Hmmm, there’s nothing there.  Time to check for error messages:

# tail /var/log/messages
Nov 10 23:14:20 ducky proftpd[17601]: attempted bind to, port 21
Nov 10 23:14:20 ducky proftpd[17601]: bind() failed in
                inet_create_connection(): Address already in use
Nov 10 23:14:20 ducky proftpd[17601]: Check the ServerType directive to
                    ensure you are configured correctly.

DOH!  I forgot to HUP inetd.

# killall -hup inetd
# /usr/local/libexec/proftpd
# tail /var/log/messages
Nov 10 23:18:20 ducky proftpd[17640]: ProFTPD 1.2.0pre8 
                                               standalone mode STARTUP 

OK.  That’s looking much better!

Testing it

With my initial testing, I was unable to connect with any user/password combination. Most annoying.  Checking the messages again, I find this:
Nov 10 23:25:35 ducky proftpd[17681]: USER dan: incorrect password from
           fred.yourdomain.org [] to

Hmmm, but my password is correct.  I dunno.  But anonymous ftp is working.

Eventually I remembered the bit about PAM from the install process and added those bits to the PAM configuration file.  But that didn’t fix it either.  At this point, I went to bed.

The problem was PAM

After posting a message to the freebsd-questions@freebsd.org I found the solution.  It appears that my version of FreeBSD  does not support PAM.   What’s PAM you say?  If you check /etc/pam.conf, you’ll see this: Pluggable Authentication Modules.  And from man pam:
PAM  Is  a system of libraries that handle the authentica-
tion tasks of applications (services) on the system.   The
library  provides  a stable general interface (Application
Programming Interface - API) that privilege granting  pro-
grams  (such  as  login(1)  and su(1)) defer to to perform
standard authentication tasks.

The solution was found at http://hamster.wibble.org/proftpd/ and it involves adding the following line to /usr/local/etc/proftpd.conf:

AuthPAMAuthoritative            off

Note: FreeBSD 3.3 does support PAM.  I know because that was the version I used when Installing an ftp server.  And there I also used proftpd.


The first thing you might want to do is add an anonymous ftp user.  Look at http://hamster.wibble.org/proftpd/ for the configuration options.  Here is more or less my anonymous settings:
<Anonymous ~ftp>
  DirFakeUser                   on ftpd
  DirFakeGroup                  on ftpd

  User                          ftp
  Group                         ftp
  ### We want clients to be able to login with "anonymous" as well as "ftp"
  UserAlias                     anonymous ftp

  ### Limit the maximum number of anonymous logins
  MaxClients                    10

  ### It is wise when making an 'ftp' user that you either block its
  ### ability to login either via /etc/login.access or my giving it
  ### an invalid shell.
  ### Uncomment this if the 'ftp' user you made has an invalid shell

  RequireValidShell             off

  ### We want 'welcome.msg' displayed at login, and '.message' displayed
  ### in each newly chdired directory.
  DisplayLogin                  welcome.msg
  DisplayFirstChdir             .message

  ### Limit WRITE everywhere in the anonymous chroot
  <Limit WRITE>

  <Directory incoming/*>

     <Limit WRITE CWD>

  <Directory bin>

Virtual servers

One of the  things which proftpd does, as do other daemons, is allow you to have virtual ftp servers.  Much like virtual websites in apache, it allows a single host to respond with different files for different server names.  See virtual ftp servers – proftpd for more detail.

Starting proftpd

I wanted to ensure that proftpd started at boot time.  So I created this file
# cat /usr/local/etc/rc.d/proftpd.sh
/bin/mkdir -p /var/run/proftpd
if [ -x /usr/local/libexec/proftpd ]; then
/usr/local/libexec/proftpd && echo -n ' proftpd'

Remember to set the permissions correctly or it won’t be executed:

chmod 711 proftpd.sh

Non-anonymous users

Here is a non-anonymous user.  It assumes you have a user and group called Susan.  Uploads will be done in the user’s home directory.
<Anonymous ~susan>
   user                  susan
   group                 susan

   AnonRequirePassword   on

Common shell problem

The login I created for Susan was an ftp-only login.  She is not allowed to use telnet or ssh.  Therefore, when I created her, I assigned a shell of /nonexistent.   But when I tested the connection I encountered a slight problem:
$ ftp ftp.mydomain.org
Connected to ftp.mydomain.org.
220 ftp.mydomain.org
Name (ftp.mydomain.org:dan): susan
331 Password required for susan.
530 Login incorrect.
ftp: Login failed.

In the logs for ftp.mydomain.org I found this

- USER susan (Login failed): Invalid shell.

There are two problems here. First, I gave Susan a login shell of /nonexistent.   Second, this shell is not listed within /etc/shells.  It is the latter issue which results in the above error message.  For more information about nologin, please see this article.

To correct this problem, I changed Susan’s login shell to /sbin/nologin after first ensuring this shell existed:

# ls -l /sbin/nologin
-r-xr-xr-x  1 root  wheel  1990 Dec  6 05:57 /sbin/nologin

And here is what was in /etc/shells after I added the /sbin/nologin entry.

# $FreeBSD: src/etc/shells,v 1999/08/29 14:19:02 peter Exp $
# List of acceptable shells for chpass(1).
# Ftpd will not allow users to connect who are not using
# one of these shells.


After fixing the above, I found that Susan’s login worked and resulted in the following log entry:

ANON susan: Login successful.