Alternatives to FTP

 < Day Day Up > 

Setting Up ProFTPD as a Replacement for the Default ftpd

If you decide to activate anonymous FTP, especially anonymous FTP with an upload directory, consider replacing the default ftpd with a more modifiable ftpd. A popular, highly configurable replacement ftpd is ProFTPD, available at In addition to being highly configurable, it easily compiles under Mac OS X.

ProFTPD is intended to be a secure, highly configurable FTP server. It is modular in design, like the Apache web server, which is discussed in Chapter 23, "Creating a Web Server." Although it is intended to be a secure FTP server, ProFTPD is not exempt from security problems. It's still important to regularly monitor the anonymous FTP area, if you have one, as well as make sure that you have the latest version of ProFTPD, which is version 1.2.10 as of this writing.

ProFTPD is quite capable. We will look at only a handful of its capabilities, including the installation process, basic configuration, expanding its capabilities with modules, and interpreting its logs.

Installing ProFTPD

To replace the default ftpd with proftpd, first download, compile, and install proftpd. proftpd is one of the packages that follows this basic format for compilation and installation:

 ./configure make make install 

By default, proftpd installs in /usr/local with root as the owner and wheel as the group. Being the highly configurable package that it is, you can these and many other parameters. To run proftpd as a different user who belongs to a different group, you will need to set the install_user and install_group variables.

With proftpd's modular design, you specify at the ./configure line any modules that you might want included. However, with its modular design, you can also easily modify which modules are included by recompiling proftpd whenever the need arises. The proftpd source does include a directory of contributed modules.

In a bash shell, your configure line might have a form like the following:

 install_user=<user> install_group=<group> ./configure --with-modules=<module1>:<module2> 

Table 22.5 provides information about some of the options you can configure for proftpd.

Table 22.5. Select Options to Configure for proftpd




Specifies a prefix for the proftpd installation other than the default /usr/local.


Enables modules listed in the colon-separated module list.


Sets the default timeout (in seconds) for idle connections (default = 600).


Sets the default timeout (in seconds) for no data transferred (default = 300).


Tunes the size (in bytes) of data transfer buffers (default = buffer size).

To distinctly separate the proftpd installation from the default ftpd, consider specifying paths in the various path parameters. In addition, you might consider running ./configure with --prefix=<some-directory-for-proftpd> so that the proftpd binaries and man pages are all in one place. Next, run make and make install.

The most complicated part about replacing the default ftpd with proftpd is deciding how to run it. You can run it as a standalone FTP server, you can run it out of launchd, or you can it out of xinetd or inetd. Refer to Chapter 16, "Managing System Services and Configuration," for advice on the different ways to start up your new FTP server.

Table 22.6 includes some runtime options for proftpd. They are mostly useful for debugging purposes, but be sure to include any runtime options of interest to you in whatever startup method you choose. For most purposes, you probably will not need to specify any runtime options.

Table 22.6. Select Runtime Options Available in proftpd


Internet File Transfer Protocol server

ftpd [-h] [-n] [-q] [-d <level>] [-D <definition>] [-c <config-file>] [-p 0|1] [-l] [-t] [-v] [-vv]

ftpd is the Internet File Transfer Protocol process. It uses the TCP protocol and runs on the port specified as ftp in /etc/services.


Displays help.


Disables background daemon mode and sends all output to stderr.


Does not send output to stderr when running with -n / --nodaemon.

-d <level>

-debug <level>

Sets debugging level (0 9, where 9 is the highest level)

-c <config-file>

--config <config-file>

Specifies an alternative configuration file.


Lists compiled-in modules.


Tests the syntax of the configuration file.

-v <version>

Prints version number and exits.


Prints extended version information and exits.

Configuring ProFTPD Server Options

The ProFTPD server comes with a basic configuration file, located in a default installation in /usr/local/etc. To configure proftpd, you will have to edit this configuration file. As we have mentioned before, the FTP server is a powerful, flexible one. In this section we will look at the basic concept of configuration directives, applying access controls, setting up virtual hosts, adding transfer ratios, and creating guest user accounts.

Understanding ProFTPD Configuration Directives

The ProFTPD configuration file gets its inspiration from the Apache web server, whose configuration will be discussed in detail in Chapter 23.

ProFTPD has seven configuration contexts: main server configuration, <Anonymous>, <Directory>, <Global>, <Limit>, <VirtualHost> and .ftpaccess. The main server configuration, usually called server config, is everything that is not in the rest of the sections. The <Anonymous> context configures an anonymous FTP server. The <Directory> context is used for configuring specific directories. The <Global> context is where you specify configuration parameters that would apply to all of your virtual hosts without having to retype the same configuration directives for every virtual host. If a directive that is specified in the global section is also included in the server config or <VirtualHost> contexts, those specifications override the specifications in the <Global> section. The <Limit> context sets limits on specific FTP commands within a given context. The <VirtualHost> context is where virtual hosts are configured. Finally, .ftpaccess is a file that users can use in their own directories.

You can use a number of directives in configuring proftpd. Table 22.7 documents the directives used in the default configuration file as well as some interesting ones. Some directives can be used in multiple contexts. Not every variation of a directive type is shown in the table. For example, Allow is shown, but not AllowUser. For a complete listing of available directives, check

