2

I need to allow a specific user to download files from my web server. The files will be in a specific directory and I don't want the downloader to read, write or do anything outside of that directory. So, I created a regular user - let's call her Downloader - on a Debian 11 server. I used the -d option to point that user's home directory to /var/www/example.com/Downloader

useradd -m -d /var/www/example.com/Downloader Downloader

All files in the example.com directory and below have permissions assigned as follows:

sudo chown -R WebAdmin /var/www/example.com/
sudo chgrp -R www-data /var/www/example.com/
sudo chmod -R 750 /var/www/example.com/
sudo chmod g+s /var/www/example.com/

and I further modified the Downloader directory as follows:

cd /var/www/example.com/Downloader
sudo chgrp -R Downloader ./
sudo chmod -R 750 ./
sudo chmod g+s ./

So now the permission look like this:

-rwxr-x---  1 WebAdmin Downloader         740 Apr 11 11:33 index.php

When I tried the command:

 rsync -arzvP Downloader@example.com:/var/www/example.com/Downloader/ ./

I get an error:

Could not chdir to home directory /var/www/example.com/Downloader/: Permission denied
receiving incremental file list
rsync: [sender] change_dir "/var/www/example.com/Downloader" failed: Permission denied (13)

sent 8 bytes received 9 bytes 1.79 bytes/sec total size is 0 speedup is 0.00 rsync error: some files/attrs were not transferred (see previous errors) (code 23) at main.c(1677) [Receiver=3.1.3] rsync: [Receiver] write error: Broken pipe (32)

I understand that user Downloader cannot traverse the parent directories, /var/www etc. but I thought making the home directory the /var/www/example.com/Downloader would fix it.

BTW, I also tried

rsync -arzvP Downloader@example.com:/ ./

and it basically started downloading from the root folder (including the boot dev and other directories)! I of course don't want that!

So, how do I achieve the desired result?

Chiwda
  • 133

1 Answers1

2

Let's look at the permissions for the directory tree you've described:

sudo ls -ld /var /var/www /var/www/example.com /var/www/example.com/Downloader

drwxr-xr-x 13 root root 4096 Sep 11 2022 /var drwxr-xr-x 4 root root 4096 Sep 8 10:27 /var/www drwxr-s--- 3 WebAdmin www-data 4096 Sep 8 10:26 /var/www/example.com drwxr-s--- 3 WebAdmin Downloader 4096 Sep 8 10:26 /var/www/example.com/Downloader

On inspection you can see that the permissions for /var/www/example.com prevent Downloader from being able to access its home directory, /var/www/example.com/Downloader.

We can verify this by becoming the Downloader user directly:

sudo -iu Downloader
sudo: unable to change directory to /var/www/example.com/Downloader: Permission denied

One solution is to relax the permissions on the parent directory so that Downloader can reach its destination. The minimum that will allow this is to give execute permissions to "others" (for a directory, execute permission means search permission):

sudo chmod o+x /var/www/example.com

And now when we reverify the situation it works as expected:

sudo -iu Downloader

pwd /var/www/example.com/Downloader

id uid=1009(Downloader) gid=1011(Downloader) groups=1011(Downloader)

However, none of this will address your primary statement, "I don't want the downloader to read, write or do anything outside of that directory". For that you would need to set up a chroot environment for the account and then the permissions structure becomes (much) more complicated. Right now, instead of rsync -av Downloader@remoteHost: (lists the files/directories on the remote because no destination path has been provided) they can also rsync -av Downloader@remoteHost:/ and access everything on your remote server that isn't locked down.

Chris Davies
  • 4,560