Revision / Modified: May 04, 2002
Author: Tom Berger
Original documents:
http://www.mandrakeuser.org/docs/connect/cftp.html
http://www.mandrakeuser.org/docs/connect/cftp2.html
FTP still is a protocol of choice when it comes to distributing larger
amounts of data among non-authenticated users. If you're using FTP for
anything involving authentication outside a trusted network, you're
living very dangerously: the whole authorization process is unencrypted, the
client can't know if the server is who it pretends to be and the same goes
for the server.
For this reason I won't go into authenticated FTP at great length in this
article. FTP is simply the wrong tool for that.
Use SSH for authenticated services instead. FTP clients like the highly popular and graphical gftp (included in Mandrake Linux) support SSH transparently. Notice that tunneling FTP via SSH only encrypts the control connection (i.e. the channel via which the password is sent), not the data channel. If you need an FTP work-alike which encrypts both channels, use OpenSSH's own 'sftp' server software and client.
Mandrake Linux 8.2 now comes with four major FTP server packages: the
traditional FTP server, the well-known WU-FTPd from the University of Washington,
ProFTPd, usually regarded as the
rightful heir to the former, and Pure-FTPd.
While PureFTPd offers more features for home users, ProFTPd is much better
documented and uses a saner, central configuration scheme, similar to that of
Apache. Configuration also doesn't require the creation of any directory
trees. In contrast to PureFTPd, ProFTPd is licensed under the GPL and thus
part of the main distribution tree, whereas the PureFTPd RPM is contributed by
a third party.
Being 'root', type
urpmi proftpd
on a command line. This will install the package from the CD (no other dependencies on a standard system).
The configuration file is '/etc/proftpd.conf'. The configuration is done via directive - value pairs. These pairs can be applied on a per user basis, on a per directory basis or a mixture of those.
Save the original '/etc/proftpd.conf' file under a different name and start from scratch with an empty 'proftpd.conf'. For a server allowing anonymous clients to download files, it might look like this:
ServerName "My FTP Server"
ServerType standalone
DefaultServer on
Umask 022
Port 21
User nobody
Group nobody
<Directory /*>
AllowOverwrite on
</Directory>
<Anonymous ~ftp>
User ftp
Group ftp
UserAlias anonymous ftp
RequireValidShell off
<Limit WRITE>
DenyAll
</Limit>
</Anonymous>
The options in detail:
ServerName "My FTP Server"
The name of your FTP server. Use
what you like.ServerType standalone
ProFTPd can either run on its own or
via a 'super server' like xinetd.standalone
to inetd
, then edit
'/etc/xinetd.d/proftpd-xinetd' and set 'disable' from 'yes' to 'no' and
restart 'xinetd'. Do not run any extra commands to start the FTP
server from now on, this will be completely handled on the fly by
'xinetd'.DefaultServer on
All incoming connections use this
configuration unless told otherwise.Umask 022
Default permissions on all new files and directories
(this resolves to 755 or rwx-rw-rw). Notice that you can employ a second umask
especially for directories (indeed you have to use it if you remove
the execute bit and still want to use subdirectories).MaxInstances 30
The maximum of allowed simultaneous
connections.Port 21
On which port the server should listen to incoming
connections. If you change this, most clients will have to specify the new
port before connecting.User nobody
Group nogroup
User and group under which ProFTPd runs. Older versions
of Mandrake Linux might use group 'nobody' instead.
<Directory /*>
AllowOverwrite on
</Directory>
You'll find this setting in the default ProFTPd configuration file. It allows
FTP clients to overwrite files with the same name in all directories. For an
anonymous only server you might want to remove it.<Anonymous ~ftp>
This starts the section for anonymous
users and tells ProFTPd to use the directory '/var/ftp' as the 'change rooted'
start directory for these users. This means anonymous FTP users won't be able
to even see the parent directory, let alone any other directory on the
server apart from those in the '/var/ftp' hierarchy.User ftp
Group ftp
Local user account for anonymous users.UserAlias anonymous ftp
Users logging in as 'anonymous'
(default in all clients) are treated like the 'ftp' user.RequireValidShell off
Either you add this setting here, or
you add '/bin/false' to 'ftp's entry in '/etc/passwd' and to '/etc/shells'.
Choose! ;-) It's easier to do it here, and I don't know of any security
implications.
<Limit WRITE>
DenyAll
</Limit>
We don't allow anonymous users to create or delete files or directories
anywhere in the '/var/ftp' hierarchy.</Anonymous>
Marks the end of the section for anonymous
users.This basic configuration allows a single anonymous login (not much, but it's a start ;-))
Before venturing any further, it's a good idea to test if this standard setup works. Start the server as 'root' with this command
service proftpd start
Next start an FTP client from your user account and connect to 'localhost'. Try to execute some commands (list directories, change directories). Notice that you're so far not allowed to upload files. If everything works, congratulations! You can skip the next section on troubleshooting then *grin*.
Security notice: With your next login, the FTP server will be started automatically on each login. This might not be preferable. To change this behavior, run this command as 'root':
chkconfig proftpd off
It will prevent the system from starting ProFTPd without an explicit 'root' command. This only applies if the server is run in 'standalone' mode.
If you get this error message:
Starting proftpd: hostname - Fatal: unable to determine IP address of 'hostname'
there's a problem with your DNS (name resolution). The most common cause for this problem is a hostname assigned to a machine which gets its IP via DHCP on a network without a DNS server. A quick fix for this problem is adding the hostname to the '/etc/hosts' file while using the same IP used for 'localhost', i.e. '127.0.0.1':
127.0.0.1 localhost.localdomain localhost
127.0.0.1 hostname of machine short name
If you don't know the hostname of your machine, run the hostname
command.
Having made that change, restart the network as 'root' with
service network restart
and try starting the FTP server again.
If you can login into the server, but you can't execute any commands, you have to dig deeper. First let proftpd check its configuration file for syntax errors with
proftpd --configtest
If everything looks OK there, stop the FTP server with
service proftpd stop
and start it again with this line
proftpd -d4 -n
This sets the debugging level to '4' and will log all messages from ProFTPd to the console. Now open a new ftp client session and try to execute the commands again. Check the terminal window ProFTPd is running on for error messages. Check the FAQ and the rest of the ProFTPd documentation if the error message you are getting is mentioned.
Notice that if you run the server in 'standalone' mode, you will either have to reload the server after every change applied to the configuration file with
service proftpd reload
or stop and start it 'by hand'.
To allow anonymous uploads, insert these lines into the 'Anonymous' section of your 'proftpd.conf' file:
<Directory incoming>
<Limit STOR CWD>
AllowAll
</Limit>
<Limit READ RMD DELE MKD>
DenyAll
</Limit>
</Directory>
and create as 'root' an 'incoming' directory in '/var/ftp' with write permissions for the 'ftp' user:
chmod 770 /var/ftp/incoming
chown ftp:ftp !$
The options in detail:
<Directory incoming>
<Limit STOR CWD>
AllowAll
</Limit>
Anonymous users are allowed to change into (CWD) the 'incoming' directory and
put files (STOR) there.
<Limit READ RMD DELE MKD SITE_CHMOD>
DenyAll
</Limit>
But they are not allowed to read the contents of 'incoming' (but they may
list the files), to delete or create or change permissions on files or
directories in that directory. This prevents people from turning your
'incoming' directory into a warez relay.Well, if you insist ...
Every user on the system running the FTP server can access their home directory via FTP logging in with their user name and password.
If you don't want that, i.e if you only want to allow anonymous access to the FTP server, add the directive
<Limit LOGIN>
DenyAll
</Limit>
to the general section of 'proftpd.conf'.
Like with anonymous users, you can put authenticated users into a change rooted 'jail' by using the 'DefaultRoot' directive:
DefaultRoot /var/ftp
will redirect all users logging in via FTP to the '/var/ftp' directory and 'jail' them in there (i.e. they won't be able to change into any directory outside the '/var/ftp' hierarchy).
In order to create a password protected anonymous login, a so-called 'guest account', you have to create a user account on the server with a password (e.g. using useradd or 'Userdrake'). The directive you need is 'AnonRequirePassword on'. Let's assume you have created the user account 'ftplogin'. Your 'Anonymous' section would then look like this:
<Anonymous ~ftp>
User ftplogin
Group ftp
AnonRequirePassword on
RequireValidShell off
<Limit WRITE>
DenyAll
</Limit>
</Anonymous>
Now your anonymous FTP users have to login with the user name 'ftplogin' and the password you've provided when creating the account.
Security notice: you shouldn't provide that user account with a valid login shell. Use '/bin/false' instead, either by using the appropriate option to 'useradd' or in 'Userdrake', or by editing the file '/etc/passwd' after creating the account. With 'useradd', you'd do something like this (as 'root'):
useradd -d /var/ftp -s /bin/false -g ftp -p password ftplogin
This creates a user account 'ftplogin', group 'ftp', with the home directory '/var/ftp', the (invalid) shell '/bin/false' and the password password.
Adopting this configuration, you can create 'home directories' for particular users by creating accounts for them with home directories in the '/var/ftp' tree.
For more options and features like ratios, virtual servers etc, have a look at the fine ProFTPd documentation site, especially the FAQ.
Running any kind of server for untrusted clients poses a security thread. If you want to do this, you are advised to follow security advisories closely, e.g. by subscribing to lists like the famous Bugtraq. Mandrakesoft also offers two security mailing lists, security-announce and security-discuss.
There are some more options for '/etc/proftpd.conf' which you should consider for the sake of security.
You can restrict access to certain IP ranges or hostnames with the
Limit LOGIN
option:
<Limit LOGIN>
Order Allow,Deny
Allow from 128.44.26.,myhost.mydomain.edu
Deny from all
</Limit>
Notice that you are advised to use IP addresses instead of domain names.
AllowFilter
and DenyFilter
allow you to filter
out string based attacks. The server will only accept commands which match
AllowFilter
and / or reject everything which matches
DenyFilter
.
AllowFilter "^[a-zA-Z0-9 ,]*$"
lets only alphanumeric characters and the whitespace trough. A similar
option is CommandBufferSize number
which allows you to control
to maximum size of commands sent to the server.
PathAllowFilter
and PathDenyFilter
on the other
hand let you filter out unwanted file names or restrict names to a certain
pattern.
To reject all files with leading periods or dashes, use
PathDenyFilter "(^|/)[-.]"
ProFTPd lets you limit resources in various ways: you can limit the storage place, the number of connections, the amount of bytes transferred simultaneously and the resources for the server itself.
To prevent people from filling up the file system '/var/ftp/incoming' is on, you can set a quota with:
Quotas on
DefaultQuota bytes
Other quota options like QuotaExempt UID
allow you
finer grained control on who is allowed to upload how much. But you could also
set an external quota for the 'ftp' and other anonymous user accounts using
setquota
.
To set a maximum number of simultaneous connections, you use the already
mentioned maxclients
option. To set a maximum number of
simultaneous connections per user, you use
MaxClientsPerUser
.
To prevent certain kinds of Denial-of-Service or fork attacks, you can
limit the number of child processes ProFTPd spawns (each child is one
connection) with MaxInstances
.
RateReadBPS
, RateReadFreeBytes
,
RateReadHardBPS
, RateWriteBPS
,
RateWriteFreeBytes
and RateWriteHardBPS
allow you to
adjust the bandwidth clients are allowed to use.
RLimitCPU
, RLimitMemory
and
RLimitOpenFiles
are used to set limits to ProFTPd's resource
usage on the hosting machine.
To make it harder for a potential attacker, you can hide the name of the
software and its version either by giving ServerIdent
some kind
of text or by turning it off
.