Setting Up FTP Server Using ProFTPD in CentOS

ProFTPD is an FTP Server for Unix/Linux servers, its easy to manage, reconfigure and very effective

Before we can start with installation and configuration, we need to download the EPEL repository which will allow us to install ProFTPD on our virtual private server with yum.

# rpm -Uvh http://download.fedoraproject.org/pub/epel/6/i386/epel-release-6-8.noarch.rpm

Installation Procedure

As root user run:

# yum install proftpd

Start ProFTPD when the system reboot:

# chkconfig --level 3 proftpd on

Basic Commands
To start proftpd ftp service, run:

# service proftpd start

To Stop proftpd ftp server, run:

# service proftpd stop

To restart proftpd ftp service, run:

# service proftpd restart

To reload the configuration file, run:

# service proftpd reload

Configuring ProFTPD
The default configuration file is located at /etc/proftpd.conf which has the default content as:

[root@burnzcentos6-sin3 ~]# cat /etc/proftpd.conf | egrep -v "(^#.*|^$)"
ServerName                      "ProFTPD server"
ServerIdent                     on "FTP Server ready."
ServerAdmin                     root@localhost
DefaultServer                   on
VRootEngine                     on
DefaultRoot                     ~ !adm
VRootAlias                      /etc/security/pam_env.conf etc/security/pam_env.conf
AuthPAMConfig                   proftpd
AuthOrder                       mod_auth_pam.c* mod_auth_unix.c
UseReverseDNS                   off
User                            nobody
Group                           nobody
MaxInstances                    20
UseSendfile                     off
LogFormat                       default "%h %l %u %t \"%r\" %s %b"
LogFormat                       auth    "%v [%P] %h %t \"%r\" %s"
<IfDefine TLS>
  TLSEngine                     on
  TLSRequired                   on
  TLSRSACertificateFile         /etc/pki/tls/certs/proftpd.pem
  TLSRSACertificateKeyFile      /etc/pki/tls/certs/proftpd.pem
  TLSCipherSuite                ALL:!ADH:!DES
  TLSOptions                    NoCertRequest
  TLSVerifyClient               off
  #TLSRenegotiate               ctrl 3600 data 512000 required off timeout 300
  TLSLog                        /var/log/proftpd/tls.log
  <IfModule mod_tls_shmcache.c>
    TLSSessionCache             shm:/file=/var/run/proftpd/sesscache
  </IfModule>
</IfDefine>
<IfDefine DYNAMIC_BAN_LISTS>
  LoadModule                    mod_ban.c
  BanEngine                     on
  BanLog                        /var/log/proftpd/ban.log
  BanTable                      /var/run/proftpd/ban.tab
  # If the same client reaches the MaxLoginAttempts limit 2 times
  # within 10 minutes, automatically add a ban for that client that
  # will expire after one hour.
  BanOnEvent                    MaxLoginAttempts 2/00:10:00 01:00:00
  # Allow the FTP admin to manually add/remove bans
  BanControlsACLs               all allow user ftpadm
</IfDefine>
<Global>
  # Umask 022 is a good standard umask to prevent new dirs and files
  # from being group and world writable
  Umask                         022
  # Allow users to overwrite files and change permissions
  AllowOverwrite                yes
  <Limit ALL SITE_CHMOD>
    AllowAll
  </Limit>