Table 22.7. Select proftpd Directives





Sets the name displayed to connecting users.



Sets the mode that the proftpd runs in.



Sets which server configuration is used as the default when an incoming connection is destined for an IP address which is not that of the primary host or any of the virtual hosts.



Sets the port for the control channel.



Sets the default umask.



Sets the maximum number of child processes spawned.



Sets the user the daemon runs as.



Sets the group the server normally runs as.



Sets the default chroot directory.



Allows files to be overwritten.



Sets the number of users that can connect.



Sets the file to display at login.



Sets the file to display when first entering a directory.



Sets access control in the <Limit> context. Specifies which hosts and networks can access the server. Typically used in conjunction with Order and Deny.



Requires anonymous logins to enter a valid password matches the password of the user that the anonymous daemon runs as. Can be used in conjunction with AuthUsingAlias to create guest accounts.



Specifies an alternate group file, having the same format as the /etc/group file.



Sets the PAM service name used in authentication. Default is ftp.



Specifies an alternative password file, having the same format as the /etc/passwd file.



Specifies authentication via alias name instead of a mapped username. Can be used in conjunction with AnonRequirePassword to create guest accounts.



Binds the server or host to a particular IP address.



Controls class based access by classifying each connecting IP address.



Enables class-based access control.



Sets the address for the main server to listen on.



Sets the default file transfer mode.



Sets access control in the <Limit> context. Specifies which hosts and/or networks are denied access to the server. Typically used in conjunction with Order and Deny.



Sets up a block of configuration directories for the specified directory and its subdirectories.



Hides the true owner of files in a directory. If turned on without specifying a username, displays all files as being owned by ftp.



Specifies custom log files.



Hides directories that the current user has no access to in a directory listing.



Sets the server address presented to clients.



Sets the maximum rate at which new TCP connections are accepted. The number set is the number at which the restriction takes effect.



Restricts size of files that can be downloaded. Optional parameters include user, group, and class.



Restricts size of files that can be uploaded. Optional parameters include user, group, and class.



Configures the order in which Allow and Deny directives are checked inside a <Limit> context.



Specifies the FTP data port range to be used.



Allows only new files that match the specified regular expression.



Denies new files that match the specified regular expression.



Sets whether ProFTPD holds files open during user/ group lookups. Default is on. ProFTPD documentation recommends setting this to off for Mac OS X.



Sets whether or not to require that a user's shell be listed in /etc/shells. Default is on.



Disables the use of the syslog mechanism and redirects all logging output to the specified file. Can be used in server config, <VirtualHost>, and <Global> contexts.



Disables the use of the syslog mechanism and redirects all logging output to the specified file. Can be used in server config context.



Configures the full path to a wu-ftpd-style transfer log. Default is /var/log/xferlog.



Sets the upload and download transfer rates.



Sets whether to block based on /etc/ftpusers. Option is on by default.



Aliases a username to a system user.



Sets the chroot directory to a subdirectory of the anonymous server.



Creates a password for a particular user that overrides a user's normal system password. Takes a hashed password argument that is clear text run through crypt. Can be useful when combined with UserAlias to provide multiple logins to an anonymous server.


The default proftpd.conf file has three contexts: the server config, <Limit>, and <Anonymous> contexts. Here is the server config context:

 # This is a basic ProFTPD configuration file (rename it to # 'proftpd.conf' for actual use.  It establishes a single server # and a single anonymous login.  It assumes that you have a user/group # "nobody" and "ftp" for normal operation and anon. ServerName                      "ProFTPD Default Installation" ServerType                      standalone DefaultServer                   on # Port 21 is the standard FTP port. Port                            21 # Umask 022 is a good standard umask to prevent new dirs and files # from being group and world writable. Umask                           022 # To prevent DoS attacks, set the maximum number of child processes # to 30.  If you need to allow more than 30 concurrent connections # at once, simply increase this value.  Note that this ONLY works # in standalone mode, in inetd mode you should use an inetd server # that allows you to limit maximum number of processes per service # (such as xinetd). MaxInstances                    30 # Set the user and group under which the server will run. User                            nobody Group                           nogroup # To cause every FTP user to be "jailed" (chrooted) into their home # directory, uncomment this line. #DefaultRoot ~ # Normally, we want files to be overwriteable. AllowOverwrite          on 

In the server config context, the ServerName, ServerType, DefaultServer, Port, Umask, MaxInstances, User, Group, DefaultRoot and AllowOverrite directives are included. One of the important directives in this section is the ServerType directive. This directive sets what mode proftpd runs in. By default, it is set to standalone. If you have a high traffic FTP server, this is the option you will want. Create a startup script to start the FTP server at boot time. It has been our experience that if you have any users with the ;basic; authentication authority, they will not be able to log in to the standalone server. Otherwise, you might prefer to set that to inetd, which works for running proftpd from inetd, xinetd, or launchd. Users with ;ShadowHash; or ;basic; authentication authority can log in to the FTP server in this mode. By default, proftpd runs as user nobody in group nogroup. For Mac OS X, change that nogroup setting to nobody. You might want to consider creating a specific user and group for proftpd to run as. The ServerName is what is displayed after the ProFTPD version information when a user connects to your machine. You can put something more interesting there than the default.

