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 SFTPIf 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
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.
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 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.
~]$ cat /etc/passwd | grep www-data www-data:x:33:33:www-data:/var/www:/usr/sbin/nologin
So, let's create our first two virtual users with name user1 and user2:
~]$ 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
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 GroupFor add, delete or change group members you can direct edit group file
Now, we need to configure the service to use SFTP.
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
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 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 22.214.171.124 # 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/
It's all. So, we need restart proftpd daemon
~] systemctl restart proftpd.service