</Global>
<IfDefine ANONYMOUS_FTP>
  <Anonymous ~ftp>
    User                        ftp
    Group                       ftp
    AccessGrantMsg              "Anonymous login ok, restrictions apply."
    # 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 "Sorry, max %m users -- try again later"
    # Put the user into /pub right after login
    #DefaultChdir               /pub
    # We want 'welcome.msg' displayed at login, '.message' displayed in
    # each newly chdired directory and tell users to read README* files.
    DisplayLogin                /welcome.msg
    DisplayChdir                .message
    DisplayReadme               README*
    # Cosmetic option to make all files appear to be owned by user "ftp"
    DirFakeUser                 on ftp
    DirFakeGroup                on ftp
    # Limit WRITE everywhere in the anonymous chroot
    <Limit WRITE SITE_CHMOD>
      DenyAll
    </Limit>
    # An upload directory that allows storing files but not retrieving
    # or creating directories.
    <Directory uploads/*>
      AllowOverwrite            no
      <Limit READ>
        DenyAll
      </Limit>
      <Limit STOR>
        AllowAll
      </Limit>
    </Directory>
    # Don't write anonymous accesses to the system wtmp file (good idea!)
    WtmpLog                     off
    # Logging for the anonymous transfers
    ExtendedLog                 /var/log/proftpd/access.log WRITE,READ default
    ExtendedLog                 /var/log/proftpd/auth.log AUTH auth
  </Anonymous>
</IfDefine>

You can change the content if the file with following descriptions:

ServerName: Make it your default server name. 
DefaultRoot: Uncomment this line to restrict users with their home folders. 
AuthOrder: Uncomment the line to enable the using of local passwords.

Checking the syntax of the configuration file

# proftpd -t6

 Users Authentication Configuration

When you install ProFTPD, it is almost ready to use by anonymous users, you only have to uncomment anonymous section in /etc/proftpd.conf but if you want authenticated access then you must configure extra directives, keep in mind these to virtual users authentication.

AuthUserFile : Specify the users file, has the same format as /etc/passwd
AuthGroupFile : Specify the groups file, has the same format as /etc/group

These files can be created with ftpasswd tool, here is an example:

# ftpasswd --passwd --name {username} --file /etc/ftpd.passwd --uid {5000} --gid {5000} --home /var/ftp/username-home/ --shell /bin/false
# ftpasswd --group --name group1 –file /etc/ftpd.group --gid 5000 --member username

For example, add a ftp user called burnz for thesysad.com domain (ftptsa group):

# ftpasswd --passwd --name burnz --file /etc/ftpd.passwd --uid 5001 --gid 5001 --home /var/ftp/burnz/ --shell /bin/false
ftpasswd: using alternate file: /etc/ftpd.passwd
ftpasswd: creating passwd entry for user burnz
ftpasswd: /bin/false is not among the valid system shells.  Use of
ftpasswd: "RequireValidShell off" may be required, and the PAM
ftpasswd: module configuration may need to be adjusted.
Password:
Re-type password:
ftpasswd: entry created

# ftpasswd --group --name ftptsa –file /etc/ftpd.group --gid 5000 --member burnz
ftpasswd: creating group entry for group ftptsa
ftpasswd: entry created

Then the above directives must be set in this way :

AuthUserFile    /etc/ftpd.passwd
AuthGroupFile    /etc/ftpd.group

If you dont have ftpasswd you can download “ftpasswd” perl script and chmod it to 755:

# wget http://www.castaglia.org/proftpd/contrib/ftpasswd 
# chmod 755 ftpasswd

The created user must have UNIX permission under his home directory.
The value of –shell option must be set to /bin/false if you want to improve the security of the FTP server.

Create a home directory with specified permission:

mkdir /var/ftp/burnz
chown burnz:burnz /var/ftp/burnz

Disable PAM authentication

PersistentPasswd	off
AuthPAM off

To jail users to theirs respective home directories, add following to config file:

DefaulRoot ~

Files Access Permission

The general syntax is as follows:

Umask FILEMODE DIRMODE

Sets the mask of the newly created files and directories. FILEMODE and DIRMODE must be an octal mode, in the format 0xxx. If DIRMODE is omitted then DIRMODE = FILEMODE.

Example:

Umask 022
  1. The owner has rw permissions over the files and full access over directories.
  2. The group has r permission over the files and rx over directories.
  3. The world has r permission over the files and rx over directories.

To Deny every one except admin changes files permission via ftp put this in your context:

AllowUser admin
DenyAll

 Final Configuration File Content

[root@burnzcentos6-sin3 burnz]# cat /etc/proftpd.conf | egrep -v "^\s*(#|$)"
ServerName                      "ProFTPD server"
ServerIdent                     on "FTP Server ready."
ServerAdmin                     root@localhost
DefaultServer                   on
VRootEngine                     on
DefaultRoot                     ~ !adm
VRootAlias                      /etc/security/pam_env.conf etc/security/pam_env.conf
UseReverseDNS                   off
User                            nobody
Group                           nobody
AuthOrder mod_auth_file.c mod_auth_unix.c
AuthUserFile    /etc/ftpd.passwd
AuthGroupFile    /etc/ftpd.group
RequireValidShell       off
PersistentPasswd        off
AuthPAM off
MaxInstances                    20
UseSendfile                     off
LogFormat                       default "%h %l %u %t \"%r\" %s %b"
LogFormat                       auth    "%v [%P] %h %t \"%r\" %s"
<IfDefine TLS>
  TLSEngine                     on
  TLSRequired                   on
  TLSRSACertificateFile         /etc/pki/tls/certs/proftpd.pem
  TLSRSACertificateKeyFile      /etc/pki/tls/certs/proftpd.pem
  TLSCipherSuite                ALL:!ADH:!DES
  TLSOptions                    NoCertRequest
  TLSVerifyClient               off
  TLSLog                        /var/log/proftpd/tls.log
  <IfModule mod_tls_shmcache.c>
    TLSSessionCache             shm:/file=/var/run/proftpd/sesscache
  </IfModule>
</IfDefine>
<IfDefine DYNAMIC_BAN_LISTS>
  LoadModule                    mod_ban.c
  BanEngine                     on
  BanLog                        /var/log/proftpd/ban.log
  BanTable                      /var/run/proftpd/ban.tab
  BanOnEvent                    MaxLoginAttempts 2/00:10:00 01:00:00
  BanControlsACLs               all allow user ftpadm
</IfDefine>
<Global>
  Umask                         022
  AllowOverwrite                yes
  <Limit ALL SITE_CHMOD>
    AllowAll
  </Limit>
</Global>
<IfDefine ANONYMOUS_FTP>
  <Anonymous ~ftp>
    User                        ftp
    Group                       ftp
    AccessGrantMsg              "Anonymous login ok, restrictions apply."
    UserAlias                   anonymous ftp
    MaxClients                  10 "Sorry, max %m users -- try again later"
    DisplayLogin                /welcome.msg
    DisplayChdir                .message
    DisplayReadme               README*
    DirFakeUser                 on ftp
    DirFakeGroup                on ftp
    <Limit WRITE SITE_CHMOD>
      DenyAll
    </Limit>
    <Directory uploads/*>
      AllowOverwrite            no
      <Limit READ>
        DenyAll
      </Limit>
      <Limit STOR>
        AllowAll
      </Limit>
    </Directory>
    WtmpLog                     off
    ExtendedLog                 /var/log/proftpd/access.log WRITE,READ default
    ExtendedLog                 /var/log/proftpd/auth.log AUTH auth
  </Anonymous>
</IfDefine>