Table of content
  1. Configuration
    1. Server
      1. Information
      2. Modules
      3. Type
      4. Protocols
      5. Listen
      6. Log format
    2. Global
      1. Owner
      2. Log
      3. Security
      4. Tuning
      5. Connections
      6. Information
      7. TLS/SSL
      8. SFTP
      9. Authentication
      10. LDAP
      11. ftpaccess
      12. Chroot
      13. File transfer
    3. Virtual
      1. Home via ftp
      2. Homepage via ftp
      3. Home via SFTP
  2. Examples
    1. Fragments
      1. share.conf
      2. anonymous.conf
      3. read-only.conf
      4. incoming.conf
    2. Use
      1. File sharing
      2. Anonymous ftp
  3. Tools
    1. Converting SSH keys
    2. Generating password
    3. Display all the files

Setting up an ftp server, whose communications will be encrypted to protect the password and the content. However the encryption won’t be used in case of communication from localhost. User accounts will be managed from an LDAP directory or from the configuration file (virtual users).

Configuration

The proFTPD server is able, as the apache server, to create virtual hosts. The choice of configuration to use is then based on the IP addresses and ports numbers; beware that it is not possible to do it based on domain names as the ftp protocol doesn’t allow it.

The proposed configuration is divided into three parts:

If a simpler configuration is desired, it’s possible to remove the distinction between server, global and virtual and to place all the directives at the same level.

Server

Information

Information about the server such as server name and person to contact in case of problems.

proftpd.conf
1
2
ServerName			"ProFTPD"
ServerAdmin			webmaster@example.com

Modules

The following modules corresponding to the functionnalities provided by LDAP, TLS and sftp are to be loaded.

proftpd.conf
1
2
3
4
LoadModule                      mod_ldap.c
LoadModule                      mod_tls.c
LoadModule                      mod_tls_shmcache.c
LoadModule                      mod_sftp.c

Type

The server is configured to operate autonomously (compared to management done through inetd).

proftpd.conf
1
2
ServerType			standalone
ScoreboardFile			/var/run/proftpd.scoreboard

The number of simultaneous connections is limited to 30 and will need to be adjusted according to the expected load.

proftpd.conf
1
MaxInstances			30

Protocols

Enabling IPv6 and SSLv3 or TLSv1 as secure transport layer (use of SSLv23 is strongly discouraged for security reasons).

proftpd.conf
1
2
UseIPv6				on
TLSProtocol 	 		SSLv3 TLSv1

It is not necessary to disable the DNS reverse verification if the connections number is not sufficient to justify it.

proftpd.conf
1
UseReverseDNS                   on

Listen

The default server and default port number are disabled to allow creating a VirtualHost configuration. The SocketBindTight directive set to off allows to limit the server to the opening of a single socket (using ANY_ADDR).

Disabling SocketBindTight can be problematic if another process is listening on an identical port number, in this case (or in doubt) set it to on.

proftpd.conf
1
2
3
Port                            0
SocketBindTight                 off
DefaultServer                   off

Log format

Defines the format used by the log files, the possible datas are: IP address of the client (%a), user (%U, %u), server name (%v), timestamp (%t), received command (%r), reply (%s), bytes transferred (%b).

LogFormat

proftpd.conf
1
LogFormat                       logfmt    "%a %U[%u] %v %t \"%r\" %s %b"

Global

The following items are to be placed in the Global section and will be applied to all configurations.

proftpd.conf
1
2
3
<Global>
    #  Configuration items
</Global>

Owner

By default, the process is owned by the nobody user, thus limiting the risk of accessing system data.

proftpd.conf
1
2
3
    # Default user
    User                        nobody
    Group                       nogroup

Log

Many information can be recorded during the process lifetime and its various customer interactions:

proftpd.conf
1
2
3
4
    # Logging
    WtmpLog                     on
#   ExtendedLog                 /var/log/proftpd.log READ,WRITE,AUTH logfmt
    TransferLog                 /var/log/xferlog

