home *** CD-ROM | disk | FTP | other *** search
- Archive-name: computer-security/anonymous-ftp-faq
- Post-Frequency: monthly
- Last-modified: 1994/6/1
- Version: 1.3
-
- How to set up a Secure Anonymous FTP Site
-
- The following is a FAQ on setting up a secure FTP Site. FTP sites
- are known for much abuse by transferring illegal files. They also open many
- oppurtunities for intruders to gain access via misconfigured setups. And
- lastly many versions of ftp servers have had security holes. This FAQ is
- intended to clean up this abuse by allowing administrators to go through this
- check list of steps to make sure their FTP is correctly configured and that
- they are running the most current ftp daemon.
-
- This is organized in the following fashion, I am breaking into several parts
- as follows:
-
- Part 1 - General Description of Setting up an "anonymous" ftp server.
- Part 2 - Setting up a chrooted Secure Anonymous ftp server.
- Part 3 - OS Specific needed information and suggestions.
- Part 4 - Where to get other FTP daemons
- Part 5 - Archie
- Part 6 - Acknowledgements.
-
-
-
-
- Part 1 - General Description of Setting up an "anonymous" ftp server.
-
- How do I setup "anonymous" ftp securely?
-
- PLEASE READ ALL NOTES AND WARNINGS!!!
-
- 1) Create the user ftp in /etc/passwd. Use a misc group. The user`s home
- directory will be ~ftp where ~ftp is the root you wish anonymous users to
- see.
-
- Use an invalid password and user shell for better security. The entry in the
- passwd file should look something like:
-
- ftp:*:400:400:Anonymous FTP:/home/ftp:/bin/true
-
- 2) Create the home directory ~ftp. Make the directory owned by root (NOT ftp)
- with the same group as ftp. Thus, owner permissions are for root and group
- permissions are for the anonymous users. Set the permissions for ~ftp to 555
- (read, nowrite, execute).
-
- 3) Create the directory ~ftp/bin. This directory is owned by root (group
- e.g. wheel) with permissions 111 (noread, nowrite, execute).
-
- 4) Copy the program ls into ~ftp/bin. ls is owned by root with permissions
- 111 (noread, nowrite, execute). Any other commands you put in ~ftp/bin
- should have the same permissions as well.
-
- 5) Make the directory ~ftp/etc. This directory is owned by root with
- permissions 111.
-
- 6) Create from scratch the files /etc/passwd and /etc/group in ~ftp/etc.
- These files should be mode 444. The passwd file should only contain root,
- daemon, uucp, and ftp. The group file must contain ftp's group. Use your
- /etc/passwd and /etc/group files as a template for creating passwd and group
- files going to ~ftp/etc. You may even change the user names in this file,
- they are used only for 'ls' command. So for example if all files in your
- ~ftp/pub/linux hierarchy will be maintained by a real user 'balon' with
- uid=156 you may put
-
- linux:*:156:120:Kazik Balon::
-
- in the ~ftp/etc/passwd file (regardless of his real username). Leave only
- these users who will own files under ftp hierarchy (e.g. root, daemon,
- ftp...) and definitely remove *ALL* passwords by replacing them with '*' so
- the entry looks like:
-
- root:*:0:0:Ftp maintainer::
- ftp:*:400:400: Anonymous ftp::
-
- For more security, you can just remove ~ftp/etc/passwd and
- ~ftp/etc/group (the effect is that ls -l will not show the directories' group
- names). Wuarchive ftp daemon (and some others) have some extensions based on
- the contents of the group/passwd files, so read the appropriate documentation.
-
- 7) Make the directory ~ftp/pub. This directory is owned by you and has the
- same group as ftp with permissions 555. On most systems (like SunOS) you may
- want to make this directory 2555, ie. set-group-id, in order to create new
- files with the same group ownership.
-
-
- Files are left here for public distribution. All folders inside ~ftp/pub
- should have the same permissions as 555.
-
- *** Neither the home directory (~ftp) nor any directory below it should be
- owned by ftp! No files should be owned by ftp either. Modern ftp daemons
- support all kinds of useful commands, such as chmod, that allow outsiders to
- undo your careful permission settings. They also have configuration options
- like the following (WuFTP) to disable them:
-
- # all the following default to "yes" for everybody
- delete no guest,anonymous # delete permission?
- overwrite no guest,anonymous # overwrite permission?
- rename no guest,anonymous # rename permission?
- chmod no anonymous # chmod permission?
- umask no anonymous # umask permission?
-
-
- 8) If you wish to have a place for anonymous users to leave files, create
- the directory ~ftp/pub/incoming. This directory is owned by root with
- permissions 733. Do a 'chmod +t ~ftp/pub/incoming'. The ftp daemon will
- normally not allow an anonymous user to overwrite an existing file, but a
- normal user of the system would be able to delete anything. By setting the
- mode to '1733' you prevent this from happening. In wuftpd you may configure
- the daemon to create new files with permissions '600' owned by root or any
- other user. Many times, incoming directories are abused by exchanging pirated
- and pornographic material. Abusers often create hidden directories there for
- this purpose. Making the incoming directory unreadable by anonymous ftp helps
- to some extent. With ordinary ftp severs there is no way to prevent
- directories being created in incoming. The WUarchive ftp server can limit
- uploads to certain directories and can restrict characters used in file names
- like this:
-
- # specify the upload directory information
- upload /var/spool/ftp * no
- upload /var/spool/ftp /incoming yes ftp staff 0600 nodirs
-
- # path filters
- # path-filter...
- path-filter anonymous /etc/msgs/pathmsg ^[-A-Za-z0-9_\.]*$ ^\. ^-
- path-filter guest /etc/msgs/pathmsg ^[-A-Za-z0-9_\.]*$ ^\. ^-
-
- Suggestion: Create an extra file-system for your ftp-area (or at least for
- your incoming-area) to prevent a denial-of-service attack by filling your
- disk with garbage (inside your incoming directory).
-
- If you have wuftpd you may want to add some ftp extensions like
- compression/decompression 'on the fly' or creation of tar files for the
- directory hierarchies. Get the appropriate sources (gzip, gnutar, compress),
- compile them and link statically, put in the ~ftp/bin directory and edit the
- appropriate file containing the definitions of the allowed conversions.
- /usr/bin/tar is already statically-linked. You may wish to use gnu tar
- anyway.
-
- Gary Mills wrote a small program to support the following:
- I got compress from ftp.uu.net, in the root directory, I believe, and compiled
- it. To do tar and compress, I wrote a tiny program called `pipe', and
- statically-linked it. My /etc/ftpconversions file looks like this:
-
- #strip prefix:strip postfix:addon prefix:addon postfix:external command:
- #types:options:description
- :.Z: : :/bin/compress -d -c %s:T_REG|T_ASCII:O_UNCOMPRESS:UNCOMPRESS
- :-z: : :/bin/compress -d -c %s:T_REG|T_ASCII:O_UNCOMPRESS:UNCOMPRESS
- : : :.Z:/bin/compress -c %s:T_REG:O_COMPRESS:COMPRESS
- : : :.tar:/bin/tar cf - %s:T_REG|T_DIR:O_TAR:TAR
- : : :.tar.Z:/bin/pipe /bin/tar cf - %s | /bin/compress -c:T_REG|T_DIR:O_COMP
- RESS|O_TAR:TAR+COMPRESS
- : : :.tar:/bin/gtar -c -f - %s:T_REG|T_DIR:O_TAR:TAR
- : : :.tar.Z:/bin/gtar -c -Z -f - %s:T_REG|T_DIR:O_COMPRESS|O_TAR:TAR+COMPRES
- S
- : : :.tar.gz:/bin/gtar -c -z -f - %s:T_REG|T_DIR:O_COMPRESS|O_TAR:TAR+GZIP
-
- Here it is:
- -----------------8<-------------cut---------------
- /* pipe.c: exec two commands in a pipe */
-
- #define NULL (char *)0
- #define MAXA 16
-
- main(argc, argv) int argc; char *argv[]; {
- char *av1[MAXA], *av2[MAXA];
- int i, n, p[2], cpid;
-
- i = 0; n = 0;
- while ( ++i < argc && n < MAXA ) {
- if ( *argv[i] == '|' && *(argv[i]+1) == '\0' ) break;
- av1[n++] = argv[i];
- }
- if ( n == 0 ) uexit();
- av1[n] = NULL;
- n = 0;
- while ( ++i < argc && n < MAXA )
- av2[n++] = argv[i];
- if ( n == 0 ) uexit();
- av2[n] = NULL;
- if ( pipe(p) != 0 ) exit(1);
- if ( ( cpid = fork() ) == (-1) ) exit(1);
- else if ( cpid == 0 ) {
- (void)close(p[0]);
- (void)close(1);
- (void)dup(p[1]);
- (void)close(p[1]);
- (void)execv(av1[0], av1);
- _exit(127);
- }
- else {
- (void)close(p[1]);
- (void)close(0);
- (void)dup(p[0]);
- (void)close(p[0]);
- (void)execv(av2[0], av2);
- _exit(127);
- }
- /*NOTREACHED*/
- }
-
- uexit() {
- (void)write(2, "Usage: pipe <command> | <command>\n", 34);
- exit(1);
- }
-
-
-
- 9) Other things to do:
-
- as root: touch ~ftp/.rhosts ~ftp/.forward
- chmod 400 ~ftp/.rhosts ~ftp/.forward
-
- ie. make these files zero-length and owned by root.
-
- Due to the last /bin/mail bugs in SunOS:
-
- touch /usr/spool/mail/ftp; chmod 400 /usr/spool/mail/ftp
-
- Consider an email-alias for the ftp-admin(s) to provide an email-address for
- problems-reports.
-
- If you are mounting some disks from other machines (or even your own) to the
- ~ftp hierarchy, mount it read-only. The correct entry for the /etc/fstab (on
- the host with ftpd) is something like:
-
- other:/u1/linux /home/ftp/pub/linux nfs ro,noquota,nosuid,intr,bg 1 0
-
- This mounts under /home/ftp/pub/linux the disk from host 'other' with no
- quota, no 'suid' programs (just in case), interruptible (in case 'other'
- goes down) and 'bg' - so if 'other' is down when you reboot it will not stop
- you trying to mount /home/ftp/pub/linux all over again.
-
-
-
- Part 2 - Setting up a chrooted Secure Anonymous ftp server.
-
- This part was contributed by Marcus J Ranum <mjr@tis.com>
-
- Steps
- -----
-
- 1) Build a statically linked version of ftpd and put it in ~ftp/bin.
- Make sure it's owned by root.
-
- 2) Build a statically linked version of /bin/ls if you'll need one.
- Put it in ~ftp/bin. If you are on a Sun, and need to build
- one, there's a ported version of the BSD net2 ls command
- for SunOs on ftp.tis.com: pub/firewalls/toolkit/patches/ls.tar.Z
- Make sure it's owned by root.
-
- 3) Chown ~ftp to root and make it mode 755 THIS IS VERY IMPORTANT
-
- 4) Set up copies of ~ftp/etc/passwd and ~ftp/etc/group just as you would
- normally, EXCEPT make 'ftp's home directory '/' -- make sure
- they are owned by root.
-
- 5) Write a wrapper to kick ftpd off and install it in /etc/inetd.conf
- The wrapper should look something like: (assuming ~ftp = /var/ftp)
-
- main()
- {
- if(chdir("/var/ftp")) {
- perror("chdir /var/ftp");
- exit(1);
- }
- if(chroot("/var/ftp")) {
- perror("chroot /var/ftp");
- exit(1);
- }
- /* optional: seteuid(FTPUID); */
- execl("/bin/ftpd","ftpd","-l",(char *)0);
- perror("exec /bin/ftpd");
- exit(1);
- }
-
- Options:
- You can use 'netacl' from the toolkit or tcp_wrappers to achieve
- the same effect.
-
- We use 'netacl' to switch so that a few machines that connect to
- the FTP service *don't* get chrooted first. This makes transferring
- files a bit less painful.
- You may also wish to take your ftpd sources and find all the places
- where it calls seteuid() and remove them, then have the wrapper do
- a setuid(ftp) right before the exec. This means that if someone
- knows a hole that makes them "root" they still won't be. Relax and
- imagine how frustrated they will be.
-
- If you're hacking ftpd sources, I suggest you turn off a bunch of
- the options in ftpcmd.y by unsetting the "implemented" flag in
- ftpcmd.y. This is only practical if your FTP area is read-only.
-
- 6) As usual, make a pass through the FTP area and make sure that the files
- are in correct modes and that there's nothing else in there that
- can be executed.
-
- 7) Note, now, that your FTP area's /etc/passwd is totally separated from
- your real /etc/passwd. This has advantages and disadvantages.
-
- 8) Some stuff may break, like syslog, since there is no /dev/log. Either
- build a version of ftpd with a UDP-based syslog() routine or
- run a second syslogd based on the BSD Net2 code, that maintains
- a unix-domain socket named ~ftp/dev/log with the -p flag.
-
- REMEMBER:
- If there is a hole in your ftpd that lets someone get "root"
- access they can do you some damage even chrooted. It's just
- lots harder. If you're willing to hack some code, making the
- ftpd run without permissions is a really good thing. The
- correct operation of your hacked ftpd can be verified by
- connecting to it and (while it's still at the user prompt)
- do a ps-axu and verify that it's not running as root.
-
-
-
- Part 3 - OS Specific needed information and suggestions.
-
-
- Older SVR2 and SVR3 system, RTU 6.0 (Masscomp, now Concurrent Real Time UNIX),
- AT&T 3B1 and 3B2 machines - May need dev/tcp:
-
- [dev/tcp]
-
- These ftpd implementations may require a ~ftp/dev/tcp in order for anonymous
- ftp to work.
-
- You have to create a character special device with the appropriate major and
- minor device numbers. The appropriate major and minor numbers of ~ftp/dev/tcp
- are what the major and minor numbers of /dev/tcp are.
-
- The ~ftp/dev is a directory and ~ftp/dev/tcp is a character special device.
- Make them owned and grouped by root. Permissions for ~ftp/dev is root
- read/write/exec and other & group read and exec. The permissions for
- ~ftp/dev/tcp is root read/write, other & group read.
-
-
-
- HPUX
-
- [Logging] If you're using HP's native ftpd, the line in /etc/inetd.conf
- should execute ftpd -l, which does extra logging.
-
-
- SunOS
-
- [Libraries] To set up SunOS to use its shared dynamic libraries, follow these
- steps:
-
- 1) Create the directory ~ftp/usr. This directory is owned by root with
- permissions 555.
-
- 2) Create the directory ~ftp/usr/lib. This directory is owned by root with
- permissions 555.
-
- 3) Copy the runtime loader ld.so into ~ftp/usr/lib for use by ls. ld.so is
- owned by root with permissions 555.
-
- 4) Copy the latest version of the shared C library, libc.so.* into
- ~ftp/usr/lib for use by ls.
-
- libc.so.* is owned by root with permissions 555.
-
- ***4.1.2(or above) users: you also need to copy /usr/lib/libdl.so.* to
- ~ftp/lib.
-
- 5) Create the directory ~ftp/dev. This directory is owned by root with
- permissions 111.
-
- 6) ~ftp/dev/zero is needed by the runtime loader. Move into the directory
- ~ftp/dev and create it with the command:
-
- mknod zero c 3 12
-
- chown ~ftp/dev/zero to root. Make sure it's readable.
-
- ***For novices: WARNING!! Don't try to copy /dev/zero to ~ftp/dev/zero!!
- This is an endless file of zeroes and it will completely fill your filesystem!
-
- 7) If you want to have the local time showing when people connect, create the
- directory ~ftp/usr/share/lib/zoneinfo and copy
- /usr/share/lib/zoneinfo/localtime
-
- 8) If you are bothered by the need for copying your libraries so that you can
- use Sun's 'ls', which is dynamically linked, you can try to get a statically
- linked copy of 'ls' instead. The CD-ROM that contains Sun's OS has a
- statically-linked version of ls. In this case, you can dispense with steps
- #6-8.
-
- Statically linked versions may be available from the following sources:
-
- If you want a statically linked "ls" get the GNU fileutils off a
- archive site near you and statically link it.
-
- [Logging] Sun's standard ftpd logs *all* password information. To correct it,
- install patch:
-
- 101640-03 SunOS 4.1.3: in.ftpd logs password info when -d option is
- used.
-
- In /etc/inetd.conf find the line that starts with "ftp". At the
- end of that line, it should read "in.ftpd". Change that to "in.ftpd -dl".
- In /etc/syslog.conf, add a line that looks like:
-
- daemon.* /var/adm/daemonlog
-
-
- Note that the whitespace between the two columns must include at least one
- TAB character, not just spaces, or it won't work. Of course your log file
- could be anything you want. Then, create the logfile (touch
- /var/adm/daemonlog should do). Finally, restart inetd and syslogd, either
- individually, or by rebooting the system. You should be good to go. If you
- do not install the patch, make sure the log file is owned by root and mode
- 600, as the ftp daemon will log *everything*, including users' passwords.
-
-
-
-
-
- Part 4 - Where to get other FTP daemons
-
- Wuarchive FTP 2.4- A secure FTP daemon that allows improved access-control,
- logging, pre-login banners, and is very configurable:
- Can be ftp'd from ftp.uu.net in "/networking/ftp/wuarchive-ftpd"
- directory. Be certain to verify the checksum information to confirm that you
- have retrieved a valid copy. [Warning: Older versions of Wu-FTP are extremely
- insecure and in some cases have been trojaned.]
-
- BSD SVR4
- File Checksum Checksum MD5 Digital Signature
- ----------------- -------- --------- --------------------------------
- wu-ftpd-2.4.tar.Z 38213 181 20337 362 cdcb237b71082fa23706429134d8c32e
- patch_2.3-2.4.Z 09291 8 51092 16 5558a04d9da7cdb1113b158aff89be8f
-
- For DECWRL ftpd, sites can obtain version 5.93 via anonymous FTP
- from gatekeeper.dec.com in the "/pub/misc/vixie" directory.
-
- BSD SVR4
- File Checksum Checksum MD5 Digital Signature
- ----------------- -------- --------- --------------------------------
- ftpd.tar.gz 38443 60 1710 119 ae624eb607b4ee90e318b857e6573500
-
- For BSDI systems, patch 005 should be applied to version 1.1 of
- the BSD/386 software. You can obtain the patch file via
- anonymous FTP from ftp.bsdi.com in the "/bsdi/patches-1.1"
- directory.
-
- BSD SVR4
- File Checksum Checksum MD5 Digital Signature
- ----------------- -------- --------- --------------------------------
- BU110-005 35337 272 54935 543 1f454d4d9d3e1397d1eff0432bd383cf
-
-
- Public Domain Sources:
- ftp.uu.net ~ftp/systems/unix/bsd-sources/libexec/ftpd
- gatekeeper.dec.com ~ftp/pub/DEC/gwtools/ftpd.tar.Z
-
-
- Part 5 - Archie
-
- Searches FTP sites for programs. Login into these sites as archie
- or use client software for faster access. To get your own anonymous
- site added to Archie's search list, e-mail archie-updates@bunyip.com.
-
- archie.ac.il 132.65.20.254 (Israel server)
- archie.ans.net 147.225.1.10 (ANS server, NY (USA))
- archie.au 139.130.4.6 (Australian Server)
- archie.doc.ic.ac.uk 146.169.11.3 (United Kingdom Server)
- archie.edvz.uni-linz.ac.at 140.78.3.8 (Austrian Server)
- archie.funet.fi 128.214.6.102 (Finnish Server)
- archie.internic.net 198.49.45.10 (AT&T server, NY (USA))
- archie.kr 128.134.1.1 (Korean Server)
- archie.kuis.kyoto-u.ac.jp 130.54.20.1 (Japanese Server)
- archie.luth.se 130.240.18.4 (Swedish Server)
- archie.ncu.edu.tw 140.115.19.24 (Taiwanese server)
- archie.nz 130.195.9.4 (New Zealand server)
- archie.rediris.es 130.206.1.2 (Spanish Server)
- archie.rutgers.edu 128.6.18.15 (Rutgers University (USA))
- archie.sogang.ac.kr 163.239.1.11 (Korean Server)
- archie.sura.net 128.167.254.195 (SURAnet server MD (USA))
- archie.sura.net(1526) 128.167.254.195 (SURAnet alt. MD (USA))
- archie.switch.ch 130.59.1.40 (Swiss Server)
- archie.th-darmstadt.de 130.83.22.60 (German Server)
- archie.unipi.it 131.114.21.10 (Italian Server)
- archie.univie.ac.at 131.130.1.23 (Austrian Server)
- archie.unl.edu 129.93.1.14 (U. of Nebraska, Lincoln (USA))
- archie.uqam.ca 132.208.250.10 (Canadian Server)
- archie.wide.ad.jp 133.4.3.6 (Japanese Server)
-
-
-
- Part 6 - Acknowledgements
-
- Thanks to the following people for suggestions that help shape this FAQ:
-
- Tomasz Surmacz (tsurmacz@asic.ict.pwr.wroc.pl)
- Wolfgang Ley (Ley@rz.tu-clausthal.de)
- Russel Street (russells@ccu1.auckland.ac.nz)
- Gary Mills (mills@CC.UManitoba.CA)
- Morten Welinder (terra@diku.dk)
- Nick Christenson (npc@minotaur.jpl.nasa.gov)
- Mark Hanning-Lee (markhl@romoe.caltech.edu)
- Marcus J Ranum <mjr@tis.com>
-
-
- Copyright
-
- This paper is Copyright (c) 1994
- by Christopher Klaus of Internet Security Systems, Inc.
-
- Permission is hereby granted to give away free copies. You may
- distribute, transfer, or spread this paper. You may not pretend that you
- wrote it. This copyright notice must be maintained in any copy made.
-
-
- Disclaimer
-
- The information within this paper may change without notice. Use of
- this information constitutes acceptance for use in an AS IS condition.
- There are NO warranties with regard to this information. In no event shall
- the author be liable for any damages whatsoever arising out of or in
- connection with the use or spread of this information. Any use of this
- information is at the user's own risk.
-
-
-
- Address of Author
-
- Please send suggestions, updates, and comments to:
-
- Christopher Klaus <cklaus@shadow.net>
- of Internet Security Systems, Inc. <iss@shadow.net>
-
- --
- Christopher William Klaus <cklaus@shadow.net> <iss@shadow.net>
- Internet Security Systems, Inc.
- 2209 Summit Place Drive,
- Atlanta,GA 30350-2430. (404)998-5871.
-
-