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.
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.
# 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.
Configuration
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 0.0.0.0, 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.
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 [10.0.0.1] to 10.0.0.2:21
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 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>
DenyAll
</Limit>
<Directory incoming/*>
<Limit READ DELE RMD RETR MKD>
DenyAll
</Limit>
<Limit WRITE CWD>
AllowAll
</Limit>
</Directory>
<Directory bin>
HideNoAccess
</Directory>
</Anonymous>
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/sh
/bin/mkdir -p /var/run/proftpd
if [ -x /usr/local/libexec/proftpd ]; then
/usr/local/libexec/proftpd && echo -n ' proftpd'
fi
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
</Anonymous>
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.
Password:
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 1.2.2.1 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.
/bin/sh
/bin/csh
/usr/local/bin/bash
/sbin/nologin
After fixing the above, I found that Susan's login worked and resulted in the following
log entry: