1

I need to allow broad anonymous download access via vsftpd, but restrict uploads to only a single path. Is there any way to do this is other than with the filesystem permissions?

There are two main problems with trying to lock down the filesystem:

  1. It affects all users -- this is a heterogeneous system, so it's difficult to ensure everyone except the FTP user has access.
  2. It doesn't appear to be hierarchical -- even if we can lock down the top-level directories, it seems easy for someone to create an FTP-writeable subdirectory, at which point vsftpd appears to happily allow things to be uploaded to it.

Right now #2 is the bigger concern, so we actually have the read-only area mounted as a read-only filesystem, but this is causing its own problems.

Castaglia
  • 3,349
  • 3
  • 21
  • 42
Adam
  • 361
  • 1
  • 3
  • 9

2 Answers2

2

You can use the bind mount option to map/remount an already mounted part of a file system hierarchy to somewhere else. Say you have a samba share with Videos and a second with an Image library and you want to offer those as a read only FTP downloads.

mkdir -p /var/ftp/Videos /var/ftp/Images
mount --bind /share/Videos /var/ftp/Videos
mount --bind /share/Images /var/ftp/Images

Then make those file systems read-only:

mount -o remount,ro /var/ftp/Videos
mount -o remount,ro /var/ftp/Images

The file system permissions remain unaltered, but everything under Videos and Images is now read-only. So it is unlikely that a sub-directory with drwx------ can be accessed by the FTP user, but neither can the FTP user write to in a sub-directory with drwxrwxrwx permissions.

The bind mount doesn't take options so to achieve a read-only mount requires a remount and therefore I think you can't use fstab to make this persistent and need to script this instead.

Next set up the upload directory:

mkdir -p /var/ftp/Upload
chmod 700 /var/ftp/Upload
chown ftp.ftp /var/ftp/Upload 

Then configure vsftpd properly for anonymous downloads and chroot() the anonymous FTP user to /var/ftp. It's been a while since I did that, but roughly and untested:

# /etc/vsftpd/vsftpd.conf
listen=YES
#The following directives prevent local users from logging in and enables anonymous access respectively.
local_enable=NO
anonymous_enable=YES
#The following directive enables write access to the ftp server’s filesystem. 
write_enable=Yes
anon_upload_enable=Yes
# Sets the root directory for anonymous connections.
anon_root=/var/ftp

Of course there are a lot more relevant options to include.

HBruijn
  • 77,029
  • 24
  • 135
  • 201
  • mount -o remount,ro /var/ftp/Images mount: /var/ftp/Images is busy – c4f4t0r Jun 24 '15 at 12:36
  • Can you check with `lsof` if any files are opened on that mount point. – HBruijn Jun 24 '15 at 14:13
  • /share/Videos 153724820 125121348 28603472 82% /var/ftp/Videos /share/Images 153724820 125121348 28603472 82% /var/ftp/Images lsof | grep "/var/ftp" doesn't show nothing – c4f4t0r Jun 24 '15 at 16:04
0

You can easily get what you want with proftpd

<VirtualHost anonymous.example.net>
   ServerName "ANONYMOUS"

   Protocols ftp
   Port 21

   DefaultRoot /var/ftp/pub/

   <Anonymous /var/ftp/pub/>
      User ftp
      Group ftp
      UserAlias anonymous ftp

      MaxStoreFileSize 100 Mb user ftp

      <Directory /var/ftp/pub/>
         <Limit RMD MKD XMKD XRMD>
            DenyAll
         </Limit>
      </Directory>
   </Anonymous>
</VirtualHost>
ALex_hha
  • 7,193
  • 1
  • 25
  • 40