I can't find anyone who has this weird issue: ftp users are able to upload files but they are not able to retrieve them.

Please give me any clue to solve this issue. Thank you

"ftpuser1" is a user defined in proftp-mysql table with home: /srv/ftp/users/ftpuser1

when "ftpuser1" starts an ftp session, he is chrooted correctly so he uploads file and creates directories in /srv/ftp/users/ftpuser1 but when he tries to cwd or retrieve a file he gots 500 errors and it seems he is trying to read from /

virtual user ftpuser1 is mapped to uid/gid 2001/2001 here are all directory permissions

# ls -aldn /srv /srv/ftp /srv/ftp/users /srv/ftp/users/ftpuser1 
drwxr-xr-x. 3    0    0 16 May 23  2016 /srv
drwxr-xr-x. 3    0    0 18 May 23  2016 /srv/ftp
drwxr-xr-x. 6   99   99 67 Sep  9 08:03 /srv/ftp/users
drwx------. 3 2001 2001 23 Sep  9 08:04 /srv/ftp/users/ftpuser1
drwxr-xr-x. 2 2001 2001  6 Sep  9 08:03 /srv/ftp/users/ftpuser1/directory1/

moreover with -Z option, it seems that se linux flags are ok

# ls -aldnZ /srv /srv/ftp /srv/ftp/users /srv/ftp/users/ftpuser1 
drwxr-xr-x.    0    0 system_u:object_r:var_t:s0       /srv
drwxr-xr-x.    0    0 unconfined_u:object_r:public_content_t:s0 /srv/ftp
drwxr-xr-x.   99   99 unconfined_u:object_r:public_content_rw_t:s0 /srv/ftp/users
drwx------. 2001 2001 unconfined_u:object_r:public_content_rw_t:s0 /srv/ftp/users/ftpuser1
drwxr-xr-x. 2001 2001 unconfined_u:object_r:public_content_rw_t:s0 /srv/ftp/users/ftpuser1/directory1/

I've disable selinux and nothing changes I did not find anything in proftpd logs or audit log

I'm using this packages on centos 7

Arch        : x86_64
Version     : 1.3.5e
Release     : 2.el7

Arch        : x86_64
Version     : 1.3.5e
Release     : 2.el7

From repo   : epel

proftpd + mod_mysql log with debug 10

proftpd.conf with mod_mysql

# This is the ProFTPD configuration file

# Trace logging, disabled by default for performance reasons
# (http://www.proftpd.org/docs/howto/Tracing.html)
TraceLog            /var/log/proftpd/trace.log
Trace               DEFAULT:0
TransferLog /var/log/proftpd/xferlog
SystemLog   /var/log/proftpd/proftpd.log

ServerName      "ProFTPD server"
ServerIdent     on "FTP Server ready."
ServerAdmin     root@localhost
DefaultServer       on
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
PassivePorts        1024 1048

# Don't do reverse DNS lookups (hangs on DNS problems)
UseReverseDNS       off

# Set the user and group that the server runs as
User                nobody
Group               nobody
CreateHome          true

# To prevent DoS attacks, set the maximum number of child processes
# to 20.  If you need to allow more than 20 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            20

# Disable sendfile by default since it breaks displaying the download speeds in
# ftptop and ftpwho
UseSendfile         off

# Define the log formats
LogFormat           default "%h %l %u %t \"%r\" %s %b"
LogFormat           auth    "%v [%P] %h %t \"%r\" %s"

# Dynamic Shared Object (DSO) loading
# See README.DSO and howto/DSO.html for more details
# General database support (http://www.proftpd.org/docs/contrib/mod_sql.html)
   LoadModule mod_sql.c

# Mysql support (requires proftpd-mysql package)
# (http://www.proftpd.org/docs/contrib/mod_sql.html)
   LoadModule mod_sql_mysql.c

# Quota support (http://www.proftpd.org/docs/contrib/mod_quotatab.html)
   LoadModule mod_quotatab.c

# SQL database "driver" for storing quota table information in SQL tables
# (http://www.proftpd.org/docs/contrib/mod_quotatab_sql.html)
   LoadModule mod_quotatab_sql.c