Security

It is essential to remove the check querying the identity, otherwise the connection latency is likely to be unbearable. Indeed, few people still use identd or worse, its ports are filtered.

proftpd.conf
1
2
3
4
5
6
7
    # Security
    RootRevoke                  on
    MaxLoginAttempts            4
    IdentLookups                off
    PassivePorts                49152 65535
    AllowForeignAddress         off
    CommandBufferSize           512

The root user as well as those contained in the file /etc/ftpusers are not allowed to connect. Additionally, users must have a valid shell, that is a shell which is available on the host.

proftpd.conf
1
2
3
4
    # User restrictions
    RootLogin                   off     # No root login
    UseFtpUsers                 on      # Exclude users in /etc/ftpusers
    RequireValidShell           on      # Validate shell with /etc/shells

Tuning

Performances can be improved when sending files over the network by using the sendfile system call (if the OS allows it), which avoids many copies between userspace and kernel mode.

proftpd.conf
1
2
    # Network optimisation
    UseSendfile                 on

The sendfile system call may not be fully functional with all file systems, especially in the case of remote file systems (such as NFS, Samba, …).

Connections

The number of distinct connections for a same user will be limited to 5. This value is of course to be tailored to suit the load that the server can bear.

proftpd.conf
1
2
3
    # Max connections
    MaxClientsPerUser           5 "Sorry, no more than %m connections per user"
    SFTPMaxChannels             5

Information

Displays a message upon connection, the message is setup by the administrator. The same message, is used for ftp and ssh).

proftpd.conf
1
2
3
    # Banner
    DisplayConnect              /etc/issue.net
    SFTPDisplayBanner           /etc/issue.net

TLS/SSL

Setting up a secure FTP connection on the control+data channel.

To provide good compatibility with ftp clients:

proftpd.conf
1
2
3
4
5
6
7
8
9
10
11
    # TLS
    TLSEngine                   on
    TLSRequired                 on
    TLSRSACertificateFile     	/etc/cert/wildcard.example.com.crt
    TLSRSACertificateKeyFile  	/etc/cert/wildcard.exmaple.com.key
    TLSCACertificateFile      	/etc/cert/cacert.pem
    TLSVerifyClient           	off
    TLSRenegotiate            	required off
    TLSOptions                 	AllowClientRenegotiations NoSessionReuseRequired
#                               EnableDiags
#   TLSLog                      /var/log/proftpd.tls.log

SFTP

If an sftp access is desired, the same keys as those created by sshd will be used. Keys for user will be checked from the ~/.sftp/authorized_keys file

Public keys are saved in RFC 4716 which differs from openssh format.

proftpd.conf
1
2
3
4
5
6
7
    # SFTP
    SFTPHostKey                 /etc/ssh/ssh_host_rsa_key
    SFTPHostKey                 /etc/ssh/ssh_host_dsa_key
    SFTPDHParamFile             /usr/local/etc/proftpd/dhparams.pem
    SFTPKeyBlacklist            /usr/local/etc/proftpd/blacklist.dat
    SFTPAuthorizedUserKeys      file:~/.sftp/authorized_keys
#   SFTPLog                     /var/log/proftpd.sftp.log

Authentication

To avoid cascading authentication, it is advised to only keep the required modules, for instance mod_ldap.c for ldap, and mod_auth_unix.c for created user through UserAlias/UserPassword:

proftpd.conf
1
2
    # Authentication
    AuthOrder                   mod_ldap.c mod_auth_unix.c

LDAP

The LDAP directory will allow retrieving of information related to the user accounts (uid, authentication, home, …).

proftpd.conf
1
2
3
4
5
6
    # LDAP
    LDAPServer                  localhost
    LDAPSearchScope             subtree
    LDAPUsers                   "ou=People,dc=example,dc=com" (&(uid=%v)(objectClass=posixAccount))
    LDAPGroups                  "ou=Groups,dc=example,dc=com"