Here is the main <Limit> context:

 # Bar use of SITE CHMOD by default <Limit SITE_CHMOD>   DenyAll </Limit> 

The default configuration file's <Limit> context denies the SITE_CHMOD command to everyone. This does not allow users to chmod files on the FTP server. The <Limit> context, which can be used within other contexts, can be used for individual FTP commands, groups of FTP commands or on all commands. SITE commands are limited by prepending SITE_ to the command. Limits on individual commands take precedence over limits on groups, which take precedence over limits on all commands. Table 22.8 shows what the <Limit> groups are and which commands belong to which groups.

Table 22.8. <Limit> Command Groups

<Limit> Command Group

FTP Commands


All FTP commands









Here is the <Anonymous> context:

 # A basic anonymous configuration, no upload directories.  If you do not # want anonymous users, simply delete this entire <Anonymous> section. <Anonymous ~ftp>   User                          ftp   Group                         ftp   # We want clients to be able to login with "anonymous" as well as "ftp"   UserAlias                     anonymous ftp   # Limit the maximum number of anonymous logins   MaxClients                    10   # We want 'welcome.msg' displayed at login, and '.message' displayed   # in each newly chdired directory.   DisplayLogin                  welcome.msg   DisplayFirstChdir             .message   # Limit WRITE everywhere in the anonymous chroot   <Limit WRITE>     DenyAll   </Limit> </Anonymous> 

If you do not plan to run an anonymous FTP server, you can delete this context. The default configuration file includes a basic configuration for an anonymous FTP server that does not have any upload directories. It lists the anonymous user as user ftp, belonging to group ftp. The anonymous and ftp logins are aliased to that user. The maximum number of clients is set to 10, and it also includes settings for a welcome message and a message to be displayed for each directory. This section specifically denies the WRITE command group to all users using the <Limit> directive.

The default configuration file, however, does not quite work in Mac OS X. If your system has PAM installed, which Mac OS X does, proftpd assumes a default PAM authentication file located at /etc/pam.d/ftp. In Mac OS X, though, this file is /etc/pam.d/ftpd. To fix this problem, you can either copy /etc/pam.d/ftpd to /etc/pam.d/ftp or you can set the AuthPAMConfig directive to /etc/pam.d/ftpd.

Depending on the shell that you assigned to your ftp user, the default <Anonymous> context might not command groups> groups> command> work. If you assigned the ftp user a shell that is not in /etc/shells, anonymous FTP will not work. Either list that shell in /etc/shells or set the RequireValidShell directive to off.

Applying Access Controls

Now that you have tested the basic functionality of the default proftpd.conf file, you probably want to expand the server's functionality. In this section we will look at some basic controls that you can apply.

To deny access to IP addresses that you have found to be troublesome, add a section like the following:

 <Limit LOGIN>   Order Allow, Deny   Deny from 192.168.23.,, </Limit> 

In the section, the order of the rules has been specified as Allow, Deny. This means that, by default, access is allowed from all hosts unless a specific deny statement exists. Then any host for which the deny statement is true, is denied access to the FTP server. In this example, then, access is allowed from all hosts, except to all users coming from the 192.168.23 subnet, the address and the subnet.


You could also choose to use TCP Wrappers for this type of control. Edit your /etc/xinetd.d/ftp file to list /usr/libexec/tcpd as the server, point the server_args to your proftpd, and add NAMEINARGS to flags.

Suppose that you wanted to allow only two users, nermal and joray, to connect to your FTP server. You could add a section like the following, which specifically allows nermal and joray, but denies access to all other users:

 <Limit LOGIN>   AllowUser nermal   AllowUser joray   DenyAll </Limit> 

If you wanted to then limit user nermal to coming from 192.168.1. subnet, you could add a section like the following:

 <IfUser nermal>   <Limit LOGIN>       Order Deny, Allow       Allow from 192.168.1.   </Limit> </IfUser> 

Please note that the <IfUser>, <IfClass>, and <IfGroup> directives are available with mod_ifsession, which is not compiled in by default.

Suppose that you only wanted to have an anonymous FTP server, and not allow access to any of your users. You could do that by adding a section to the server config context that denies access to all:

 <Limit LOGIN>   DenyAll </Limit> 

Then in the <Anonymous> context, add a section that allows access to all:

 <Limit LOGIN>    AllowAll </Limit> 

As you are probably starting to see, the access restriction possibilities with ProFTPD are enormous. There are a variety of access restriction directives available. Some notable directives include AllowUser, DenyUser, AllowGroup, DenyGroup, Class, and Directory. With the Class directive, you can set up classes of hosts and apply restrictions based on the class. The Directory directive can be used to set up access restrictions to the specified directory and its subdirectories.

Setting Up Virtual Hosts

One of the reasons that you might have decided to replace the default ftpd with proftpd is to set up a virtual FTP server. In this section, we will take a brief look at setting up a basic virtual anonymous FTP server.

The <VirtualHost> context enables you to serve multiple FTP servers that don't relate to the main FTP server or main anonymous FTP server all from the same machine. You will need an IP address and a domain name. Your network administrator or ISP can help you with those details.

