Date: Tue, 28 Nov 2000 05:40:07 -0500
From: Gregory A Lundberg <>
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.


> I have upgraded my ftpd to the latest version of wuftpd but I still cannot
> seem to get a user to chroot to its own directory.


> How do I avoid having to copy the "glue" needed to get ls (as well as
> compress, tar, gzip, etc.) working?


> Do I really need to copy bin/ls into every user's home directory?


> The user is chroot'd but the initial directory is incorrect.


> How can I change the user's initial directory for FTP without changing it
> for shell access?


> How do I keep users from being able to cd out of their home directories?


> 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

  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:


- 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 buy 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.1, 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 anachronism is corrected in versions after 2.6.1 (which, as I write
  this, has yet to be released).

- 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:


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:


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
determination of "home". By adding the following clause, my users are no
longer able to access files outside their "home" (even via a symbolic

  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 incumbent with having actually done a
chroot (by that, I mean, mainly, having to copy the "glue" around so ls

A few words of warning: although restricted-uid works to give an effect
much the same as a chroot, I VERY STRONGLY discourage it's 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.

Now, having done all this, go read the Upload Configuration HOWTO.

Last updated: Wed, 16 May 2001 09:58:47 -0400