ftpaccess

As for Apache with .htaccess files, proFTPD allows to override some directives according to visited directories, this is done through .ftpaccess files. By default, we remove this possibility.

proftpd.conf
1
2
    # Toggle .ftpaccess
    AllowOverride               off

Chroot

Prevents the user to access files other than those present in his home

proftpd.conf
1
2
    # Jailing
    DefaultRoot                 ~

File transfer

File transfer will be done in binary by default. The other possibility is text mode, which performs an automatic conversion of end of line characters based on operating system (Unix vs. Windows). This last mode has no real purpose anymore and was the source of many file corruption during transfers.

proftpd.conf
1
2
    # File transfer
    DefaultTransferMode         binary

It is decided below to overwrite existing files, not to keep a file partially transfered, and hide files being transferred.

proftpd.conf
1
2
3
4
5
    # File uploading / Directory creation
    AllowOverwrite              on
    DeleteAbortedStores         on
    HiddenStores                on
    Umask                       022

Virtual

In the configurations shown below the users are taken from the LDAP directory defined in the Global section.

Home via ftp

Access to accounts is made possible in two ways, each defined by a virtual host configuration:

proftpd.conf
1
2
3
4
# Access from outside
<VirtualHost ftp.example.com>
    TLSRequired               on
</VirtualHost>
proftpd.conf
1
2
3
4
5
# Access from localhost
<VirtualHost localhost.example.com>
    TLSRequired               off       # No encryption for localhost
    ListOptions               -a        # List all files
</VirtualHost>

Homepage via ftp

We consider the case where users have their homepage in the /fs/homepage directory. To setup an ftp access to these homepages, we need to force the use of another home instead of the one specified by the attribute homeDirectory. The standard port number having already been used before, another port is selected:

proftpd.conf
1
2
3
4
5
6
7
<VirtualHost ftp.example.com>
    TLSRequired               on
    Port                      121
    LDAPGenerateHomedir       on
    LDAPForceGeneratedHomedir on
    LDAPGenerateHomedirPrefix /fs/homepage
</VirtualHost>

Home via SFTP

It is possible to use proFTPD to replace openssh (mod_sftp module) to provide an sftp/scp access. The benefit of this solution is to only provide an access to the desired data, particularly:

However note that if a real ssh access is required to perform system administrative tasks, it will be necessary to select a different IP address or port number either for ssh, or for proftpd.

For proper operations of the sftp module, it is necessary to ensure that the TLS layer is disabled. Selected authentication methods are public keys and password, the first one being the most secure.

proftpd.conf
1
2
3
4
5
6
<VirtualHost ftp.example.com>
     TLSRequired              off		# Disable TLS
     SFTPEngine               on		#    as we will use SFTP
     Port                     22
     SFTPAuthMethods 	      publickey password
</VirtualHost>

Examples

Fragments

Below are presented configuration fragments (share.conf, anonymous.conf, read-only.conf, and incoming.conf) which can either be copied or included using the Include directive to easily create different access type.

share.conf

Create a shared and anonymous access with password restriction (ie: a single login and password for all users). Access rights are those of the ftp user.

proftpd.conf
1
2
3
4
5
6
  User                      ftp
  Group                     ftp

  RequireValidShell         off
  AnonRequirePassword       on
  AuthAliasOnly             on

anonymous.conf

Create a public and anonymous access, the users are not required to identify themselves to gain access to the content. However, good practice is to use the email address as password, but no guarantee is made on what will be input by the users.

proftpd.conf
1
2
3
4
5
6
7
8
9
  User                      ftp
  Group                     ftp

  AllowOverride             on
  HideNoAccess              on
  PathDenyFilter            "(\.htaccess)|(\.ftpaccess)$"

  RequireValidShell         off
  AnonRequirePassword       off

read-only.conf

Allow to limit access to read-only. To do this, write operation and permission operations are prohibited. And for aesthetics, the owner and permissions of the file are presented to the user as belonging to root with a read-only rights.