Probably the easiest way to see how the virtual anonymous FTP server configuration works is to look at a modified version of the sample configuration that comes with ProFTPD.

 #Virtual FTP server <VirtualHost>   ServerName                    "'s FTP server"   Umask                         027 RequireValidShell off ServerLog /var/log/ TransferLog /var/log/   <Limit LOGIN>     DenyAll   </Limit>   <Anonymous /Users/virtual/>     User                        ftp     Group                       ftp     UserAlias                   anonymous ftp     <Limit LOGIN>       AllowAll     </Limit> <Directory *>       <Limit WRITE>       DenyAll     </Limit>    </Directory>     <Directory incoming>       <Limit READ WRITE>         DenyAll       </Limit>       <Limit STOR>         AllowAll       </Limit>     </Directory>   </Anonymous> </VirtualHost> 

The configuration for the virtual host looks a lot like the configuration for the main FTP server or main anonymous FTP server. The <VirtualHost> context takes either an IP address or a DNS name. In this example, we see that the virtual FTP server is running on When someone ftps to this FTP server, it displays that it is's FTP server, as set by the ServerName directive. The ServerLog and transferLog directives have been used to specify alternative logs for the virtual FTP server. This makes it easier to track information regarding that FTP server. The next section denies login for all users.

The final section is the virtual FTP server's configuration for its anonymous FTP server. We see that its anonymous directory is running out of the /Users/virtual/ Like the standard anonymous FTP server, it runs as user ftp in group ftp. A user can log in as anonymous or ftp for login, and all logins are allowed. The last section configures directories. The WRITE command is denied to all directories by default. The incoming directory denies the READ and WRITE command groups by default, but does allow the STOR command that belongs to the WRITE command group.

If you are running a lot of virtual FTP servers, especially high traffic virtual FTP servers, you might want to run proftpd as a standalone server.


To bind another IP address to your network card, you can just duplicate your interface in the Network Preferences pane and assign another IP address to the duplicate entry.

Alternatively, to bind another IP address to your network card (typically en0 for most single network card systems), run this command at the command line:

 sudo ifconfig en0 alias 

Put this in a startup script. For more discussion on ifconfig, see Chapter 28, "Implementing Server Security and Advanced Network Configuration."

Adding Transfer Controls

ProFTPD has a variety of transfer controls available. Such control directives include MaxConnectionRate, MaxRetrieveFileSize, MaxStoreFileSize and TRansferRate. The most complex of these directives is TRansferRate, whose syntax is

TransferRate [<FTP commands>][<kilobytes-per-second>[:<free-bytes>]] [user|group|class <expression>]

transferRate is applied to a comma-separated list of FTP commands, selected from APPE, RETR, STOR, and STOU. The rate, in kilobytes/second, is the actual transfer rate used. The <free bytes> parameter sets the number of free bytes that can be transferred before the restriction is applied. This allows small files to be easily transferred, but throttles the transfer of larger files. The transferRate directive can also be applied to a certain user, group, or class, with an <expression> that specifies what user, group, or class to which to restrict or not restrict bandwidth.

For example,

 TransferRate RETR 1.5 user marvin 

restricts user marvin's rate to retrieve data from the FTP server to 1.5 KB/s.

The following statements restrict the append and store commands for all users to 8192 KB/s, and the retrieve command to 4096 KB/s:

 TransferRate APPE,STOR 8192 TransferRate RETR 4096 

Other transfer controls are available with the mod_quotatab module. This module also has driver modules mod_quotatab_file, mod_quota_ldap, and mod_quota_sql. You must install mod_quotatab and at least one of the driver modules. If you install mod_quota_ldap, you must also install either of the other two driver modules. If you install mod_quota_sql, you must also have installed mod_sql. In our examples, we have installed mod_quotatab and mod_quotatab_file.

To make use of mod_quotatab, you have to define two quota tables. One table keeps quota information for absolute file/byte limits for users, groups, and classes. The other table keeps a current tally of the file/bytes used by those users, groups, and classes. To keep track of the uploaded bytes/files limits, mod_quotatab uses the data from the DELE, APPE, STOR, and STOU commands issued; for downloaded bytes/files limits, RETR; for transferred bytes/files limits, DELE, APPE, STOR, STOU, and RETR. To create these tables for mod_quota_file and manipulate their data, the ftpquota utility, which is a Perl script, is provided. Table 22.9 contains command line documentation for ftpquota.

Table 22.9. ftpquota Command Documentation


Manipulates FTP quota tables

ftpquota <operation-type> <table-type> <options>

Operation Types


Creates a new record with the specified limits. Requires the -name and -quota-type options.


Creates table if not present. Default table locations are ./ftpquota.limittab and ./ftpquota.tallytab.


Deletes the specified record. Requires the -name and -quota-type options.


Displays all the quota records in the table in a readable format.


Updates a record with the specified quota limits.

Table Type


Specifies the table type to use as either tally or limit. Required option.

Quota-Limiting Options


Specifies the limit of the number of bytes that may be uploaded. Defaults to -1 (unlimited).



Specifies the limit of the number of bytes that may be downloaded. Defaults to -1 (unlimited).



Specifies the limit of the number of bytes that may be transferred. Total includes uploads, downloads, and directory listings. Defaults to -1 (unlimited).



