ProFTPd Server with virtual users and in SFTP mode

ProFTPd Server with virtual users and in SFTP mode

ProFTPd Server with virtual users and in SFTP mode


ProFTPd is a popular FTP server that can be configured to use the SFTP protocol, a secure FTP alternative, instead of FTP. This article will show you how to configure ProFTPd to use this protocol to avoid the insecurity of FTP. All our virtual users will have the same UID which correspond to www-data system username.

We will show you how to configure this on an Debian VPS, but most distributions should operate in a similar way.

FTPS vs SFTP
If you’re not yet familiar with the key differences between FTP, FTPS and SFTP then please see the previous article Understanding Key Differences Between FTP, FTPS and SFTP

Install ProFTPd and create virtual users


The ProFTPd software is in Debian default repositories. We can install it by typing

~]$ apt-get install proftpd-basic

A virtual user is, quite simply, a user that is not defined in the system /etc/passwd file. The /etc/passwd file is a text-based database of information about users that may log into the system and contain unique ID for each user. Virtual users are defined in e.g. another file, or in database or ldap server.

Defining users outside of /etc/passwd means that system utilities like ls and chown do not work as expected. When the administrator lists the files uploaded by virtual users, those files will have the wrong owner names or show only UID number.

By default, ls lists the names of file owners by looking up those names in /etc/passwd. This is why listing files of virtual users will often show incorrect names; ls has no knowledge of virtual user names. When working with files created by virtual users, use ls -n so that you can see the UIDs, not the names, associated with those files. You will then need to manually make sure those UIDs are the correct ones for the file.

Which UIDs should I use for my virtual users? It does not matter. The only UID and GID which are special are UID 0 (zero) and GID 0 (zero). These UID is used for user root and group root; do not assign these UID to your virtual users unless you absolutely trust those users.

Never assign UID and GID 0 (zero) to any of your virtual users.

Other than that, you are free to use any UIDs you like. It is generally a good idea to use UIDs for your virtual users that are not already in use in /etc/passwd, in order to keep the privileges of your system users separate from the privileges of your virtual users; privileges are determined by UIDs. However, in some cases (such as using ProFTPd for FTP access to websites), you may want all of your virtual users to run as the web server user, e.g. user “www-data” or user “http”. Use the UIDs that make the most sense for your site needs.

One related question often asked is “Can I have my virtual users have the same UIDs?” Yes, you can. This means that all of those virtual users would have the exact same privileges. If you use this approach, make sure those virtual users are all confined to separate home (or web site) directories by using DefaultRoot ~ in your proftpd.conf. This means that even though those virtual users would all have the same privileges, they would be unable to see and affect each others’ files since they would all be separated in different directories.

ftpasswd utility


ftpasswd program is used to create and manage files, correctly formatted, suitable for use with ProFTPD’s AuthUserFile and AuthGroupFile configuration directives. It can also generate password hashes for ProFTPD’s UserPassword directive.

In other words, we will use ftpasswd program to create and manage our virtual users. We will manage virtual users in /etc/proftpd/ftpd.passwd file and groups in /etc/proftpd/ftpd.group files.

All our virtual users will have the same UID which correspond to www-data system username. We need examine UID for www-data system username:

~]$ cat /etc/passwd | grep www-data
www-data:x:33:33:www-data:/var/www:/usr/sbin/nologin

We see, that UID for www-data system user is 33 and GID is also 33.

So, let’s create our first two virtual users with name user1 and user2:

create users:

~]$ ftpasswd --passwd --file=/etc/proftpd/ftpd.passwd --name=user1 --uid=33 --gid=33 --home=/var/www/html/user1 --shell=/bin/false             
ftpasswd: using alternate file: /etc/proftpd/ftpd.passwd
ftpasswd: creating passwd entry for user user1

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 --passwd --file=/etc/proftpd/ftpd.passwd --name=user2 --uid=33 --gid=33 --home=/var/www/html/user2 --shell=/bin/false
ftpasswd: using alternate file: /etc/proftpd/ftpd.passwd
ftpasswd: creating passwd entry for user user2

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

create groups file:

~]$ ftpasswd --group --name=www-data --file=/etc/proftpd/ftpd.group --gid=33 --member user1,user2
ftpasswd: using alternate file: /etc/proftpd/ftpd.group
ftpasswd: updating group entry for group www-data
ftpasswd: entry updated       

change ftpd.passwd and ftpd.group to read only and chagne ownership to root user:

~]$ chmod 400 /etc/proftpd/ftpd.passwd /etc/proftpd/ftpd.group
~]$ chown root:root /etc/proftpd/ftpd.passwd /etc/proftpd/ftpd.group
~]$ ls -alFh /etc/proftpd/ftpd.*
-r-------- 1 root root  26 Dec 12 14:50 /etc/proftpd/ftpd.group
-r-------- 1 root root 158 Dec 12 14:50 /etc/proftpd/ftpd.passwd

show ftpd.passwd and ftpd.group file:

~]$ cat ftpd.passwd 
user1:$1$elbFOuqM$Z0FfP9GhwMLIZza4m27ie.:33:33::/var/www/html/user1:/bin/false
user2:$1$RQfV4FlC$dOVVecDeUlSpKkvwUz4dow:33:33::/var/www/html/user2:/bin/false
~]$ cat /etc/proftpd/ftpd.group 
www-data:x:33:user1,user2

ftpasswd utility - another examples


Since the passwords in the file are stored in encrypted form, you can change the password to the user as follows:

~]$ ftpasswd --passwd --file=/etc/proftpd/ftpd.passwd --name=test --change-password

You can lock/unlock the user (add/remove the ! character in the ftpd.passwd file before the password hash, thereby making it impossible for the user to connect):

~]$ ftpasswd --passwd --file=/etc/proftpd/ftpd.passwd --name=test2 --lock
~]$ ftpasswd --passwd --file=/etc/proftpd/ftpd.passwd --name=test2 --unlock

You can delete the user as follows:

~]$ ftpasswd --passwd --file=/etc/proftpd/ftpd.passwd --name=test --delete-user

Add or Delete user from Group
For add, delete or change group members you can direct edit group file ftpd.group

Configure ProFTPd to use SFTP


Now, we need to configure the service to use SFTP.

Loaded Modules


Edit your /etc/proftpd/modules.conf file that you load only this two modules:

~]$ vi /etc/proftpd/modules.conf
# This is the directory where DSO modules reside

ModulePath /usr/lib/proftpd

LoadModule mod_sftp.c
LoadModule mod_sftp_pam.c

Create configuration for SFTP


ProFTPd use conf.d subdirectory for additional configuration. We will create a file there to enable the use of SFTP whith this configuration:

~] vi /etc/proftpd/conf.d/sftp.conf
 <IfModule mod_sftp.c>
  SFTPEngine ON
  Port 60001
  SFTPHostKey /etc/ssh/ssh_host_rsa_key
  SFTPHostKey /etc/ssh/ssh_host_ecdsa_key
  SFTPLog /var/log/proftpd/sftp.log
  SFTPCompression delayed

  DefaultRoot ~
  RequireValidShell off
  AuthUserFile /etc/proftpd/ftpd.passwd
  AuthGroupFile /etc/proftpd/ftpd.group
  AuthOrder mod_auth_file.c
  SFTPPAMEngine off
  UseReverseDNS off
 </IfModule>

Edit proftpd.conf file


Edit your proftpd.conf file to this content:

~] vi /etc/proftpd/proftpd.conf
#
# /etc/proftpd/proftpd.conf -- This is a basic ProFTPD configuration file.
# To really apply changes, reload proftpd after modifications, if
# it runs in daemon mode. It is not required in inetd/xinetd mode.
# 

# Includes DSO modules
Include /etc/proftpd/modules.conf

# Set off to disable IPv6 support which is annoying on IPv4 only boxes.
UseIPv6                         on
# If set on you can experience a longer connection delay in many cases.
IdentLookups                    off

ServerName                      "Debian"
# Set to inetd only if you would run proftpd by inetd/xinetd.
# Read README.Debian for more information on proper configuration.
ServerType                              standalone
DeferWelcome                    off

MultilineRFC2228                on
DefaultServer                   on
ShowSymlinks                    on