proftpd.conf
1
2
3
4
5
6
7
  DirFakeGroup              on root
  DirFakeUser               on root
  DirFakeMode               0444

  <Limit WRITE SITE_CHMOD>
    DenyAll
  </Limit>

incoming.conf

Create an incoming directory in which it is only possible to upload files, but impossible to know whether a file exists or to download it. Only the administrator of the host may have access to these files.

This is the typical configuration used to allow users to transmit files to the webmaster while preventing the ftp server from becoming a place of illegal file sharing.

proftpd.conf
1
2
3
4
5
6
7
8
9
10
11
12
13
  <Directory incoming>
    DirFakeMode             0300
  </Directory>

  <Directory incoming/*>
    AllowOverwrite          off
    <Limit ALL>
      DenyAll
    </Limit>
    <Limit STOR MKD XMKD CWD>
      AllowAll
    </Limit>
  </Directory>

Use

The different configuration fragments proposed above will be assembled to provide various type of access and will be included in a VirtualHost section.

File sharing

Create a sharing place protected by a password (you can make it read-only by uncommenting #1#). The typical use of this configuration is to give a read/write access to a website content so that developers can modify it.

If this configuration is used to develop a website and if the website will need to have a write access to its own files, it may be desirable to choose the www user as owner of the process (instead of ftp) . This change will affect the User, Group, UserAlias directives and may require modification of the /etc/ftpusers file.

proftpd.conf
1
2
3
4
5
6
    <Anonymous /web/www.example.com>
      Include                   /usr/local/etc/proftpd/share.conf
#1#   Include                   /usr/local/etc/proftpd/read-only.conf
      UserAlias                 web-example ftp
      UserPassword              ftp ?????????
    </Anonymous>

Anonymous ftp

Create an anonymous ftp, which means that it is accessible to all but only in read-only and with a dedicated incoming directory to upload files to the administrator intent. This is the description of the classical “anonymous ftp”.

To guide the user in the ftp site, welcome messages will be displayed if the necessary files are present at the connection (welcome.msg file) and upon entry in a directory (.message file ). To control the use of this public resource, we choose here to limit the number of simultaneous connections to 10.

proftpd.conf
1
2
3
4
5
6
7
8
9
    <Anonymous ~ftp>
      Include                   /usr/local/etc/proftpd/anonymous.conf
      Include                   /usr/local/etc/proftpd/read-only.conf
      Include                   /usr/local/etc/proftpd/incoming.conf
      UserAlias                 anonymous ftp
      DisplayLogin              welcome.msg
      DisplayChdir              .message
      MaxClients                10
    </Anonymous>

Tools

Converting SSH keys

To convert an SSH key to the (RFC 4716) format used by proFTPD, the ssh-keygen command is used on the public keys (generally named id_rsa.pub or id_dsa.pub):

ssh key convertion
1
ssh-keygen -e -f public_key_file

The following script provide a way to convert to the RFC 4716 format all the keys contained in ~/.ssh/authorized_keys:

Converting to RFC 4716 all keys listed in authorized_keys
1
2
3
4
5
6
tmp=`mktemp -u -t ssh-conv`
while read line ; do 
    echo "$line" | sed -nE 's/^.*(ssh-)/\1/p' > ${tmp} && chmod 600 ${tmp} &&
    ssh-keygen -e -f ${tmp} 
done < $HOME/.ssh/authorized_keys
rm ${tmp}

Generating password

Passwords used by the UserPassword directive are stored in encrypted form (through the crypt function). The following command line help to generate the crypted form:

Generating random password
1
ruby -e 'puts ARGV[0].crypt(rand(2**256).to_s(36)[0..1])' password

Display all the files

It may be desirable to force the display of hidden files (ie: dot-file) to allow some ftp clients to recursively delete directories. This does not affect files that are explicitly hidden at the server level.

proftpd.conf
1
ListOptions                     -a