Specifies the limit of the number of files that may be uploaded. Defaults to -1 (unlimited).



Specifies the limit of the number of files that may be downloaded. Defaults to -1 (unlimited).



Specifies the limit of the number of files that may be transferred, including uploads and downloads. Defaults to -1 (unlimited).



Specifies the type of limit, hard or soft, of the bytes limits. If hard, any uploaded files that push the bytes used counter past the limit will be automatically deleted; if soft, those extra bytes will be allowed, but future uploads will be denied.



Specifies a name for the quota record. This name will be the user/login name, group name, or class name, depending on the quota type. Option is ignored if the quota type specified is all.



Specifies that the quota limit is to be applied only to each session, rather than persisting across sessions. By default, quotas are persistent.



Specifies a quota type for this record, where the type is which category of FTP users this quota applies to. The quota type must be one of the following: user, group, class, or all.


Miscellaneous Options


Displays help.


Specifies the quota table location.


Specifies whether to treats bytes as is, or in kilobytes, megabytes, or gigabytes. Allowable options are B or byte, Kb or kilo, Mb or mega, and Gb or giga. Defaults to byte.


Toggles more verbose information about the tool as it works.

To create your tables, run commands of the following form:

 ftpquota --create-table --type=limit ---table-path=<path-to-table> ftpquota --create-table --type=tally --table-path=<path-to-table> 

Next, populate the limit with your quota information. The tally table is automatically populated by mod_quotatab, although you can manually manipulate records in it.

In this example, we place limits on user nermal, who will have a limit of two upload files and two download files:

localhost: root# ftpquota --add-record --type=limit --name=nermal --quota-type=user --files-upload=2 --files-download=2 --table-path=/usr/local/etc/ftpquota.limittab

It is recommended that you place either file limits or byte limits, but not both. To see the contents of the table, run the following command:

localhost: root# ftpquota --show-records --type=limit --table-path=/usr/local/etc/ftpquota .limittab ------------------------------------------- Name: nermal Quota Type: User Per Session: False Limit Type: Hard Uploaded bytes: unlimited Downloaded bytes: unlimited Transferred bytes: unlimited Uploaded files: 2 Downloaded files: 2 Transferred files: unlimited

We see that she can download and upload only two files, that a hard limit has been placed, and that the Per Session setting is currently set to false.

The mod_quotatab module provides these directives: QuotaDirectoryTally, QuotaDisplayUnits, QuotaEngine, QuotaLimitTable, QuotaLock, QuotaLog, QuotaShowQuotas, QuotaTallyTable. To use mod_quotatab, you will need to provide entries in the configuration file for at least QuotaEngine, QuotaLimitTable, and QuotaTallyTable.

We added these entries:

 QuotaEngine on QuotaLimitTable file:/usr/local/etc/ftpquota.limittab QuotaTallyTable file:/usr/local/etc/ftpquota.tallytab QuotaLog /var/log/proftpd-quota.log 

To enable or disable mod_quotatab, QuotaEngine must be set to on or off, as appropriate. To disable QuotaEngine, simply set this directive to off, and then you don't have to worry about commenting out any other quota-related directives. The QuotaLimitTable and QuotaTallyTable directives tell proftpd where to look for the appropriate tables. The QuotaLog directive specifies an alternate log where quota activity can be logged.

After our user has uploaded and downloaded files, we see that the tally table information shows:

localhost: root# ftpquota --show-records --type=tally --table-path=/usr/local/etc/ftpquota .tallytab ------------------------------------------- Name: nermal Quota Type: User Uploaded bytes: 0.00 Downloaded bytes: 0.00 Transferred bytes: 0.00 Uploaded files: 1 Downloaded files: 1 Transferred files: 0

The nermal user has uploaded and downloaded one file so far; only one more of each remains in her quotas. After she has reached a quota, she and her administrator will have to decide whether her quotas should be adjusted. Perhaps she should have higher limits; maybe per-session quotas would be more appropriate; perhaps her limits should be removed; or perhaps she is a trouble user, and no adjustment is appropriate.

The last type of transfer control that might be of interest is ratio control, available in mod_ratio. With this module, you can control upload and download ratios. This module includes quite a few directives, some involving the actual ratios and others involving error messages and such. The directives involving the ratios themselves are AnonRatio, GroupRatio, HostRatio, and UserRatio. To enable the module, you have to set the Ratios directive to on.

Each of these directives takes four parameters: file ratio, initial file credit, byte ratio, and initial byte credit. Setting a parameter to 0 disables that check. The default for each parameter is 0.

The basic syntax for one of these directives is

<directive> <specific anon password/group/host/user> <file-ratio> <initial-file-credit> <byte-credit> <initial-byte-credit>

The following sample sets up a restriction for users in group test to have a file ratio of 50:1, an initial credit of five files, a byte ratio of 5:1 and an initial byte credit of 100KB.

 GroupRatio test 50 5 5 100000 

Creating Guest User Accounts

