
Copyright (c) 1999,2000 WU-FTPD Development
Group.
All rights reserved.
Portions Copyright (c)
1980, 1985, 1988, 1989, 1990, 1991, 1993, 1994
The Regents of the University of California.
Portions Copyright (c) 1993, 1994 Washington
University in Saint Louis.
Portions Copyright (c) 1996, 1998 Berkeley Software Design, Inc.
Portions Copyright (c) 1989 Massachusetts
Institute of Technology.
Portions
Copyright (c) 1998 Sendmail, Inc.
Portions Copyright (c) 1983, 1995, 1996, 1997 Eric P. Allman.
Portions Copyright (c) 1997 Stan Barber.
Portions Copyright (c) 1997 Kent
Landfield.
Portions Copyright (c)
1991, 1992, 1993, 1994, 1995, 1996, 1997
Free Software Foundation, Inc.
Use and distribution of this software and
its source code are governed
by
the terms and conditions of the WU-FTPD Software License
("LICENSE").
If you did not receive a copy of the
license, it may be obtained online
at http://www.wu-ftpd.org/license.html.
$Id:
upload.configuration.HOWTO,v 1.2 2000/07/01 18:49:32 wuftpd Exp $
Upload Configuration
HOW-TO
This
document is available on-line at:
ftp://ftp.wu-ftpd.org/pub/wu-ftpd/upload.configuration.HOWTO
One
of the more powerfull, yet most often misused, features of WU-FTPD is
the
upload clause. Historically, the
problems with the upload clause stem
from unclear documentation and poor
implementation. This document is
an
attempt to address these issues.
The features discussed in this document
apply to WU-FTPD Version
2.6.0. If you are not running 2.6.0,
you are
strongly encouraged to upgrade; it includes a number of
corrections, new
features and security enhancements not available with
earlier versions of
WU-FTPD.
Upload restrictions
for anonymous FTP users
-------------------------------------------
For
this example, we'll assume your system /etc/passwd file contains an
entry
for the anonymous FTP user as follows:
ftp:*:95:95::/home/ftp:
If
your /etc/passwd file does not contain an entry for the user 'ftp' your
site
will not allow anonymous FTP. In
addition, if the usernames 'ftp' or
'anonymous' appear in the
/etc/ftpusers file, anonymous FTP will not be
allowed.
In
/etc/ftpaccess, we need a class which allows anonymous access. The
following allows anonymous FTP from
anywhere:
class anonftp anonymous *
To prevent anonymous
FTP users attempting a Denial of Service (DoS) attack
against your system,
you should create a special filesystem to receive
their uploads. This separate filesystem protects your
server by limiting
the total size of all uploaded files while preventing
those files from
consuming all available space on the server. For this example, mount the
filesystem
on /home/ftp/incoming
By default, the server will not allow uploads
from anonymous FTP users.
Just to be safe, and so we don't forget, let's
add a clause saying that:
upload /home/ftp * no
What this
says is, "For any user whose home directory is the anonymous FTP
area,
/home/ftp, do not allow any uploads."
As I said, this is the
default, but put it in anyway so you don't
forget.
Now, we want to allow uploads into the incoming
filesystem. We MUST add a
clause
granting that privilege to anonymous users.
Right now we don't want
to let anonymous users create
directories. (I recommend NEVER
allowing them
to do it, but I'll show you how in a bit.) We want to ensure, however,
the server
is safe and cannot be used as a way-point for software pirates
(warez
traders). So we'll set the directory
permissions for the incoming
area to prevent anyone seeing what's there
and make the area write-only for
anonymous users.
First, we
need an FTP site administrator, someone who owns the files, but
isn't the
root user or the anonymous user.
Something like the following
/etc/passwd entry will do:
ftpadmin:*:96:96::/home/ftp:
Set
the incoming area permissions and ownership to safe values. I
recommend the following:
chown
ftpadmin /home/ftp/incoming
chgrp ftpadmin /home/ftp/incoming
chmod
3773 /home/ftp/incoming
Actually, ftpadmin should own more of the
site, but I'm only talking about
uploads right now.
Finally,
before we get into allowing uploads, one last thing. Whether you
allow on-the-fly tar'ing of directories or not,
you should make sure an
end-run cannot be made and the incoming area
downloaded using tar. To do
so,
create the special file '.notar' in both the FTP directory and the
incoming
area:
touch /home/ftp/.notar
chmod 0 /home/ftp/.notar
touch
/home/ftp/incoming/.notar
chmod 0 /home/ftp/incoming/.notar
The
zero-length .notar file can confuse some web clients and FTP proxies,
so
let's mark it unretrievable.
noretrieve .notar
Time to
allow uploads, put the following in /etc/ftpaccess:
upload /home/ftp
/incoming yes ftpadmin ftpadmin 0440 nodirs
Notice the target
directory for the uploads is relative to the view the
user will have
during the FTP session.
What this says is, "For any user whose
home directory is the anonymous FTP
area, /home/ftp, allow uploads into
the directory /incoming but do not
allow the creation of new
directories. Make all files uploaded
owned by
the FTP administrator, mark them read-only so we don't allow them
to be
downloaded." If
uploaded files are to be made available for downloading,
the safest thing
to do is to tell the FTP administrator to move them into a
public area and
modify the permissions after validating and approving them.
I know this
seems draconian but, in the long run, it's best.
Some FTP sites like
to live dangerously and allow anonymous users to create
directories. I don't recommend this; it cannot be done
with absolute
safety. If you
insist, however, you can at least limit it to a single
directory
level. For example, replace the upload
clause just added with
the following:
upload /home/ftp
/incoming yes ftpadmin ftpadmin 0440
dirs 3773
upload /home/ftp /incoming/* yes ftpadmin ftpadmin 0440
nodirs
The first line allows directories to be created in the
incoming area and
enforces the use of safe permissions on them. The second prevents creation
of deeper
sub-directories. Notice one of the
problems with allowing
directory creation is there is no way to
automatically create a '.notar' in
the new directory, so a crafty user may
be able to make an end-run and
download it anyway using on-the-fly
tar'ing.
One last thing: since the incoming area shouldn't allow
downloads, and
since it's a file system, there will be a lost+found area;
you will want to
add the following clause to make SURE no downloads
occur:
noretrieve /home/ftp/incoming
or, at least, add
the following to prevent downloading of the lost+found
files:
noretrieve
/home/ftp/incoming/lost+found
Upload restrictions for
guest users
-----------------------------------
Setting up the FTP
server for guest users is covered in the Guest HOWTO.
It is not my purpose
here to cover how to set up for guest access.
If you
have not yet done so, review the information in that
document at:
ftp://ftp.fni.com/pub/wu-ftpd/guest-howto
For this example,
I'll assume you have entries similar to the following in
your system
/etc/passwd file:
dick:*:1010:1010::/home/users/./dick:/bin/sh
jane:*:1011:1011::/home/users/./jane:/bin/sh
By
default, the WU-FTPD server will grant upload privileges to all guest
users. The example users are chroot'd to
/home/users and cannot access any
area of the filesystem outside that
directory structure. What we're
interested
in, then, is simply protecting the areas in the chroot directory
structure
we want to keep the users out of.
In a minimal installation, there
will be bin, etc and dev, subdirectories
in the /home/users
directory. Other files and
subdirectories may exist
depending upon the requirements of your operating
system. We don't want
users being
able to upload into these areas. In
case something happens to
the permissions on them (you did set the
permissions to safe values, didn't
you?), you should deny upload
privileges in your ftpaccess file. In
our
case, we'll say the following:
upload /home/users/* / no
upload /home/users/* /bin no
upload
/home/users/* /etc no
upload /home/users/* /dev no
While we're
at it, we'll prevent downloads with noretrieve. Don't forget
to prevent end-runs by also creating .notar
files in each directory.
noretrieve /home/users/bin
noretrieve
/home/users/etc
noretrieve /home/users/dev
Upload
restrictions for real users
----------------------------------
First
off, let me say you shouldn't have any real users in your FTP site.
Or,
being more realistic, the only real user should be the site
administrator. That being said, real users should be
restricted to
uploading only into specific areas. Let's start with a real user in
/etc/passwd:
ftpadmin:*:109:109::/home/users/ftpadmin:/bin/sh
Again,
by default, the server will grant upload privileges everywhere, so
we have
to start by revoking them and only allowing what we want to:
upload
/home/users/ftpadmin *
no
upload /home/users/ftpadmin /tmp yes nodirs
upload /home/users/ftpadmin
/home/users/ftpadmin yes
upload
/home/users/ftpadmin /home/users/ftpadmin/* yes
upload
/home/users/ftpadmin /home/ftp/incoming
yes ftpadmin ftpadmin 0440 nodirs
About matching
rules
--------------------
Use extreme care when forming wildcard
matching rules. It may be
tempting
to say, for instance:
upload /home/users/ftpadmin
/home/users/ftpadmin* yes
But, if you do, there will be unintended
consequences. In the example,
we're
trying to restrict upload privileges to just the ftpadmin's home
directory. Consider, though, this will match all of the
following
directories:
/home/users/ftpadmin
/home/users/ftpadmin/mirrors
/home/users/ftpadministration
This
last directory isn't wanted. Instead
use:
upload /home/users/ftpadmin /home/users/ftpadmin yes
to match the ftpadmin's home
directory itself, then use:
upload /home/users/ftpadmin
/home/users/ftpadmin/* yes
to match all subdirectories under the
ftpadmin's home.
umasks for guest and real users
-------------------------------
In
most cases you will want to allow guest and real users to control the
permissions
on their own files and directories. As
in the examples shown,
if there are no specific permissions given on
upload clauses, any new files
or directories created will have all
permissions set. umasks can be
used
to reduce these permissions.
The daemon has a command-line
option (-u) to set the default umask for all
users. Follow the -u option with an octal
permissions mask. Bits in this
mask
are permissions to turn off whenever the daemon creates a new file or
directory. The manpage for ftpd documents the -u
option.
Often times, the global -u option is not sufficient. In the ftpaccess
file, you can control
umasks by class by using the defumask clause.
If no
class is given, defumask overrides the -u umask from the
command line. If
the current user
is a member of the named class, defumask overrides the
umask setting for
this user only.
For example, assume there are several classes of
users
class admin real 10.0.0.0/8 127.0.0.0/8
class
local guest 10.0.0.0/8 127.0.0.0/8
class remote guest *
class anon anonymous
*
( Notice, by the way, in this example, real users will not
be allowed
access unless from the local network since they are not in any
class when
coming from an outside IP address. Since the daemon gives no clue to the
remote user in this
case, to outside addresses it will appear as if the
admin users do not
exist on the server. The specific cause
for their login
failure will appear in your system logs. )
We
can control the umask by class for these users. For example, we might
say:
defumask 0377
defumask
0177 admin
defumask 0133 local remote
The first clause applies
whenever another defumask clause does not match
the current user's
class. This is the same as adding '-u
0377' to the
command line for the FTP daemon. In this case, the clause applies only to
anonymous users
since all other classes have specific default umasks given.
The
second turns off execute permissions, as well as group- and world- read
and
write permissions, for all files and directories created by real users
(users
in the admin class).
The last rule turns off execute permissions and
group- and world-write
permissions for files and directories created by
guests (in the local and
remote classes).
Remember: umasks
apply to ALL files and directories created EXCEPT those
where an upload
clause applies AND the upload clause gives specific
permissions. Disabling execute permissions will cause
problems using newly
created directories; leaving them enabled is unsafe
because all files
uploaded will have execute permission and could,
therefore, be used in
attempts to break into the server.
I
recommend disabling all execute permissions and instructing your users to
use
the chmod command to add execute permissions to directories or to
change
the umask before creating directories.
This may be a bit more work
for your users, but it is safer than
having a Trojan Horse program marked
executable just waiting for someone,
possibly root, to try running it.
umask and chmod
command restrictions
------------------------------------
As just
mentioned, users have the ability to change the current umask and
modify
the permissions on files and directories.
Obviously, you will want
to disable this feature for anonymous users.
You
may also want to control who may use these features for your
guest and real
users. The defaults
should be acceptable for most sites.
The default
settings are equivalent to the following (which you may
want to add to your
ftpaccess file so you don't forget):
chmod
no anonymous
chmod yes real,guest
umask
no anonymous
umask yes
real,guest
If, for example, you wanted to disable these commands for
guests accessing
the server from outside the local network, you could add
the following:
chmod no
class=remote
umask no
class=remote
Be sure to insert these _before_ the 'yes'
clauses. Order is important;
the
daemon will apply the first matching rule it finds. If you do
something like this, it is probably safer to
rewrite the clauses to deny
everything but what you allow. For example:
chmod yes real,class=local
umask
yes real,class=local
chmod no
guest,anonymous
umask no
guest,anonymous
Delete, overwrite, rename
restrictions
--------------------------------------
The daemon also
provides control over the user's ability to delete, over-
write and rename
files. Again, the defaults are probably
acceptable in
most cases. These
are:
delete no
anonymous
delete yes real,guest
rename no anonymous
rename yes real,guest
overwrite
no anonymous
overwrite yes
real,guest
As with the chmod and umask clauses, you can control
these by class as
well. Continuing
the above example, restricting these to local users only,
we could instead
say:
delete yes
real,class=local
rename yes
real,class=local
overwrite yes real,class=local
delete no
guest,anonymous
rename
no guest,anonymous
overwrite
no guest,anonymous
Per-class
upload clauses
------------------------
Just as we can restrict the
ability to change permissions, delete files,
etc., we can also define
upload clauses which apply only to specific
classes of users. For instance, with the classes from the
above examples,
we can revoke upload rights for remote guests.
For
example, we can deny all uploads the remote guests except to their
personal
tmp directories:
upload class=remote /home/users/* * no
upload class=remote
/home/users/* /*/tmp yes nodirs
Private incoming
areas
----------------------
Often times, users would like to have
private areas in the FTP site.
Sometimes, it is usefull to also have
incoming areas in those private
areas.
Examples of the permissions for private areas can be found in the
layout
at ftp://ftp.wu-ftpd.org/pub/wu-ftpd/examples/ and, other than
ownership,
are no different than the public incoming area, so I'll simply
present the
upload clauses here.
For this example, we'll allow anonymous uploads
into all private incoming
areas:
upload /home/ftp /private/*/incoming yes * * 0440 nodirs
upload
/home/users/ftpadmin /home/ftp/private/*/incoming yes * * 0440 nodirs
The
assumption here is Unix shell users have private areas in the anonymous
site. Those areas are owned by the appropriate
user, and incoming files
are to be owned by that user. The wildcard match on directory allows
anonymous
uploading to any private incoming directory.
The wildcard for
owning user and group instructs the daemon to set
the file's ownership to
that of the directory receiving it.
Don't
forget, if you allow private incoming areas, they are open for
anonymous
access and you should take care to ensure a DoS attempt to fill
the file
system cannot take out your entire server.
Create a separate
filesystem for the private incoming areas or put
them inside the public
incoming area.
Differences
from earlier versions
---------------------------------
This HOWTO was
written for version 2.6.0 of the
WU-FTPD server. Earlier
versions
used different rules for the upload clause.
Some versions of the
daemon required the first parameter to be the name of
the root directory
for the chroot. This allowed upload
control by area,
but did not provide for different rules on a per-user
basis.
Some versions of the daemon required the first parameter to
be lexically
identical to the user's home directory entry. This was non-obvious and the
'/./' was
often forgotten.
Some versions of the daemon got totally confused,
attempted to apply both
these methods at once, and ended up ignoring all
your upload rules. If you
were
smart, you had your permissions set properly and didn't notice.
Early
versions of the VR upgrades, and all earlier versions of the daemon,
allowed
file system modification as the default for all users. The current
version does not allow any
modification commands (ie., upload, delete,
rename) by anonymous users
unless specifically granted in the ftpaccess
file.
Early
versions of the VR upgrades, and all earlier versions of the dameon,
had
no method for specifying the permissions for a newly created directory.
Also,
they required exact matches for the first parameter (no globbing) and
exact
user and group names or numbers for ownership file files and
directories.
--
Gregory A Lundberg
WU-FTPD Development Group
1441 Elmdale Drive lundberg@wu-ftpd.org
Kettering,
OH 45409-1615 USA
1-800-809-2195