WhySetting 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:
- server: directives specific to the server configuration and that can not differ.
- global: shared configuration between all the instances and can also be used as default values.
- virtual: virtual configuration specific to a set of IP address and port number.
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.
ServerName "ProFTPD"
ServerAdmin Contact e-mail
Modules
The following modules corresponding to the functionnalities provided by LDAP, TLS and sftp are to be loaded.
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).
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.
MaxInstances 30
Protocols
Enabling IPv6 and SSLv3 or TLSv1 as secure transport layer
(use of SSLv23 is strongly discouraged for security reasons).
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.
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.
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).
See also LogFormat
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.
<Global>
# Configuration items
</Global>
Owner
By default, the process is owned by the nobody user,
thus limiting the risk of accessing system data.
# Default user
User nobody
Group nogroup
Log
Many information can be recorded during the process lifetime and its various customer interactions:
- login and logout with
WtmpLog - transferd files with
TransferLog - protocol commands with
ExtendedLog
# 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.
# 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.
# 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.
# 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.
# Max connections
MaxClientsPerUser 5 Message to send to the client
SFTPMaxChannels 5
Information
Displays a message upon connection, the message is setup by the
administrator. The same message, is used for ftp and ssh).
# 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:
- they will not be required to present a certificate
- renegotiating the encryption is not mandatory
- it is possible to use the same encryption session for the control and the data channel
# 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.
# 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:
# 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, …).
# LDAP
LDAPServer localhost
LDAPSearchScope subtree
LDAPUsers Branch holding users Filter to apply
LDAPGroups Branch holding groups
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.
# Toggle .ftpaccess
AllowOverride off
Chroot
Prevents the user to access files other than those present in his home
# 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.
# File transfer
DefaultTransferMode binary
It is decided below to overwrite existing files, not to keep a file partially transfered, and hide files being transferred.
# 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:
- from the outside, with a TLS secured connection
- from the same host (through loopback), without setting up encryption
and listing all the files (the -a option is systematically used when
performing
lscommands)
# Access from outside
<VirtualHost ftp.example.com>
TLSRequired on
</VirtualHost>
# 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:
<VirtualHost ftp.example.com>
TLSRequired on
Port Alternate port number
LDAPGenerateHomedir on
LDAPForceGeneratedHomedir on
LDAPGenerateHomedirPrefix Prefix for generated homedir
</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:
- no port forwarding
- no shell and so no possibility for running commands
- setting up of a chroot to the concerned directory
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.
<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.
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.
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.
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.
<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.
<Anonymous /web/www.example.com>
Include /usr/local/etc/proftpd/share.conf
#1# Include /usr/local/etc/proftpd/read-only.conf
UserAlias Username ftp
UserPassword ftp Password
</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.
<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-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:
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:
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.
ListOptions -a