In addition to allowing real users and anonymous users access to your FTP area, you might also be interested in allowing guest user access. You can restrict your real users' FTP access to their home directories, if you so choose. Whether you choose to do so is up to you. If you trust your users enough to give them full login access to your machine in the first place, you might also trust them with full FTP access. Anonymous users are users who have access to only the anonymous area of your machine, if you chose to create an anonymous FTP area. Guest users are users who have accounts on your machine but aren't granted full access to your machine. Although there are probably various ways to define a guest user, for our purposes, a guest user is a user who has an account on your machine, but who is not granted full access to your machine. Guest user accounts might be suitable for users who have websites on your machine and need FTP access only to occasionally update their websites.

A guest user account is a cross between a real user account and an anonymous FTP account. A guest user has a username and password but doesn't have shell access to his account. This enables him to use FTP to access files on the server via a user ID and password, but prevents him from being able to log in to the machine either through the network or at the console. Guest user accounts are useful if, for example, you need to set up a place where a group of collaborators can share sensitive information and data, but where you don't really want members of the group to be full users of your machine. If you set up a single guest user account for this group of users, all that group's users can access it with a user ID and password, and people without the user ID and password can't, so their information remains private. Because the users in the group don't have real shells, however, they can't log in to your machine and use any resources other than those available through the FTP server.

Guest user accounts are set up similarly to the anonymous FTP account. The users are restricted to their home directories only, as is the anonymous FTP account, and traditionally, their accounts contain the commands that they might need to run while accessing their accounts via FTP.

If you decide that you need guest user accounts, do the following to create a guest user:


Decide where the guest user's home directory should be. You could put your guest users in the same location as your regular users. You also could create a directory somewhere for guest users and place guest user directories in that location.


After you've decided where the guest account should reside, make a guest account. You could create your user in the Accounts pane in System Preferences. Your guest user, however, might not really have a need for all the directories that are made in a user account created in this way. You can decide what directories might be necessary. If you anticipate having many guest users, you could create a guest skeleton user as your basis for guest accounts.


The guest user should belong to some sort of guest group. Create a guest group with an unused GID number. Edit the guest user's account to belong to the guest group. The guest user's shell should be modified to some nonexistent shell. Make sure that the guest user's home directory and everything in it are owned by the guest user with the guest group.


Include the shell that you use for the guest in /etc/shells. You might want the contents of your fake guest user shell to be something like this:

 #! /bin/sh exit 1 


Update the ownership information of the guest user's account to include the guest group GID indicated in the NetInfo database.


Copy the same system files used for the anonymous FTP user to the guest user's account. Specifically, make sure that the system files

 /bin/ls /usr/lib/dylib /usr/lib/libSystem.B.dylib /System/Library/Frameworks/System.framework/Versions/B/System 

are included in the guest user's home directory. In this example, for user ralph, the files would be placed in

 /Users/guests/ralph/bin/ /Users/guests/ralph/usr/lib/ /Users/guests/ralph/System/Library/Frameworks/System.framework/Versions/B/ 

with the same permissions and ownerships that are used for an anonymous FTP account.

If you create a skeleton guest user account, these are files that would be useful to include in the skeleton guest user account. Note, however, that this step is not necessary for ProFTPD, but is shown in case the need should ever arise.

As you might expect, with ProFTPD's amazing flexibility, there are at least two ways that you could approach configuring ProFTPD to recognize your guest user as a guest user. The simplest way is to restrict your guest group users to their home directories by using the DefaultRoot directive. If you called your guest group ftponly, your statement would look like this:

 DefaultRoot ~ ftponly 

You could also treat the guest users more like anonymous users, and use an anonymous user configuration, like this modification of one of the sample configurations:

 <Anonymous ~ralph>   User ralph   Group ftponly   UserAlias artist ralph   AuthAliasOnly on   AnonRequirePassword on # Deny write operations to all directories, underneath root-dir # Default is to allow, so we don't need a <Limit> for read # operations. <Directory *>   <Limit WRITE>   DenyAll </Limit> </Directory> # Deny all read/write operations in incoming. Because these are # command-group limits, we can explicitly permit certain # operations which will take precedence # over our group limit. <Directory incoming> <Limit READ WRITE>   DenyAll </Limit> # The only command allowed in incoming is STOR (transfer file # from client to server) <Limit STOR>   AllowAll </Limit> </Directory> </Anonymous> 

This sample sets up a configuration for guest user ralph. This user can log in either as ralph or as artist, and is required to issue a password to log in. By default, the WRITE command group is denied to all of his directories. For his incoming directory, the READ and WRITE command groups are denied, but from the WRITE command group, the STOR command is allowed. With this configuration, user ralph can only upload to his incoming directory. The directory configurations can certainly be changed to suit whatever your guest user's needs are.

Expanding ProFTPD Capabilities with Modules

As you have seen throughout this part of the chapter, the default capabilities of ProFTPD can be expanded by installing modules. You can get news on the latest modules at You can also find many modules at The ProFTPD source distribution comes with a number of modules that aren't compiled in. However, there are other modules that do not come with the ProFTPD source.

Before you install a module, even one that comes with the source, read any pertinent READMEs and follow those instructions. For modules that are not included with the source, instructions frequently include first copying files to the contrib directory of the source tree, and then running configure with that module listed in the --with-modules option and recompiling.