TimeoutNoTransfer               600
TimeoutStalled                  600
TimeoutIdle                     1200

DisplayLogin                    welcome.msg
DisplayChdir                    .message true
ListOptions                     "-l"

DenyFilter                      \*.*/

# Use this to jail all users in their homes 
DefaultRoot                     ~

# Users require a valid shell listed in /etc/shells to login.
# Use this directive to release that constrain.
RequireValidShell               off

# Port 21 is the standard FTP port.
Port                            21

# In some cases you have to specify passive ports range to by-pass
# firewall limitations. Ephemeral ports can be used for that, but
# feel free to use a more narrow range.
# PassivePorts                  49152 65534

# If your host was NATted, this option is useful in order to
# allow passive tranfers to work. You have to use your public
# address and opening the passive ports used on your firewall as well.
# MasqueradeAddress             1.2.3.4

# This is useful for masquerading address with dynamic IPs:
# refresh any configured MasqueradeAddress directives every 8 hours
<IfModule mod_dynmasq.c>
# DynMasqRefresh 28800
</IfModule>

# To prevent DoS attacks, set the maximum number of child processes
# to 30.  If you need to allow more than 30 concurrent connections
# at once, simply increase this value.  Note that this ONLY works
# in standalone mode, in inetd mode you should use an inetd server
# that allows you to limit maximum number of processes per service
# (such as xinetd)
MaxInstances                    30

# Set the user and group that the server normally runs at.
User                            proftpd
Group                           nogroup

# Umask 022 is a good standard umask to prevent new files and dirs
# (second parm) from being group and world writable.
Umask                           022  022
# Normally, we want files to be overwriteable.
AllowOverwrite                  on

# Uncomment this if you are using NIS or LDAP via NSS to retrieve passwords:
# PersistentPasswd              off

# This is required to use both PAM-based authentication and local passwords
# AuthOrder                     mod_auth_pam.c* mod_auth_unix.c

# Be warned: use of this directive impacts CPU average load!
# Uncomment this if you like to see progress and transfer rate with ftpwho
# in downloads. That is not needed for uploads rates.
#
# UseSendFile                   off

TransferLog /var/log/proftpd/xferlog
SystemLog   /var/log/proftpd/proftpd.log

LogFormat muj-log "%H %h %l %u %t \"%r\" %s %b"
ExtendedLog /var/log/proftpd/extended.log ALL muj-log

# Logging onto /var/log/lastlog is enabled but set to off by default
#UseLastlog on

# In order to keep log file dates consistent after chroot, use timezone info
# from /etc/localtime.  If this is not set, and proftpd is configured to
# chroot (e.g. DefaultRoot or <Anonymous>), it will use the non-daylight
# savings timezone regardless of whether DST is in effect.
#SetEnv TZ :/etc/localtime

<IfModule mod_quotatab.c>
QuotaEngine off
</IfModule>

<IfModule mod_ratio.c>
Ratios off
</IfModule>


# Delay engine reduces impact of the so-called Timing Attack described in
# http://www.securityfocus.com/bid/11430/discuss
# It is on by default. 
<IfModule mod_delay.c>
DelayEngine on
</IfModule>

<IfModule mod_ctrls.c>
ControlsEngine        off
ControlsMaxClients    2
ControlsLog           /var/log/proftpd/controls.log
ControlsInterval      5
ControlsSocket        /var/run/proftpd/proftpd.sock
</IfModule>

<IfModule mod_ctrls_admin.c>
AdminControlsEngine off
AdminControlsACLs all allow user root
</IfModule>

#
# Alternative authentication frameworks
#
#Include /etc/proftpd/ldap.conf
#Include /etc/proftpd/sql.conf

#
# This is used for FTPS connections
#
#Include /etc/proftpd/tls.conf

#
# Useful to keep VirtualHost/VirtualRoot directives separated
#
#Include /etc/proftpd/virtuals.conf

# A basic anonymous configuration, no upload directories.

# Include other custom configuration files
Include /etc/proftpd/conf.d/

Restart proftpd daemon


It’s all. So, we need restart proftpd daemon

~] systemctl restart proftpd.service