Copyright (c) 1999,2000,2001 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: guest.HOWTO,v 1.6 2002/02/13 17:58:05 wuftpd Exp $
***********************************************************************
This document was originally published by Michael Brennen on Fri, 15 Sep
1995 and contributed to the WU-FTPD Development Group on Fri, 28 Jul 2000.
The last section is Gregory A Lundberg's email from Nov, 2000, describing
some of the new features and issues involved in setting up a guest server.
***********************************************************************
There are three kinds of FTP logins that wu-ftpd provides:
1: anonymous FTP
2: real FTP
3: guest FTP
Anonymous FTP is well known; one logs in with the username 'anonymous'
and an email type password.
Real FTP is when someone logs in with a real username and password and
has access to the entire disk structure. This form of access can be
extremely dangerous to system security and should be avoided unless
absolutely necessary and well controlled.
Guest FTP is a form of real FTP; one logs in with a real user name and
password, but the user is chroot'ed to his home directory and cannot
escape from it. This is much safer, and it is a useful way for remote
clients to maintain their Web accounts.
If you want to learn more about 'chroot', the following two commands
should help, as should any good Unix text.
man chroot
There may be different man pages in sections 1, 2 and 8 (or others,
perhaps) depending on your operating system. ('man # chroot')
This howto will describe in detail the steps necessary to set up a
guest FTP account. It does not describe anonymous or real FTP setup,
though the procedures for setting up an operational 'ls' command will
apply equally to anonymous FTP because of the chroot'ed nature of
anonymous FTP.
***********************************************************************
The working example here will be as if it were a directory under a Web
tree, /home/web. The Web account will be maintained remotely by FTP.
The remote user is Mortimer. Mortimer's account name is "mort", group
"client".
(Yes, there is some droll humor here for the French speakers...)
1. Create Mort's entry in /etc/passwd and /etc/group. Do so manually,
or use adduser or whatever your Unix supports. If you use adduser,
you will probably have to make manual modifications to get the /./
information in the home path.
There are also entries to make in /etc/ftpaccess.
/etc/passwd:
mort:*:403:400:Mortimer Snerd:/home/web/mort/./:/etc/ftponly
^^^
The /./ sequence determines where the chroot() is done to. If you
want the chroot() done to the web directory and a chdir() to mort,
it would look like this:
mort:*:403:400:Mortimer Snerd:/home/web/./mort/:/etc/ftponly
^^^
--------> (make sure "/etc/ftponly" is in /etc/shells.)
/etc/group:
client::400:mort
Set Mort's password as you wish, or better yet use S/KEY.
The current releases of wu-ftpd come with /etc/ftpaccess enabled by
default. If your version does not do this for some reason, you must
do one of two thing to properly use /etc/ftpaccess:
1) compile the source to use /etc/ftpaccess by default;
modify the source to set use_accessfile = 1;
OR
2) run the daemon with the -a option.
/etc/ftpaccess:
class local real,guest,anonymous ......
... ^^^^^
... +----------- define 'guest' in the proper classes;
... this is site dependent.
...
...
delete no anonymous,guest # delete permission?
overwrite no anonymous,guest # overwrite permission?
rename no anonymous,guest # rename permission?
chmod no anonymous,guest # chmod permission?
umask no anonymous,guest # umask permission?
... ^^^^^
... +------ decide if guest should be in this
... permission list; this is site dependent.
...
...
path-filter guest /etc/pathmsg ^[-A-Za-z0-9_\.]*$ ^\. ^-
...
guestgroup client
...
2. Create Mort's home directory and set its ownership and protections.
mkdir /home/web/mort
chown mort.client /home/web/mort
chmod 755 /home/web/mort
3. Build the directory structure under Mort's account.
Create the /etc, /lib, and any other directory you need
in the directory that the chroot() is done into.
cd /home/web/mort
mkdir etc bin [dev lib] (dev and lib are optional and are OS dependent.)
chown root.daemon etc bin
chmod 111 etc bin
4. Build the contents of the ~/bin directory.
NOTE WELL: if you cannot see the directory contents after you login
as the guest user, the 'ls' program that you installed is not working.
If you use an 'ls' linked for dynamic libraries, and you do not have
the required libraries and/or devices installed properly in the guest
tree, 'ls' will not work and you will not see the contents of the
guest directory.
This is the single most FAQ on the wu-ftpd list. Repeating: if you
cannot see the contents of the directory, your installed 'ls' is not
working. The proper installation procedures for 'ls' vary by operating
system. There are some OS specific notes at the bottom of this howto
that may be of help.
Another problem that has been reported is that the chroot() directory
given in your /etc/passwd file for the guest account must be to the
directory where your ~/bin directory is located. That is, if your
chroot directory is /u01/ftp/ftptest/ and your /etc/passwd account is
yourftp:x:42:42:guest ftp account:/u01/ftp/./ftptest:/etc/ftponly
it will not work, as the ~/bin directory is not under the chroot()ed
directory. It must be set as follows.
yourftp:x:42:42:guest ftp account:/u01/ftp/ftptest/./:/etc/ftponly
There are additional resources to help if you still cannot see files
after an FTP login. See the FAQ and resource center at
http://www.wuftpd.org/ for more information.
USE STATIC LINKED COPIES OF ALL UTILITIES IF POSSIBLE.
You may get the source to build your own static 'ls' by downloading the
GNU fileutils source package from .
cp /.../bin/ls bin
chown root.bin bin/ls
chmod 111 bin/ls
Optional for on the fly compression and tar:
cp /.../bin/gzip bin
cp /.../bin/tar bin
chown root.bin bin/gzip
chown root.bin bin/tar
chmod 111 bin/gzip
chmod 111 bin/tar
If the utilities are not static, create the necessary devices in ~/dev and
copy the necessary libraries into ~/lib. Check the man page for ftpd that
comes with your system; it may be of help.
REGARDING HARD AND SOFT/SYMBOLIC LINKS:
The chroot() obviates the use of soft links in this case. However, it
it is possible to make these hard links back to the master copy of the
utilities rather than copies. This can save some disk space if that is
a concern.
5. Build the contents of the ~/etc directory.
Edit "passwd" to contain the following:
root:*:0:0::/:/etc/ftponly
mort:*:403:400::/home/web/mort/./:/etc/ftponly
Edit "group" to contain the following:
root::0:root
client::400:mort
chown root.daemon passwd group
chmod 444 passwd group
6. Add some extra security touches
cd /home/web/mort
touch .rhosts .forward
chown root.root .rhosts .forward
chmod 400 .rhosts .forward
You should now be the proud owner of a working guest group FTP login.
Connect to the machine via FTP and login as "mort". You should end up in
Mort's account with a current directory of "/".
If not, go over it carefully again, as there is a lot of detail here. If
you still can't get it to work, yell for help on wu-ftpd@wugate.wustl.edu.
**************************************************************************
OS DEPENDENCIES / QUIRKS
LINUX:
Linux does not need a ~/dev dir. It does need the ~/lib dir if the
utilities in ~/bin are dynamically linked.
Use the 'ldd' command to find out what libraries are necessary for a given
dynamically linked utility.
LINUX REDHAT 6.1: (reported by Steven Schramm )
I found the following steps for the lib directory critical to my
success:
- create the lib directory with mode 111
- cd lib
- cp /lib/ld-2.1.1.so .
- cp /lib/libc-2.1.1.so .
- ln -s ld-2.1.1.so ld-linux.so.2
- ln -s libc-2.1.1.so libc.so.6
- chmod 111 ld-2.1.1.so
- chmod 555 libc-2.1.1.so
SOLARIS:
Solaris can't handle SETPROCTITLE, so turn the compile time option off.
(The following was culled from a post by Tom Leach to the wu-ftpd list.)
>For people who are having problems with ls -al and dir on solaris 2.x
>systems, you might try the following to find out what's missing...
>truss -f chroot ~ftp /bin/ls
>This will run the ls command in the same chroot'd environment that
>anonymous FTP runs in. The truss will show you what
>files/libraries/devices are accessed and where the ls is looking for them.
>Tom Leach
>leach@oce.orst.edu
SOLARIS 2.6:
Contents of ~ftp/usr/lib
Solaris expects to find the libraries in ~ftp/usr/lib , not in ~ftp/lib
Copy the following libraries out of /usr/lib into ~ftp/usr/lib
Also, I'm not sure that intl and w are necessary.
ld.so
ld.so.1
libc.so.1
libdl.so.1
libintl.so (can be a symlink to libintl.so.1)
libintl.so.1
libw.so.1
Contents of ~ftp/dev:
Create "zero" and "tcp" entries. Check your existing /dev/zero and
/dev/tcp (using ls -lL /dev/zero /dev/tcp) to make sure that these
major and minor numbers are correct for your system (they have been
changed for newer Solaris versions), then use "mknod" to create the
device files in ~ftp/dev
mknod zero c
mknod tcp c
The above notes are gratefully acknowledged from
Gregor Mosheh
SUN 4.1.x:
Create a ~dev/zero and ~dev/tcp device for the FTP directory as follows.
Run the following 'ls' command, then create the devices in the ~/dev
directory with the 'mknod' command, using the major and minor numbers
from the 'ls' results (thanks to Jim Davis ).
ls -lL /dev/zero /dev/tcp
cd dev
mknod zero c
mknod tcp c
cd ..
chmod 555 dev
You may also wish to use the following method to create the device,
per Ian Willis ; repeat this command for each device
(zero, tcp, etc.).
find /dev/zero -print | cpio -pd ~ftp
Also, you probably need the following shared libraries:
~lib/ld.so
~lib/libc.so
~lib/libdl.so
BSDI:
Set 555 protections on the ~ftp/shlib and its contents if shared
libraries are used.
From Darci Chapman (dchapmax@preview.jf.intel.com):
The following directories and files need to be created in whatever
directory/ies are being chrooted to (~ftp for anon ftp or for whatever
directory guest users are chrooted):
dr-xr-xr-x root/wheel 0 Nov 3 01:43 1995 bin/
-r-xr-xr-x root/wheel 12288 Nov 3 01:43 1995 bin/compress
-r-xr-xr-x root/wheel 45056 Nov 3 01:43 1995 bin/gzip
-r-xr-xr-x root/wheel 12288 Nov 3 01:43 1995 bin/ls
-r-xr-xr-x root/wheel 65536 Nov 3 01:43 1995 bin/pax
dr-xr-xr-x root/wheel 0 Nov 3 01:43 1995 etc/
-r--r--r-- root/wheel 793 Nov 3 01:43 1995 etc/group
-r--r--r-- root/wheel 817 Nov 3 01:43 1995 etc/localtime
-r--r--r-- root/wheel 40960 Nov 3 01:43 1995 etc/pwd.db
dr-xr-xr-x root/wheel 0 Feb 3 12:34 1995 pub/
dr-xr-xr-x root/wheel 0 Nov 3 01:43 1995 shlib/
-r-xr-xr-x root/wheel 298407 Nov 3 01:43 1995 shlib/libc_s.2.0
IRIX (5.3, 6.x)
from frans stekelenburg :
(as in SUN 4.1.x, but without /dev/tcp)
Create a ~dev/zero device for the FTP directory as follows. (tip:
search on 'dev/zero' in your IRIX systems' Online Books.)
Run the following 'ls' command, then create the devices in the ~/dev
directory with the 'mknod' command, using the major and minor numbers
from the 'ls' results (thanks to Jim Davis ).
ls -lL /dev/zero
cd dev
mknod zero c
cd ..
chmod 555 dev
You may also wish to use the following method to create the device,
per Ian Willis ; repeat this command for each device
(zero, tcp, etc.).
find /dev/zero -print | cpio -pd ~ftp
Also, you probably need the following shared libraries:
~lib/rld
~lib/libc.so.1
(found in /lib)
Also read the manpages on FTPD, or look in the IRIX Insight Library
(Online Books) in the book/chapter "IRIX Admin: Networking and Mail"
for the paragraph 'How to Set Up a Proper Anonymous FTP Account'
(search helps:-)) on your IRIX system.
AIX:
Per Chuque Berry and Joseph Matusiewicz
, AIX needs the following files for
the external ls to work:
~lib/libc.a
~lib/libcurses.a (???)
You may also need:
~lib/libcrypt.a
**************************************************************************
For extra tips on security see Christopher Klaus's FAQ:
http://www.iss.net/iss/faq.html
**************************************************************************
If you run across some special trick required to get guest access to run
on your OS, or some security cleanup, please let me know and I will update
the master of this document.
Don't contact me individually for help. Go through the wu-ftpd list for
that and I will see the post there.
Michael Brennen
mbrennen@fni.com
***************************************************************************
Date: Tue, 28 Nov 2000 05:40:07 -0500
From: Gregory A Lundberg
Cc: WU-FTPD Development Group ,
WU-FTPD Questions ,
WU-FTPD Discussion List ,
WU-FTPD Documentation
Subject: Guest HOWTO
Koos -- for the FAQ.
Everyone else -- consider this a basis for a new Guest HOWTO ... it does
not completely replace the current one (since I don't go into system-
specific information), but it does give the basics.
> My ftpaccess file does not seem to be used.
or
> I have ungraded my ftpd to the latest version of wuftpd but i still seem
> unable to get a user to chroot to its own directory.
plus
> How do I avoid having to copy the "glue" needed to get ls (as well as
> compress, tar, gzip, etc.) working?
or
> Do I really need to copy bin/ls into every user's home directory?
plus
> The user is chroot'd but the initial directory is incorrect.
or
> How can I change the user's initial directory for FTP without changing it
> for shell access?
plus
> How do I keep users from being able to cd out of their home directories?
or
> How do I keep users from being able to see and/or access each other's
> files and directories?
First off, almost everything you will want to do requires that you're
actually using the ftpaccess file.
- Make sure you have the -a option on the command line. The most common
reason for failure to chroot when upgrading from VERY old versions is
this option is missing. Be sure to check the -a option is not being
'eaten' by mistake. I suggest using "-a -a". If this solves the problem
change it to "ftpd -a". Be sure to tell inetd to reload its
configuration each time you make a change (typically by using "killall
-HUP inetd").
- If the above does not solve the problem, ensure you are editing the
correct ftpaccess file. The easiest way to do this is to insert a
greeting clause at the top of the ftpaccess file. Before doing so,
connect to the daemon using telnet or a command-line FTP client. Notice
the initial greeting message. The default greeting contains the version
and compile date of the daemon. Take a moment and check; make sure the
version and compile date/time indicate you are running the version of the
daemon you THINK you should be.
By adding 'greeting brief' to the ftpaccess file, the version and date
information should no longer appear. (Changing to 'greeting terse'
should remove the host name as well.)
If this indicates you are not editing the correct file, you can locate
the actual file name. Usually, simply running the ckconfig utility
(compiled when you built the daemon) will tell you the file name.
Sometimes, however, this command is not installed or is outdated. You
can get the information directly from the daemon using the strings
command. First, locate the actual daemon executable file. I'll use
/usr/sbin/wu-ftpd in this example but check your /etc/inetd.conf for the
actual file name:
$ strings /usr/sbin/wu-ftpd | grep '/ftpaccess' | head -n 1
/etc/ftpaccess
Repeat the first set of tests using this file name. If the output does
not make sense, remove the "| head -n 1" and read through the entire
list; the file name will be there. (If it's not, recompile and
re-install the daemon after beating up the person who hand-hacked the
source to yours and obtaining a fresh copy of the source kit.)
- If you're using "guestgroup" and the old "/./ hack", you need to be sure
the user is explicitly listed as a member of one of the guest groups in
your master group file. For example (if I used the "/./ hack"), to make
myself a guest, I could say:
guestgroup lundberg
Some older versions of the daemon, however, would not detect that the
user was a member of this group by the master password file entry.
Instead, the user had to be explicitly listed. So, if I used this
feature, to make myself a guest, my master group file (/etc/group) entry
for this group would need to read:
lundberg::101:lundberg
- The "/./ hack" is no longer required to chroot guest users. In fact, I
suggest not using it since the "/./ hack" can cause some problems for
certain shell uses. (Plus it involves a by-hand edit of your master
password file, which is almost always a bad idea.) Instead, I suggest
using the new guest-root clause. This clause works by USER NAME or ID
NUMBER. When guest-root is present and matches for a user, two things
happen: the master password file is no longer consulted to determine
where to chroot to for matching users, the master password file no longer
determines the user's "home" (for both initial directory or ~ notation).
Instead, the guest-root determines the chroot directory, and the chroot-
local password file determines the user's "home".
On my servers, all users chroot to a common point. I do this so I do not
need to copy the "glue" into every user's home directory. My users all
go into a directory (actually, a file system) named /home/users so I use
the following clause:
guest-root /home/users
Notice I do not specify any user name or ID number. This causes the
guest-root to be the default; it applies unless there is a specific
clause matching the user.
By using guest-root, I override any "/./ hacks" which might already exist
in my master password file.
By using a common point for all users, I only need a single copy of the
various bits and pieces needed for ls to work. In my example, I only
need the following directories and files:
d--x--x--x /home/users/etc
-r--r--r-- /home/users/etc/.notar
-r--r--r-- /home/users/etc/passwd
-r--r--r-- /home/users/etc/group
d--x--x--x /home/users/bin
-r--r--r-- /home/users/bin/.notar
---x--x--x /home/users/bin/ls
d--x--x--x /home/users/dev
-r--r--r-- /home/users/dev/.notar
crw-rw-rw- /home/users/dev/null
Plus any other files or directories needed to make bin/ls work as well as
the tar, compress or gzip programs (and their glue) if I want to use
ftpconversions. (Note to Redhat Linux users: you get all the necessary
glue by installing the anonftp RPM into the chroot area.)
Guest-root only applies to guests. I recommend making EVERYONE a guest.
I do that by using the new "guestuser" clause with a wildcard:
guestuser *
On versions through 2.6.2, due to an oversight on my part some time ago,
you will also need to add the following:
realuser ftp
Otherwise anonymous users will become guests as well (which is bad).
This anachonism is corrected in versions after 2.6.2 (which, as I write
this, has yet to be released).
(As of 2.8.0, the anonymous user 'ftp' is always "real" and this is no
longer required.)
- If, at this point, your user is not chroot'd you are not running the
most-recent version of WU-FTPD. Obtain the source kit for the current
version, recompile and repeat the above steps.
When using the "guest-root" clause, the user's initial directory (and
"home" for ~ notation) is taken from the chroot-local password file. It
becomes CRITICAL that this file be "locally correct." By that, I mean that
the home directory entries in the chroot-local password file be correct
when viewed from INSIDE the chroot. (In fact, it has always been important
that the local password file be locally correct, but this distinction
becomes critical when using guest-root.)
Using my account as an example, my master password file entry looks
something like:
lundberg:*:101:101:Gregory A Lundberg:/home/users/lundberg:/bin/sh
Remember, I use guest-root to chroot all users to /home/users. So my
chroot-local password file is /home/users/etc/passwd. The "locally
correct" entry for me in this file reads:
lundberg::101:101::/lundberg:
Notice, for security, to avoid leaking any information I don't absolutely
need to, I've also removed all unnecessary information.
Many of my customers use FTP to manage their web sites. For them, I'd
rather their FTP client see their web directory as "home". But I need to
leave their system home unchanged (so Apache can find their site properly).
On many systems, web pages are stored in ~/public-html. To modify my
account to my FTP starts in my web pages rather than my "home", I simply
change the chroot-local password entry to read:
lundberg::101:101::/lundberg/public-html:
At this point, my users are chroot'd and starting in the proper
directories. But they are all chroot'd to a common point. I don't want my
customers to be able to view each other's files (or even be able to use FTP
to determine who my other customers are).
For this, I use the restricted-uid clause. I restrict everyone (including
myself) to their "home". Remember, the guest-root clause changes the
determinination of "home". By adding the following clause, my users are no
longer able to access files outside their "home" (even via a symbolic
link):
restricted-uid *
Note this applies to real users as well. Think of restricted-uid as a
"soft" chroot. The effect is (or, at least, should be) the same as a
chroot, but without the problems encumbent with having actually done a
chroot (by that, I mean, mainly, having to copy the "glue" arround so ls
works).
A few words of warning: although restricted-uid works to give an effect
much the same as a chroot, I VERY STRONGLY discourage its use in place of
making users guests. While it appears to work properly, I never trust any
single feature to provide the level of security I want. So I make my users
guests AND restrict them to their homes. This way, if a user should find a
way to work past the restricted-uid feature to access files outside its
home, access is still limited to the chroot area.
--
Gregory A Lundberg WU-FTPD Development Group
1441 Elmdale Drive lundberg@wu-ftpd.org
Kettering, OH 45409-1615 USA 1-800-809-2195