If you wanted to recompile proftpd to contain additional modules we have mentioned, first make a backup of all of your proftpd binaries and your configuration file. Then re-run configure as you ran it originally, but also include the modules, and recompile and reinstall. For example, to compile in mod_ifsession, mod_ratio, mod_quotatab, and mod_quotatab_file, do this:

 ./configure --with-modules=mod_ifsession:mod_ratio:mod_quotatab:mod_quotatab_file make make install 

Now your proftpd has even more capabilities!

Interpreting FTP Logs

While you are fine-tuning your ProFTPD configuration, undoubtedly something will not work as you hoped it would. That's when it becomes helpful to be able to interpret your FTP logs. As flexible as ProFTPD is, which FTP logs your system has will vary with your configuration.

By default, transfers are logged to /var/log/xferlog. Other logging is done via syslog, based on /etc/syslog.conf. You can bypass logging via syslog by using the SystemLog directive, which is what we did. These are the custom settings we put in place for our proftpd:

 SystemLog /var/log/proftpd.log QuotaLog /var/log/proftpd-quota.log ServerLog /var/log/ TransferLog /var/log/ 

In our /var/log/proftpd.log, we find statements such as these:

Jan 26 23:15:14 localhost proftpd[1069] localhost ([]): FTP session opened. Jan 26 23:15:21 localhost proftpd[1069] localhost ([]): ANON anonymous: Login successful. Jan 26 23:15:34 localhost proftpd[1069] localhost ([]): FTP session closed. Jan 30 14:21:44 localhost proftpd[232] localhost ([]): FTP session opened. Jan 30 14:21:48 localhost proftpd[232] localhost ([]): USER nermal : Login successful. Jan 30 14:21:58 localhost proftpd[232] localhost ([]): FTP session closed. Jan 30 14:33:42 localhost proftpd[243] localhost ([]): FTP session opened. Jan 30 14:33:47 localhost proftpd[243] localhost ([]): USER nermal: Login successful. Jan 30 14:33:47 localhost proftpd[243] localhost ([]): USER nermal: Limit access denies login. Jan 30 14:33:47 localhost proftpd[243] localhost ([]): FTP session closed. Jan 30 14:52:17 localhost proftpd[266] localhost ([]): FTP session opened. Jan 30 14:52:22 localhost proftpd[266] localhost ([]): PAM(nermal) : Authentication failure. Jan 30 14:52:22 localhost proftpd[266] localhost ([]): USER nermal (Login failed): Incorrect password. Jan 30 14:52:23 localhost proftpd[266] localhost ([]): FTP session closed. Jan 31 22:03:15 localhost proftpd[18286] localhost ([]): FTP session opened. Jan 31 22:03:19 localhost proftpd[18286] localhost ([]): USER ralph: Login successful. Jan 31 22:03:25 localhost proftpd[18286] localhost ([]): FTP session closed. Jan 31 22:40:34 localhost proftpd[18388] localhost ([]): FTP session opened. Jan 31 22:40:37 localhost proftpd[18388] localhost ([]): ANON ralph: Login successful. Jan 31 22:40:55 localhost proftpd[18388] localhost ([]): FTP session closed. Feb 01 00:09:06 localhost proftpd[18665] localhost ([]): FTP session opened. Feb 01 00:09:11 localhost proftpd[18665] localhost ([]): ANON artist: Login successful. Feb 01 00:09:14 localhost proftpd[18665] localhost ([]): FTP session closed Feb 02 15:30:09 localhost proftpd[26333] localhost (sage[]): FTP session opened. Feb 02 15:30:19 localhost proftpd[26333] localhost (sage[]): USER nermal: Login successful. Feb 02 15:30:31 localhost proftpd[26333] localhost (sage[]): FTP session closed.

This log shows authentication information for a given session. From the typical line, we can find out the date and time of the activity, the process ID, the hostname of the connecting machine (if known), the connecting machine's IP address, and an action. If the user is a real user, the user is described as USER. If the user is an anonymous user, the description is ANON. If the user cannot log in, a reason is provided, such as Authentication failure or Limit access denies login. When our guest user ralph's guest configuration was set using the DefaultRoot directive, the log describes him as a USER. When the <Anonymous> description was used instead for him, he is described as ANON. We can also see when he logs in as ralph and when he logs in as artist.

In our quota log, /var/log/proftpd-quota.log, we see entries such as these:

Jan 31 16:39:28 mod_quotatab/1.2.13[17863]: found limit entry for user 'nermal' Jan 31 16:39:28 mod_quotatab/1.2.13[17863]: creating new tally entry to match limit entry Jan 31 16:39:28 mod_quotatab/1.2.13[17863]: new tally entry successfully created Jan 31 16:40:27 mod_quotatab/1.2.13[17865]: found limit entry for user 'nermal' Jan 31 16:40:27 mod_quotatab/1.2.13[17865]: found tally entry for user 'nermal' Jan 31 16:52:43 mod_quotatab/1.2.13[17879]: found limit entry for user 'nermal' Jan 31 16:52:43 mod_quotatab/1.2.13[17879]: found tally entry for user 'nermal' Jan 31 16:53:01 mod_quotatab/1.2.13[17879]: STOR: quota reached: used 2 of 2 upload files Jan 31 16:54:08 mod_quotatab/1.2.13[17879]: RETR: quota reached: used 2 of 2 download files Jan 31 16:55:50 mod_quotatab/1.2.13[17879]: RETR denied: quota exceeded: used 2 of 2 download files

