The current version of the File Transfer Protocol (FTP)
in RFC 959, October 1985. Its purpose is to reliably
between computing systems independent of the operating
FTP uses a client-server model. The server side is implemented
a daemon called ftpd or in.ftpd. The client side is
implemented with a program called ftp. Figure 1 shows
model of FTP.
The client starts the session by opening a control connection
the server, sending the request to port 21/tcp. The
client sends its
port number, and network address in the connection request.
is not available at the network address, the transport
a "connection refused message." If the request
for a control
connection is accepted, the ftp server sends back a
code 220, saying that the server is ready, start the
The reply code is a three-character digit code followed
by a text
string. The text string is for human use and is not
fixed by the protocol.
The digit code is used by the client process and is
fixed by the FTP
protocol. The first digit tells whether the reply is
positive or negative.
The second digit tells the reply's category. The third
digit, if not
0, is a gradation of the reply. See Figure 2 for the
meanings of the
first two digits.
Once authentication is done and a confirming reply is
client issues commands, and the server responds with
replies on the
control connection. RFC 959 contains a list of all client
and server replies. I found that only a subset of the
under the FTP protocol are implemented.
If there is data to transfer, the server opens and manages
a new connection
to transfer the data. It uses port 20/tcp on its side
of the connection.
By default the client's control port and network address
other half of the connection. The client can specify
and network address by using the PORT command.
This paper reports on an exploration of the server side
of the FTP
protocol. I used three versions of UNIX: System V/386
from Interactive (SVR3), System V Release 4.0 from Dell
Sun 4.1.3 from Sun Microsystem (SunOS).
On all three operating systems, ftpd does not listen
requests. Instead inetd is configured to listen for
inetd executes ftpd once for each request received.
If inetd is not listening for requests, when an ftp
request comes in, the client receives a "connection
message from the transport provider.
I tried to run ftpd as a standalone program, mostly
what would happen because the program is designed to
work under inetd.
I removed ftpd from inetd.conf. I logged in as root
and started the ftpd program. In each case the program
executing with an error message showing there was a
problem with its
access to the network.
The last field of inetd.conf mimics starting the program
the command line. This allows the specification of options
program. ftpd has three options: -d, logging debugging information to syslog.
The -t option identifies the number of seconds of inactivity
allowed before ftpd closes the session. Figure 3 shows
results of setting the -t option to 20 seconds on SVR4.
The 421 time out reply code does not show on the screen
command is issued. The default inactivity time is 900
minutes). The other systems' ftpds acted similarly.
The -T option of SVR3's ftp program allows a user
to override the -t option by specifying the timeout
this session. This has a maximum of two hours.
ftpd writes three levels of messages to the syslog
daemon facility. Figure 4 shows the levels and the types
The err level messages are always written. The info
level messages are written only if the -l option is
The debug level messages are written only if the -d
option is set. The syslog.conf file must be modified
messages or they are lost.
While testing for the -l options, I found that ftpd
writes login and logout information in the wtmp file.
this information is sufficient. On DELL's SVR4 the wtmp
have an error and cannot be read by who. Here I do use
The data available from ftpd's -d option is difficult
to correlate to the actions of the user of the ftp client.
The same data available from ftpd's -d option
is available from the client's ftp by using the verbose
and -d option. The sidebar "A Sample ftp Session
the -d Option" walks you through a session with
Configuration Files of ftpd
Basic access to ftpd requires a user to be listed in
/etc/passwd file and to have a password. Anonymous ftp
not require a valid password in /etc/passwd. The files
and /etc/shells modify the basic requirements.
The file /etc/ftpusers is a list of account names, one
per line, that
may not log into the system through ftp. I tried this
on all systems,
and it is true that you cannot login if your account
name is in the
file. However, this does not apply to anonymous ftp.
David A. Curry,
in UNIX System Security suggests:
As a minimum, the super-user, root, and any other
accounts with user id 0, should always be listed in
this file. System
accounts that do not normally have a human associated
with them, such
as bin, daemon, news, sync, sys, and
uucp, should usually be listed as well. (page 70)
For SVR3, the file /etc/shells determines which additional
shells are allowed over the standard shells: /bin/sh,
/bin/csh, /usr/bin/sh, /usr/bin/ksh, /usr/bin/csh.
The SVR4 /etc/shells file works slightly differently.
the file does not exist, then only the standard shells
ksh, and csh in /bin and /usr/bin
are allowed to login using ftp. If there is an /etc/shells
file, then only accounts with a listed shell can use
If the file is empty, then no one can use ftp.
SunOS's /etc/shells file works similarly to the SVR4's
that it uses a different list of default shells: sh
in the directories /bin and /usr/bin.
As a result of exploring the options and setup files
I do the following when setting up ftpd: First, I use
timeout option (-t) with a value of 300 seconds --
five minutes is a long time for no activity. Second,
I follow David
Curry's recommendations on /etc/ftpusers and place all
accounts and all accounts not associated with an individual
/etc/ftpusers. Third, I list all of the shells being
on the system in /etc/shells. I do not use the option
I only use the -l option on DELL's SVR4.
Configuring an Anonymous ftp
If the system administrator establishes an account named
ftpd will allow access to anyone who can ping the
system using the account name "ftp" or "anonymous."
Any set of characters works as the answer to the password
just pressing the enter key does not work. This access
method is generally
referred to as "anonymous ftp."
Each version of UNIX has a set of directions for setting
ftp. The emphasis here is on why the ftp account structure
certain directories and files, and on the tools available
the necessary directories and files.
The first step is to make sure your ftpd does not have
bugs. This means having the current version of the software.
that the only sure way to know what version of ftpd
used is to talk with the vendor.
In UNIX System Security, Curry talks about problems
of ftpd earlier than July 1989. Node agate.berkeley.edu
current version to be 5.4 (Berkeley) 7/2/91. CERT advisory
shows the current version from wuarchive.wustl.edu to
be 8 April 1993.
Versions of ftpd based on the BSD software are probably
if the version date is later than July 1989 and are
probably the latest
version if the version date is 2 July 1991 or later.
version date should be after 8 April 1993.
The second step is to create an account for the anonymous
structure, ownership, and permissions of the account
by three conditions. First, the account name must be
ftpd does chroot after accepting the password for
the ftp account. Third, placement of the home directory
by the use of the account.
An entry in /etc/passwd creates a new account. Figure
a summary of what is in the seven fields. The account
name must be
ftp. Since ftpd does not use the password entry, I usually
locked. The uid is any available user id. The group
can be a default
user's group. In the gcos field we place the words,
ftp login." The location of the home directory
can be any directory
(placement of the directory is discussed in the section
and uploading). The initial command field (shell) is
not used, but
I have seen the ftp program placed there. I tried /dev/null
and it worked just fine. I normally place a non-executing
The standard startup files are not necessary for this
user. To handle
mail that might come to this account, I add an entry
to the aliases
file, forwarding it to another user.
The chroot command accepts a pathname as its only parameter.
It changes the root directory (/), to this pathname.
Only a uid 0
account can execute this command. (Note: for chroot(2)
be effective, the program must then do a chdir(2) to
. will access the current local directory.)
After executing chroot, the kernel does not allow access
any file outside of the local hierarchy, does not allow
outside of the local hierarchy, and does not allow symbolic
outside of the local hierarchy. Thus, a limited file
must be built under the ftp account's home directory,
the new /, to
contain the files ftpd needs. The chroot command is
executed as part of accepting the password. chroot restrictions
are in force when the 230 reply code (230 "Guest
login ok, access
restrictions apply.") is displayed.
The ftpd needs access to the ls command after the
chroot to comply with the ftp protocol commands LIST
and NLIST. The ls command is usually stored under
/bin and /usr/bin. On all systems I looked at, the
150 reply code to an ftp dir or ftp ls command
shows the path to the command being executed by ftpd.
The reply shows ftpd using the ls in /bin.
The limited hierarchy needs the directory ~ftp/bin to
a copy of the ls command. The permissions on the command
should be 111 since ftpd needs only to execute the command.
The ls command depends on accessing dynamic libraries
some of its subroutines. In SVR4 and SunOS, the command
lists the dynamic libraries used by a command. SVR3
does not have
the ldd command; the command dump with the -Lv
options gives the same information. The dump command
available on SVR4. Figure 6 shows the results on the
The libraries are stored in /usr/lib on SVR4 and SunOS.
these systems, the ftp account needs the directory ~ftp/usr/lib
with copies of the libraries. On SVR3 the library directory
Here the ftp account needs the directory ~ftp/shlib
copy of the library. All of the ls accessed libraries
needed since ls is accessed after the chroot. The
libraries need the same protection as in the normal
permissions are 555.
The command lld or dump must be run on the ftpd
command since ftpd may access libraries after the chroot.
Figure 6 shows the results on the diffent systems. I
tested each library
to see if it was needed. SVR3 is easy since both ftpd
ls need the same libraries. SVR4 shows that ftpd needs
two additional libraries besides the one needed by ls.
shows neither library is needed. Under SunOS, a quick
accessing anonymous ftp without the library and with
the library shows
ftpd needs the /usr/lib/libdl.so.1.0 and /usr/lib/libc.so.1.8
libraries. SunOS also needs the file /usr/lib/ld.so,
loader. This file is needed anytime a dynamic library
is used. When
I leave it out, the error message shows this file is
For the ls command to display the correct information
to access the files /etc/passwd and /etc/group. Strip
these files of all entries that are not needed. The
file shows only the owners of files and directories.
file shows only those groups associated with files and
In fact, the entries can be entirely bogus so long as
the uids and
gids match those in the ~ftp hierarchy. The files are
stored in ~ftp/etc.
The files need the same protection they have in the
permissions are 444.
Commands may access a device file during their execution.
the command trace shows all system calls and signals
command given as a parameter. grepping for /dev shows
a superset of the devices needed. On SVR4 the output
of the command
truss, trace system calls and signals, can be greped
for /dev to find all of the possible device files. On
neither trace nor truss exists, so I used strings,
grepping for /dev. Figure 7 shows that the ls
command accesses no device files in SVR3. Experimentation
only device file necessary in ~ftp/dev of all those
by the strings command is tcp.
grepping the SVR4 truss files for /dev, as
shown in Figure 8, and doing some experimentation shows
needs /dev/zero and ftpd needs /dev/zero and /dev/tcp.
The /dev/tcp is a STREAMS device file accessed whenever
tcp port is opened. In STREAMS on SVR4, multiple transport
mechanisms are possible. The file /etc/netconfig contains
information on available transport mechanisms. It is
a STREAMS device is used to find the underlying transport
Thus, the file must be available in ~ftp/etc.
grepping the SunOS trace files for /dev, as
in Figure 9, shows ls needs the device /dev/zero and
ftpd needs /dev/zero and /dev/null. Experimenting
shows the /dev/null driver is not needed.
The device files cannot be copied into ~ftp/dev. The
system entries must be made with the program mknod,
makes a special file using the same major and minor
numbers for the
corresponding device files in /dev. To find the major
minor numbers, do an ls -l on the device in /dev.
If ls is derived from SVR3 or SVR4, then the major and
numbers are the 5th and 6th fields of the output. If
derived from a BSD-based system, then the major and
are the 4th and 5th fields of the output.
Figure 10 summarizes the directories, files, and their
needed in the ~ftp hierarchy. (Traditionally, there
is one more directory.
I discuss it in the Uploading and Downloading Directories
One question not decided is who should own the ~ftp
in Anonymous FTP Configuration Guidelines recommends
that the ftp
account's home directory and the subdirectories not
be owned by ftp.
This prevents anyone from making changes to the ~ftp
recommending, CERT states that for most systems root
as the owner of the directories in the hierarchy, and
to root's group is good for the group of the hierarchy
Downloading and Uploading Directories
One more directory, ~ftp/pub, is traditionally added.
If the server will allow only downloading then the permissions
the directory are 755. It's under this directory that
you should build
the hierarchy used to hold the files clients are allowed
If uploading is allowed, create a directory, ~ftp/incoming,
with the permissions set to 777 to allow anyone to create
the directory. This opens up ftp to some abuses. Placing
in its own partition or, if possible, limiting the space
for the directory allows you to protect the system from
some of the
CERT, in Anonymous FTP Configuration Guidelines, suggests
of hidden directories to limit access to uploading.
To implement this,
first change the permissions on ~ftp/incoming to 751.
allows the anonymous ftp user to change to the directory
but not to
list the contents of the directory. Second, create directory
using the same rules as making good password names.
Give these subdirectories
to ~ftp/incoming permissions 777. Now anyone knowing
name can upload to the known directory. The security
of this system
is only as good as the password-directory names.
Generally, I follow the directions given in the ftpd
for setting up anonymous ftp. I modify the directions
to follow CERT's
suggestion on ownership of the files and directories.
each system I explored, I found I needed to use ldd
-Lv, and trace, truss, or strings to
find missing data.
RFC 959. J. Postel and J. Reynolds, October 1985.
Available by anonymous ftp from host nic.ddn.mil, directory
UNIX System Laboratories. User's Reference Manual/System
Administrator's Reference Manual for Intel Processors.
Hall, 1992. ISBN 0-13- 951310-8.
SunOS Reference Manual. Part Number:800-3827-10,
Revision A of 27 March 1990.
Anonymous FTP Configuration Guidelines. CERT.
Available by anonymous ftp from host cert.org, directory
Curry, David A. UNIX System Security. Addison-Wesley,
1993. ISBN 0-201- 56327-4.
About the Author
Arthur Messenger returned from the Air Force, where
he worked on numerious computer systems, in 1988.
Since then, he has been doing teaching and consulting.
His current interest is in UNIX and Network management.
He can be reached at email@example.com.