# Administrative control actions for the ftpdctl program
# (http://www.proftpd.org/docs/contrib/mod_ctrls_admin.html)
LoadModule mod_ctrls_admin.c

# Implement a virtual chroot capability that does not require root privileges
# (http://www.castaglia.org/proftpd/modules/mod_vroot.html)
# Using this module rather than the kernel's chroot() system call works
# around issues with PAM and chroot (http://bugzilla.redhat.com/506735)
LoadModule mod_vroot.c

# Allow only user root to load and unload modules, but allow everyone
# to see which modules have been loaded
# (http://www.proftpd.org/docs/modules/mod_dso.html#ModuleControlsACLs)
ModuleControlsACLs      insmod,rmmod allow user root
ModuleControlsACLs      lsmod allow user *

# Enable basic controls via ftpdctl
# (http://www.proftpd.org/docs/modules/mod_ctrls.html)
ControlsEngine          on
ControlsACLs            all allow user root
ControlsSocketACL       allow user *
ControlsLog         /var/log/proftpd/controls.log

# Enable admin controls via ftpdctl
# (http://www.proftpd.org/docs/contrib/mod_ctrls_admin.html)
<IfModule mod_ctrls_admin.c>
  AdminControlsEngine       on
  AdminControlsACLs     all allow user root

# Enable mod_vroot by default for better compatibility with PAM
# (http://bugzilla.redhat.com/506735)
<IfModule mod_vroot.c>
  VRootEngine           on

# Dynamic ban lists (http://www.proftpd.org/docs/contrib/mod_ban.html)
# Enable this with PROFTPD_OPTIONS=-DDYNAMIC_BAN_LISTS in /etc/sysconfig/proftpd
  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

  # Inform the user that it's not worth persisting
  BanMessage            "Host %a has been banned"

  # Allow the FTP admin to manually add/remove bans
  BanControlsACLs       all allow user ftpadm

# Set networking-specific "Quality of Service" (QoS) bits on the packets used
# by the server (contrib/mod_qos.html)
<IfDefine QOS>
  LoadModule            mod_qos.c
  # RFC791 TOS parameter compatibility
  QoSOptions            dataqos throughput ctrlqos lowdelay
  # For a DSCP environment (may require tweaking)
  #QoSOptions           dataqos CS2 ctrlqos AF41

# Global Config - config common to Server Config and all virtual hosts
# See: http://www.proftpd.org/docs/howto/Vhost.html

  # 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

# Proftpd sample configuration for SQL-based authentication.
# (This is not to be used if you prefer a PAM-based SQL authentication)

<IfModule mod_sql.c>

DefaultRoot                     ~   
# Choose a SQL backend among MySQL or PostgreSQL.
# Both modules are loaded in default configuration, so you have to specify the backend 
# or comment out the unused module in /etc/proftpd/modules.conf.
# Use 'mysql' or 'postgres' as possible values.
SQLBackend  mysql
SQLEngine on
SQLAuthenticate on
# Use both a crypted or plaintext password 
#SQLAuthTypes Crypt Plaintext
# Use a backend-crypted or a crypted password
#SQLAuthTypes Backend Crypt 
SQLAuthTypes OpenSSL Crypt Plaintext

# Connection 
#SQLConnectInfo proftpd@sql.example.com proftpd_user proftpd_password
SQLConnectInfo ftp@localhost dedalo dedalo
# Describes both users/groups tables
SQLUserInfo ftpuser userid passwd uid gid homedir shell
SQLGroupInfo ftpgroup groupname gid members

# set min UID and GID - otherwise these are 999 each
SQLMinID    98

SQLNamedQuery updatecount UPDATE "count=count+1, accessed=now() WHERE userid='%u'" ftpuser

# Update modified everytime user uploads or deletes a file
SQLLog  STOR,DELE modified
SQLNamedQuery modified UPDATE "modified=now() WHERE userid='%u'" ftpuser

# User quotas
# ===========
QuotaEngine on
QuotaDirectoryTally on
QuotaDisplayUnits Mb
QuotaShowQuotas on
SQLNamedQuery get-quota-limit SELECT "name, quota_type, per_session, limit_type, bytes_in_avail, bytes_out_avail, bytes_xfer_avail, files_in_avail, files_out_avail, files_xfer_avail FROM ftpquotalimits WHERE name = '%{0}' AND quota_type = '%{1}'"
SQLNamedQuery get-quota-tally SELECT "name, quota_type, bytes_in_used, bytes_out_used, bytes_xfer_used, files_in_used, files_out_used, files_xfer_used FROM ftpquotatallies WHERE name = '%{0}' AND quota_type = '%{1}'"
SQLNamedQuery update-quota-tally UPDATE "bytes_in_used = bytes_in_used + %{0}, bytes_out_used = bytes_out_used + %{1}, bytes_xfer_used = bytes_xfer_used + %{2}, files_in_used = files_in_used + %{3}, files_out_used = files_out_used + %{4}, files_xfer_used = files_xfer_used + %{5} WHERE name = '%{6}' AND quota_type = '%{7}'" ftpquotatallies
SQLNamedQuery insert-quota-tally INSERT "%{0}, %{1}, %{2}, %{3}, %{4}, %{5}, %{6}, %{7}" ftpquotatallies
QuotaLimitTable sql:/get-quota-limit
QuotaTallyTable sql:/get-quota-tally/update-quota-tally/insert-quota-tally
SqlLogFile /var/log/proftpd/sql.log

  • What does your full proftpd.conf (and any included files) look like? – Castaglia Sep 8 '17 at 14:27
  • sorry, I've added configuration. Anyway I've disabled mysql authentication and I've created real users and everthing is working but I need to know if there is a bug on mod_mysql – Bob Bedinsky Sep 8 '17 at 17:37
  • Could you also show the ProFTPD debug logging showing one of these download failures? – Castaglia Sep 8 '17 at 23:18
  • I've added debug logging of ftp session of user ftpuser1. Before posting I had already checked this log but I had not found any clue. I hope it helps – Bob Bedinsky Sep 9 '17 at 8:35
  • 1
    @BobBedinsky Please don't edit the solution into your question. Post it as an answer instead. You can accept your own answer. There is also no need to add "solved" to the title, your question is marked as solved as long as an answer is accepted. – Gerald Schneider May 21 '18 at 16:22

I figured out that this is problem of mod_vroot module. Deactivate it in configuration file - comment line LoadModule mod_vroot.c. Then it is working fine as expected.

  • I have deactivated mod_vroot from proftpd.conf configured with mod_mysql and I have trasferred/deleted files correctly using filezilla but I need to do further checks with other ftp clients. Thank you. – Bob Bedinsky Oct 17 '17 at 10:00

I believe the issue is that for some reason your permissions on /srv/ftp/users/ftpuser1 are not correct. You should verify that ftpuser1 has complete control over the folder.

  • Run ls -l /src/ftp/users | grep ftpuser1 and see what permissions it has and who owns the folder.

  • If ftpuser1 does not own the folder, try taking ownership with sudo chown ftpuser1:ftpuser1 /srv/ftp/users/ftpuser1.

  • Restart ProFTPD and try again.

Someone else had a similar issue here: Cannot delete or edit files on ProFTPD server

Posting your config file will also help us a lot more.

Also, when your users have CHROOT enabled and the client says they are trying to read/write from /. It is referring / as their current working directory NOT the actual root of the OS itself.

  • Thank you for answer but I do not think it applies to my issue. Using mod_mysql users are virtual and all files under ftproot are owned by a real user which is associated to virtual user in a mysql table In my case ftpuser1 has been associated to a real user with uid=2001 gid=2001. Files created under /srv/ftp/users/ftpuser1 have right owner ship – Bob Bedinsky Sep 9 '17 at 8:30


I did a yum -y update, I recommend a full update of all installed packages in particular system libraries

This new package solved the issues I had on virtual users:

Arch        : x86_64
Version     : 1.3.5e
Release     : 4.el7

Arch        : x86_64
Version     : 1.3.5e
Release     : 4.el7

From repo   : epel

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.