A typical entry in this log includes the date and time, process ID, and an action. We can see when the system found the limit information for user nermal and created her tally information. We can also see when the quotas for nermal were reached, and even that nermal must have attempted a download after having reached her download quota.

In our server log for the virtual FTP server for, /var/log/, we find entries similar to those in the main server log, /var/log/proftpd.log:

Jan 30 17:29:18 localhost proftpd[395] ([]): FTP session opened. Jan 30 17:29:25 localhost proftpd[395] ([]): ANON anonymous: Login successful. Jan 30 17:29:42 localhost proftpd[395] ([]): FTP session closed. Jan 31 12:39:41 localhost proftpd[17756] ([]): FTP session opened. Jan 31 12:39:46 localhost proftpd[17756] ([]): ANON anonymous: Login successful. Jan 31 12:40:06 localhost proftpd[17756] ([]): FTP session closed. Feb 02 15:52:29 localhost proftpd[26351] (sage[]): FTP session opened. Feb 02 15:52:34 localhost proftpd[26351] (sage[]): ANON anonymous: Login successful. Feb 02 15:52:38 localhost proftpd[26351] (sage[]): FTP session closed.

In the first section of entries, the server host does not know the name that belongs to the IP address that it is serving. By the second section of entries, it knows that is

The most complicated of the FTP server logs is the transfer log, /var/log/xferlog. Its format follows the format of the xferlog that wu-ftpd creates. Each entry in the log consists of an entry in this format:

 <current-time> <transfer-time> <remote-host> <file-size> <filename> <transfer-type> <special-action-flag> <direction> <access-mode> <username> <service-name> <authentication-method> <authenticated-user-id> <completion-status> 

At a casual glance, that format might seem a bit overwhelming. Let's look at some sample entries to better understand that format.

Here's an entry resulting from someone contacting the anonymous FTP server:

Wed Jan 26 23:31:04 2005 0 186880 /Users/ftp/incoming/train.wav b _ i a sage@ ftp 1 * c

Immediately apparent are the date and time when the transfer occurred. The next entry, the 0, indicates that the transfer time was only one second. The remote host was If a name is known for the remote host, the name appears here instead. The file size was 186880 bytes. The file transferred was TRain.wav in the incoming area of the anonymous FTP server. The transfer was a binary transfer. No special action, such as compressing or tarring, was done. From the i, you can see that this was an incoming transfer; that is, an upload. From the a, you can see that this was an anonymous user. The string identifying the username in this case is sage@. That is the password that the user entered. The ftp indicates that the FTP service was used. The 1 indicates that RFC931 Authentication was used. The * indicates that an authenticated user ID is not available. The c indicates that the transfer completed.

Here are entries resulting from a real user contacting the FTP server:

Mon Jan 31 13:41:44 2005 0 753474 /Users/joray/Documents/terminal-split-2 .tiff b _ i r joray ftp 1 * c Mon Jan 31 13:50:10 2005 490 753474 /Users/joray/Documents/terminal-split-2 .tiff b _ o r joray ftp 1 * c

These entries look much like the entry we saw for the anonymous transfer. In this example, r indicates that a real user made the transfer. In this case, the real user is joray. We learn from the o in the second entry that the transfer is an outgoing transfer; that is, a download. From these entries we see that joray uploads a file, and then downloads the same file, all from the same host. From the transfer times, we see that the upload only takes 0 seconds, but the download takes 490 seconds. This user probably has a low TRansferRate set for the RETR command!

Here are some entries resulting from a guest user contacting the FTP server:

Mon Jan 31 22:08:40 2005 4 188970 /Users/guests/ralph/train.aif b _ o r ralph ftp 1 * c Mon Jan 31 22:24:37 2005 0 186880 /Users/guests/ralph/incoming/train.wav b _ i a ralph ftp 1 * c Wed Feb 2 16:30:27 2005 0 sage 2890 /Users/guests/ralph/incoming/unison-log b _ i a artist ftp 1 * c

These entries also look much like entries we have seen before. Most notable about the guest user is how the guest user is labeled. Our guest user is labeled with an r when we use the DefaultRoot mechanism for defining the guest, and with an a when we use the <Anonymous> mechanism. In the last entry we see that our FTP server knows the remote host as sage, and that our guest user logs in using his alias, artist.

Finally, here is an entry from our virtual FTP server's xferlog, /var/log/

Mon Jan 31 12:40:04 2005 0 899 /Users/virtual/ .pub b _ i a miwa@ ftp 1 * c

The most interesting part about this entry is that the only clue we have that this is an entry for a transfer to the virtual FTP server is the upload directory.

If you are having problems with the FTP server, definitely check your logs. If you need even more information, particularly when you are trying to get it started, you might also consider running proftpd in standalone mode with debugging turned on. You can get a lot of information from your logs and debugging mode.

     < Day Day Up > 

    Mac OS X Tiger Unleashed
    Mac OS X Tiger Unleashed
    ISBN: 0672327465
    EAN: 2147483647
    Year: 2005
    Pages: 251 © 2008-2017.
    If you may any questions please contact us: