A reasonably secure config file for ProFTPD

SYNOPSIS

- I take no responsibility yadda yadda, etc.  This config is virtually
  verbatim off a very public server with no IP restrictions other than
  the ones specifically blocked (unchanged from my real config... make
  up your own mind about keeping them...)  I find this setup to be a
  good mix of both security and convenience.

REQUIRED

- Any reasonably recent version of ProFTPD, 1.2.0rc3 or greater should 
  be fine (download).
  
PREPARATION

- Create your upload directory.  Call it whatever you want.  I use
  /incoming so if you use something different, be sure to go
  through the config and modify it in the appropriate places.  This
  directory should be created in the ProFTPD user's home directory,
  ie. the FTP server root:

  [root@spork tmp]# cd ~ftp
  [root@spork ftp]# mkdir incoming
  [root@spork ftp]# chmod 1333 incoming

- Now your directory permissions should look something like this:

  [root@spork ftp]# ls -ld ~ftp/incoming
  d-wx-wx-wt   5 root     operator     1024 May 24 14:17 /var/ftp/incoming

RATIONALE FOR UPLOAD DIRECTORY PERMISSIONS

- Quite simple actually.  Anybody can write to this directory.  But
  nobody can "see" anything in it.  This way if you (or your users)
  need to pass sensitive files back and forth, they simply upload 
  and send an exact link to the file to the recipient (for example,
  'ftp://ftp.mydomain.com/incoming/obscure_filename.tar.gz')
  
CREATE CONFIG FILE

#
#   ProFTPD 1.2.x Configuration File
#
ServerName			"My FTP Server"
ServerAdmin			admin@mydomain.com
ServerType			standalone  #(x)inetd is evil and unnecessary for FTP
DefaultServer			on   #Set this to 'off' if you have multiple IPs on the box, and
                                     #you only want to allow connections to the main destination IP
Port				21
User				nobody
Group				nobody #Pick a user/group with little to no priveleges
MaxClientsPerHost		3 "Only 3 simultaneous connections permitted from your host!"
MaxInstances			50   #Child processes allowed - not necessarily connections
TimeoutStalled			300  #Drop a 'hung' connection after 5 minutes
TimeoutNoTransfer		600  #I personally omit this line and use the server default
                                     #of 300 seconds but some find this to be a bit strict
AuthPAM				off  #Just trust me on this one - PAM seems to break 
                                     #everything, at least with FreeBSD

<Global>
  DefaultRoot			~    #Non-anonymous users automatically get jailed in their homedir
  AllowChmod			false
  DefaultTransferMode		binary  #If anybody actually _needs_ ASCII, they'll know how to set it
  DisplayLogin			.welcome.msg
  MaxClients			30
</Global>

<Limit LOGIN>
  Order Deny,Allow
  Deny from .fr, 64.230.225., .ca, .telia.com, .btopenworld.com, .fi, .ar 
    .rochester.rr.com .nbtel.net .adsl.swbell.net .albny.adsl.bellatlantic.net 
    .va.sprint-hsd.net cable.ntl.com .dsl.hstntx.swbell.net .dip.t-dialin.net
    #These are hosts/ISPs/countries that have pissed me off
  Allow from all
</Limit>

<Directory /webroot>
  AllowOverwrite		on   # This is for non-anonymous users and left in just as an example
</Directory>

<Anonymous ~ftp>
  User				ftp
  Group				ftp
  UserAlias			anonymous ftp
  MaxClients			10
  RequireValidShell		off  #I personally think its safer for user ftp to have no shell, hence this directive
  DisplayLogin			welcome.msg
  DisplayFirstChdir		.message
  AllowOverwrite		off  #If they up it, you have a right to see it before they whack it :)
  PathAllowFilter               "^[-A-Za-z0-9._+]*$" #Only allow matches to this regexp for uploads
  PathDenyFilter                "(^|/)[-.]"  #This restricts lame leading characters on uploads that
                                             #might otherwise be permitted by the ruleset above
  AllowFilter			"^[a-zA-Z0-9 .,/_+\-]*$" #Only allow COMMANDS matching this regexp
  <Directory incoming>
    Umask				0133 0444
    <Limit RMD DELE SITE_CHMOD RNFR>
      DenyAll
    </Limit>
    <Limit CWD MKD STOR RETR STAT>
      AllowAll
    </Limit>
  </Directory>
  <Directory incoming/*/*>
    Umask                       0133
    <Limit MKD RNFR DELE RMD SITE_CHMOD>
      DenyAll
    </Limit>
    <Limit CWD RETR STAT>
      AllowAll
    </Limit>
  </Directory>
</Anonymous>

#Okay, all of the mess above is really pretty simple.  The first Limit 
#directive says "You can't remove files or directories in /incoming."  
#The second Limit permits users to create directories, change into them, 
#and up/download files to or from this directory or any created in it.
#The third Limit says that in directories created _in_ /incoming, you may not
#create any more directories, nor as before, remove files or directories.  The
#final Limit statement says that it is fine to change into directories created
#in /incoming and also to download files from them.

#The Umask directives are a bit boneheaded if you ask me.  ProFTPD requires
#that you set the inverse required mask (so you basically subtract from 0777)
#So 0133 sets created files to standard 0644.  And 0444 sets new directories
#to 0333.  The directory Umask is omitted from the second Directory section
#since the Limit denies their creation anyway.


NOTES

- These instructions should be relatively easy, however if there are
  any suggestions or noted ommissions/errors, etc. feel free to drop
  me a note at bofh at ls dash l dot net

  Colin Bloch [05/24/2002]